diff --git a/lib/ops/community-store-ops.js b/lib/ops/community-store-ops.js new file mode 100644 --- /dev/null +++ b/lib/ops/community-store-ops.js @@ -0,0 +1,113 @@ +// @flow + +import type { BaseStoreOpsHandlers } from './base-ops.js'; +import type { + CommunityInfo, + CommunityInfos, + CommunityStore, +} from '../types/community-types.js'; + +// client types +export type ReplaceCommunityOperation = { + +type: 'replace_community', + +payload: { +id: string, +communityInfo: CommunityInfo }, +}; + +export type RemoveCommunitiesOperation = { + +type: 'remove_communities', + +payload: { +ids: $ReadOnlyArray }, +}; + +export type RemoveAllCommunitiesOperation = { + +type: 'remove_all_communities', +}; + +export type CommunityStoreOperation = + | ReplaceCommunityOperation + | RemoveCommunitiesOperation + | RemoveAllCommunitiesOperation; + +// SQLite types +export type ClientDBCommunityInfo = { + +id: string, + +communityInfo: string, +}; + +export type ClientDBReplaceCommunityOperation = { + +type: 'replace_community', + +payload: ClientDBCommunityInfo, +}; + +export type ClientDBCommunityStoreOperation = + | ClientDBReplaceCommunityOperation + | RemoveCommunitiesOperation + | RemoveAllCommunitiesOperation; + +const communityStoreOpsHandlers: BaseStoreOpsHandlers< + CommunityStore, + CommunityStoreOperation, + ClientDBCommunityStoreOperation, + CommunityInfos, + ClientDBCommunityInfo, +> = { + processStoreOperations( + communityStore: CommunityStore, + ops: $ReadOnlyArray, + ): CommunityStore { + if (ops.length === 0) { + return communityStore; + } + + let processedCommunityInfos = { ...communityStore.communityInfos }; + + for (const operation of ops) { + if (operation.type === 'replace_community') { + processedCommunityInfos[operation.payload.id] = + operation.payload.communityInfo; + } else if (operation.type === 'remove_communities') { + for (const id of operation.payload.ids) { + delete processedCommunityInfos[id]; + } + } else if (operation.type === 'remove_all_communities') { + processedCommunityInfos = {}; + } + } + + return { ...communityStore, communityInfos: processedCommunityInfos }; + }, + + convertOpsToClientDBOps( + ops: $ReadOnlyArray, + ): $ReadOnlyArray { + return ops.map(operation => { + if ( + operation.type === 'remove_communities' || + operation.type === 'remove_all_communities' + ) { + return operation; + } + + return { + type: 'replace_community', + payload: { + id: operation.payload.id, + communityInfo: JSON.stringify(operation.payload.communityInfo), + }, + }; + }); + }, + + translateClientDBData( + communites: $ReadOnlyArray, + ): CommunityInfos { + const communityInfos: { [id: string]: CommunityInfo } = {}; + + communites.forEach(dbCommunity => { + communityInfos[dbCommunity.id] = JSON.parse(dbCommunity.communityInfo); + }); + + return communityInfos; + }, +}; + +export { communityStoreOpsHandlers };