diff --git a/lib/ops/entries-store-ops.js b/lib/ops/entries-store-ops.js --- a/lib/ops/entries-store-ops.js +++ b/lib/ops/entries-store-ops.js @@ -2,19 +2,24 @@ import type { BaseStoreOpsHandlers } from './base-ops.js'; import { daysToEntriesFromEntryInfos } from '../reducers/entry-reducer.js'; +import { threadSpecs } from '../shared/threads/thread-specs.js'; import type { EntryStore, RawEntryInfo, RawEntryInfos, } from '../types/entry-types.js'; +import type { RawThreadInfos } from '../types/thread-types.js'; import { values } from '../utils/objects.js'; +type ReplaceEntryOperationPayload = { + +id: string, + +entry: RawEntryInfo, + +isBackedUp: boolean, +}; + export type ReplaceEntryOperation = { +type: 'replace_entry', - +payload: { - +id: string, - +entry: RawEntryInfo, - }, + +payload: ReplaceEntryOperationPayload, }; export type RemoveEntriesOperation = { @@ -49,10 +54,7 @@ function convertEntryInfoIntoClientDBEntryInfo({ id, entry, -}: { - +id: string, - +entry: RawEntryInfo, -}): ClientDBEntryInfo { +}: ReplaceEntryOperationPayload): ClientDBEntryInfo { return { id, entry: JSON.stringify(entry), @@ -131,4 +133,30 @@ }, }; -export { convertEntryInfoIntoClientDBEntryInfo, entryStoreOpsHandlers }; +function createReplaceEntryOperation( + id: string, + entry: RawEntryInfo, + threadInfos: RawThreadInfos, +): ReplaceEntryOperation { + const threadInfo = threadInfos[entry.threadID]; + if (!threadInfo) { + return { + type: 'replace_entry', + payload: { id, entry, isBackedUp: true }, + }; + } + return { + type: 'replace_entry', + payload: { + id, + entry, + isBackedUp: threadSpecs[threadInfo.type].protocol.dataIsBackedUp, + }, + }; +} + +export { + convertEntryInfoIntoClientDBEntryInfo, + entryStoreOpsHandlers, + createReplaceEntryOperation, +}; diff --git a/lib/ops/entries-store-ops.test.js b/lib/ops/entries-store-ops.test.js --- a/lib/ops/entries-store-ops.test.js +++ b/lib/ops/entries-store-ops.test.js @@ -55,6 +55,7 @@ payload: { id: '123', entry: newEntry, + isBackedUp: false, }, }, ]), @@ -135,6 +136,7 @@ payload: { id: key, entry: entryStore.entryInfos[key], + isBackedUp: false, }, }; expect( diff --git a/lib/reducers/entry-reducer.js b/lib/reducers/entry-reducer.js --- a/lib/reducers/entry-reducer.js +++ b/lib/reducers/entry-reducer.js @@ -40,7 +40,10 @@ } from '../actions/user-actions.js'; import { setNewSessionActionType } from '../keyserver-conn/keyserver-conn-types.js'; import type { EntryStoreOperation } from '../ops/entries-store-ops.js'; -import { entryStoreOpsHandlers } from '../ops/entries-store-ops.js'; +import { + createReplaceEntryOperation, + entryStoreOpsHandlers, +} from '../ops/entries-store-ops.js'; import { entryID } from '../shared/entry-utils.js'; import { stateSyncSpecs } from '../shared/state-sync/state-sync-specs.js'; import { threadInFilterList } from '../shared/thread-utils.js'; @@ -138,13 +141,9 @@ if (_isEqual(currentEntryInfo)(newEntryInfo)) { mergedEntryInfos[serverID] = currentEntryInfo; } else { - ops.push({ - type: 'replace_entry', - payload: { - id: serverID, - entry: newEntryInfo, - }, - }); + ops.push( + createReplaceEntryOperation(serverID, newEntryInfo, threadInfos), + ); mergedEntryInfos[serverID] = newEntryInfo; } } @@ -199,6 +198,7 @@ const markAsDeletedOps = markDeletedEntries( updatedEntryInfos, deletedEntryIDs, + newThreadInfos, ); const ops = [...mergeEntriesOps, ...markAsDeletedOps]; return { @@ -233,13 +233,9 @@ } const ops = [ { type: 'remove_all_entries' }, - ...Object.entries(newEntryInfos).map(([id, entry]) => ({ - type: 'replace_entry', - payload: { - id, - entry, - }, - })), + ...Object.entries(newEntryInfos).map(([id, entry]) => + createReplaceEntryOperation(id, entry, newThreadInfos), + ), ]; return { entryStore: entryStoreOpsHandlers.processStoreOperations(entryStore, ops), @@ -273,13 +269,9 @@ } const ops = [ { type: 'remove_all_entries' }, - ...Object.entries(newEntryInfos).map(([id, entry]) => ({ - type: 'replace_entry', - payload: { - id, - entry, - }, - })), + ...Object.entries(newEntryInfos).map(([id, entry]) => + createReplaceEntryOperation(id, entry, newThreadInfos), + ), ]; return { entryStore: { @@ -332,6 +324,7 @@ const markAsDeletedOps = markDeletedEntries( updatedEntryInfos, action.payload.deletedEntryIDs, + newThreadInfos, ); const ops = [...mergeEntriesOps, ...markAsDeletedOps]; return { @@ -347,13 +340,7 @@ const localID = entryInfo.localID; invariant(localID, 'localID should be set in CREATE_LOCAL_ENTRY'); const ops = [ - { - type: 'replace_entry', - payload: { - id: localID, - entry: entryInfo, - }, - }, + createReplaceEntryOperation(localID, entryInfo, newThreadInfos), ]; return { entryStore: { @@ -454,17 +441,12 @@ reportCreationRequests: [], }; } + const newEntry: RawEntryInfo = { + ...entryInfos[payload.id], + text: payload.dbText, + }; const ops = [ - { - type: 'replace_entry', - payload: { - id: payload.id, - entry: { - ...entryInfos[payload.id], - text: payload.dbText, - }, - }, - }, + createReplaceEntryOperation(payload.id, newEntry, newThreadInfos), ]; return { entryStore: entryStoreOpsHandlers.processStoreOperations(entryStore, ops), @@ -478,18 +460,11 @@ ? payload.serverID : payload.localID; invariant(id, 'either serverID or localID should be set'); - const ops = [ - { - type: 'replace_entry', - payload: { - id, - entry: { - ...entryInfos[id], - deleted: true, - }, - }, - }, - ]; + const newEntry: RawEntryInfo = { + ...entryInfos[id], + deleted: true, + }; + const ops = [createReplaceEntryOperation(id, newEntry, newThreadInfos)]; return { entryStore: { ...entryStoreOpsHandlers.processStoreOperations(entryStore, ops), @@ -530,19 +505,12 @@ }; } // Make sure the entry is in sync with its latest revision - const ops = [ - { - type: 'replace_entry', - payload: { - id, - entry: { - ...entryInfos[id], - text: action.payload.text, - deleted: action.payload.deleted, - }, - }, - }, - ]; + const newEntry: RawEntryInfo = { + ...entryInfos[id], + text: action.payload.text, + deleted: action.payload.deleted, + }; + const ops = [createReplaceEntryOperation(id, newEntry, newThreadInfos)]; return { entryStore: entryStoreOpsHandlers.processStoreOperations(entryStore, ops), entryStoreOperations: ops, @@ -658,13 +626,9 @@ { type: 'remove_all_entries', }, - ...Object.entries(newEntryInfos).map(([id, entry]) => ({ - type: 'replace_entry', - payload: { - id, - entry, - }, - })), + ...Object.entries(newEntryInfos).map(([id, entry]) => + createReplaceEntryOperation(id, entry, newThreadInfos), + ), ]; return { entryStore: entryStoreOpsHandlers.processStoreOperations(entryStore, ops), @@ -785,6 +749,7 @@ function markDeletedEntries( entryInfos: { +[id: string]: RawEntryInfo }, deletedEntryIDs: $ReadOnlyArray, + threadInfos: RawThreadInfos, ): $ReadOnlyArray { const ops = []; for (const deletedEntryID of deletedEntryIDs) { @@ -792,16 +757,13 @@ if (!entryInfo || entryInfo.deleted) { continue; } - ops.push({ - type: 'replace_entry', - payload: { - id: deletedEntryID, - entry: { - ...entryInfo, - deleted: true, - }, - }, - }); + const newEntry: RawEntryInfo = { + ...entryInfo, + deleted: true, + }; + ops.push( + createReplaceEntryOperation(deletedEntryID, newEntry, threadInfos), + ); } return ops; } diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -1334,6 +1334,11 @@ payload: { id, entry, + // Adding this only to support types, when this migration was + // implemented, backup was not yet supported, because of that, + // this migration should maintain the default behaviour. + // Migrating DM entries to be supported by backup is added later. + isBackedUp: false, }, })); diff --git a/web/redux/initial-state-gate.js b/web/redux/initial-state-gate.js --- a/web/redux/initial-state-gate.js +++ b/web/redux/initial-state-gate.js @@ -202,7 +202,10 @@ entryStoreOperations = entries(payload.entryStore.entryInfos).map( ([id, entry]) => ({ type: 'replace_entry', - payload: { id, entry }, + // This code is responsible for migrating keyserver entries to + // SQLite, which means this data shouldn't be included in the + // backup because it is owned by keyserver. + payload: { id, entry, isBackedUp: false }, }), ); } diff --git a/web/shared-worker/queries/entry-queries.test.js b/web/shared-worker/queries/entry-queries.test.js --- a/web/shared-worker/queries/entry-queries.test.js +++ b/web/shared-worker/queries/entry-queries.test.js @@ -54,10 +54,18 @@ throw new Error('SQLiteQueryExecutor is missing'); } queryExecutor?.replaceEntry( - convertEntryInfoIntoClientDBEntryInfo({ id: '0', entry: TEST_ENTRY_1 }), + convertEntryInfoIntoClientDBEntryInfo({ + id: '0', + entry: TEST_ENTRY_1, + isBackedUp: false, + }), ); queryExecutor?.replaceEntry( - convertEntryInfoIntoClientDBEntryInfo({ id: '1', entry: TEST_ENTRY_2 }), + convertEntryInfoIntoClientDBEntryInfo({ + id: '1', + entry: TEST_ENTRY_2, + isBackedUp: true, + }), ); }); @@ -89,6 +97,7 @@ convertEntryInfoIntoClientDBEntryInfo({ id: '1', entry: updatedTestEntry, + isBackedUp: false, }), );