diff --git a/lib/ops/keyserver-store-ops.js b/lib/ops/keyserver-store-ops.js new file mode 100644 index 000000000..da7b2156d --- /dev/null +++ b/lib/ops/keyserver-store-ops.js @@ -0,0 +1,132 @@ +// @flow + +import { type BaseStoreOpsHandlers } from './base-ops.js'; +import { + transformKeyserverInfoToPersistedKeyserverInfo, + transformPersistedKeyserverInfoToKeyserverInfo, +} from '../shared/transforms/keyserver-store-transform.js'; +import type { + KeyserverInfo, + KeyserverInfos, +} from '../types/keyserver-types.js'; + +// client types +export type ReplaceKeyserverOperation = { + +type: 'replace_keyserver', + +payload: { +id: string, +keyserverInfo: KeyserverInfo }, +}; + +export type RemoveKeyserversOperation = { + +type: 'remove_keyservers', + +payload: { +ids: $ReadOnlyArray }, +}; + +export type RemoveAllKeyserversOperation = { + +type: 'remove_all_keyservers', +}; + +export type KeyserverStoreOperation = + | ReplaceKeyserverOperation + | RemoveKeyserversOperation + | RemoveAllKeyserversOperation; + +// SQLite types +export type ClientDBKeyserverInfo = { + +id: string, + +keyserverInfo: string, +}; + +export type ClientDBReplaceKeyserverOperation = { + +type: 'replace_keyserver', + +payload: ClientDBKeyserverInfo, +}; + +export type ClientDBKeyserverStoreOperation = + | ClientDBReplaceKeyserverOperation + | RemoveKeyserversOperation + | RemoveAllKeyserversOperation; + +function convertKeyserverInfoToClientDBKeyserverInfo({ + id, + keyserverInfo, +}: { + +id: string, + +keyserverInfo: KeyserverInfo, +}): ClientDBKeyserverInfo { + const persistedKeyserverInfo = + transformKeyserverInfoToPersistedKeyserverInfo(keyserverInfo); + return { + id, + keyserverInfo: JSON.stringify(persistedKeyserverInfo), + }; +} + +function convertClientDBKeyserverInfoToKeyserverInfo( + dbKeyserverInfo: ClientDBKeyserverInfo, +): KeyserverInfo { + const persistedKeyserverInfo = JSON.parse(dbKeyserverInfo.keyserverInfo); + return transformPersistedKeyserverInfoToKeyserverInfo(persistedKeyserverInfo); +} + +const keyserverStoreOpsHandlers: BaseStoreOpsHandlers< + KeyserverInfos, + KeyserverStoreOperation, + ClientDBKeyserverStoreOperation, + KeyserverInfos, + ClientDBKeyserverInfo, +> = { + processStoreOperations( + keyserverInfos: KeyserverInfos, + ops: $ReadOnlyArray, + ): KeyserverInfos { + if (ops.length === 0) { + return keyserverInfos; + } + + let processedKeyserverInfos = { ...keyserverInfos }; + for (const operation: KeyserverStoreOperation of ops) { + if (operation.type === 'replace_keyserver') { + processedKeyserverInfos[operation.payload.id] = + operation.payload.keyserverInfo; + } else if (operation.type === 'remove_keyservers') { + for (const id of operation.payload.ids) { + delete processedKeyserverInfos[id]; + } + } else if (operation.type === 'remove_all_keyservers') { + processedKeyserverInfos = {}; + } + } + return processedKeyserverInfos; + }, + + convertOpsToClientDBOps( + ops: $ReadOnlyArray, + ): $ReadOnlyArray { + return ops.map(operation => { + if ( + operation.type === 'remove_keyservers' || + operation.type === 'remove_all_keyservers' + ) { + return operation; + } + return { + type: 'replace_keyserver', + payload: convertKeyserverInfoToClientDBKeyserverInfo(operation.payload), + }; + }); + }, + + translateClientDBData( + keyservers: $ReadOnlyArray, + ): KeyserverInfos { + const keyserverInfos: { [id: string]: KeyserverInfo } = {}; + keyservers.forEach(dbKeyserver => { + keyserverInfos[dbKeyserver.id] = + convertClientDBKeyserverInfoToKeyserverInfo(dbKeyserver); + }); + + return keyserverInfos; + }, +}; + +export { keyserverStoreOpsHandlers };