diff --git a/lib/ops/synced-metadata-store-ops.js b/lib/ops/synced-metadata-store-ops.js new file mode 100644 --- /dev/null +++ b/lib/ops/synced-metadata-store-ops.js @@ -0,0 +1,120 @@ +// @flow +// +import type { BaseStoreOpsHandlers } from './base-ops.js'; +import type { + SyncedMetadata, + SyncedMetadataStore, +} from '../types/synced-metadata-types.js'; + +// client types + +export type ReplaceSyncedMetadataEntryOperation = { + +type: 'replace_synced_metadata_entry', + +payload: { + +name: string, + +data: string, + }, +}; + +export type RemoveSyncedMetadataOperation = { + +type: 'remove_synced_metadata', + +payload: { +names: $ReadOnlyArray }, +}; + +export type RemoveAllSyncedMetadataOperation = { + +type: 'remove_all_synced_metadata', +}; + +export type SyncedMetadataStoreOperation = + | ReplaceSyncedMetadataEntryOperation + | RemoveSyncedMetadataOperation + | RemoveAllSyncedMetadataOperation; + +// SQLite types + +export type ClientDBSyncedMetadataEntry = { + +name: string, + +data: string, +}; + +export type ClientDBReplaceSyncedMetadataEntryOperation = { + +type: 'replace_synced_metadata_entry', + +payload: ClientDBSyncedMetadataEntry, +}; + +export type ClientDBSyncedMetadataStoreOperation = + | ClientDBReplaceSyncedMetadataEntryOperation + | RemoveSyncedMetadataOperation + | RemoveAllSyncedMetadataOperation; + +const syncedMetadataStoreOpsHandlers: BaseStoreOpsHandlers< + SyncedMetadataStore, + SyncedMetadataStoreOperation, + ClientDBSyncedMetadataStoreOperation, + SyncedMetadata, + ClientDBSyncedMetadataEntry, +> = { + processStoreOperations( + syncedMetadataStore: SyncedMetadataStore, + ops: $ReadOnlyArray, + ): SyncedMetadataStore { + if (ops.length === 0) { + return syncedMetadataStore; + } + + let processedSyncedMetadata = { ...syncedMetadataStore.syncedMetadata }; + + for (const operation of ops) { + if (operation.type === 'replace_synced_metadata_entry') { + processedSyncedMetadata[operation.payload.name] = + operation.payload.data; + } else if (operation.type === 'remove_synced_metadata') { + for (const name of operation.payload.names) { + delete processedSyncedMetadata[name]; + } + } else if (operation.type === 'remove_all_synced_metadata') { + processedSyncedMetadata = {}; + } + } + + return { + ...syncedMetadataStore, + syncedMetadata: processedSyncedMetadata, + }; + }, + + convertOpsToClientDBOps( + ops: $ReadOnlyArray, + ): $ReadOnlyArray { + return ops.map(operation => { + if ( + operation.type === 'remove_synced_metadata' || + operation.type === 'remove_all_synced_metadata' + ) { + return operation; + } + + return { + type: 'replace_synced_metadata_entry', + payload: { + name: operation.payload.name, + data: operation.payload.data, + }, + }; + }); + }, + + translateClientDBData( + communites: $ReadOnlyArray, + ): SyncedMetadata { + const syncedMetadata: { [name: string]: string } = {}; + + communites.forEach(dbSyncedMetadata => { + syncedMetadata[dbSyncedMetadata.name] = dbSyncedMetadata.data; + }); + + return syncedMetadata; + }, +}; + +export { syncedMetadataStoreOpsHandlers };