Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3298461
D11538.id38840.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
14 KB
Referenced Files
None
Subscribers
None
D11538.id38840.diff
View Options
diff --git a/keyserver/src/responders/redux-state-responders.js b/keyserver/src/responders/redux-state-responders.js
--- a/keyserver/src/responders/redux-state-responders.js
+++ b/keyserver/src/responders/redux-state-responders.js
@@ -68,6 +68,7 @@
import { thisKeyserverID } from '../user/identity.js';
const excludedDataValidator: TInterface<ExcludedData> = tShape<ExcludedData>({
+ userStore: t.maybe(t.Bool),
threadStore: t.maybe(t.Bool),
});
@@ -238,6 +239,10 @@
};
})();
const userInfosPromise = (async () => {
+ if (excludedData.userStore && useDatabase) {
+ return {};
+ }
+
const [userInfos, hasNotAcknowledgedPolicies] = await Promise.all([
userInfoPromise,
hasNotAcknowledgedPoliciesPromise,
diff --git a/lib/types/store-ops-types.js b/lib/types/store-ops-types.js
--- a/lib/types/store-ops-types.js
+++ b/lib/types/store-ops-types.js
@@ -55,6 +55,7 @@
ThreadStoreOperation,
} from '../ops/thread-store-ops.js';
import type {
+ ClientDBUserStoreOperation,
UserStoreOperation,
ClientDBUserInfo,
} from '../ops/user-store-ops.js';
@@ -77,6 +78,7 @@
+threadStoreOperations?: $ReadOnlyArray<ClientDBThreadStoreOperation>,
+messageStoreOperations?: $ReadOnlyArray<ClientDBMessageStoreOperation>,
+reportStoreOperations?: $ReadOnlyArray<ClientDBReportStoreOperation>,
+ +userStoreOperations?: $ReadOnlyArray<ClientDBUserStoreOperation>,
+keyserverStoreOperations?: $ReadOnlyArray<ClientDBKeyserverStoreOperation>,
+communityStoreOperations?: $ReadOnlyArray<ClientDBCommunityStoreOperation>,
+integrityStoreOperations?: $ReadOnlyArray<ClientDBIntegrityStoreOperation>,
diff --git a/web/redux/action-types.js b/web/redux/action-types.js
--- a/web/redux/action-types.js
+++ b/web/redux/action-types.js
@@ -58,9 +58,9 @@
continue;
}
const clientUpdatesCurrentAsOf = allUpdatesCurrentAsOf[keyserverID];
- const keyserverExcludedData: ExcludedData = {
- threadStore: !!excludedData.threadStore && !!clientUpdatesCurrentAsOf,
- };
+ const keyserverExcludedData: ExcludedData = clientUpdatesCurrentAsOf
+ ? excludedData
+ : {};
if (keyserverID === threadKeyserverID) {
requests[keyserverID] = {
urlInfo,
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
@@ -6,12 +6,13 @@
import { setClientDBStoreActionType } from 'lib/actions/client-db-store-actions.js';
import type { ThreadStoreOperation } from 'lib/ops/thread-store-ops.js';
+import type { UserStoreOperation } from 'lib/ops/user-store-ops.js';
import { allUpdatesCurrentAsOfSelector } from 'lib/selectors/keyserver-selectors.js';
import { canUseDatabaseOnWeb } from 'lib/shared/web-database.js';
import type { RawThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
import type { LegacyRawThreadInfo } from 'lib/types/thread-types.js';
import { convertIDToNewSchema } from 'lib/utils/migration-utils.js';
-import { entries } from 'lib/utils/objects.js';
+import { entries, values } from 'lib/utils/objects.js';
import { useDispatch } from 'lib/utils/redux-utils.js';
import { infoFromURL } from 'lib/utils/url-utils.js';
@@ -26,6 +27,7 @@
getClientDBStore,
processDBStoreOperations,
} from '../shared-worker/utils/store.js';
+import type { InitialReduxStateActionPayload } from '../types/redux-types';
type Props = {
+persistor: Persistor,
@@ -75,6 +77,7 @@
urlInfo,
excludedData: {
threadStore: !!clientDBStore.threadStore,
+ userStore: !!clientDBStore.users,
},
allUpdatesCurrentAsOf,
});
@@ -89,50 +92,65 @@
return;
}
+ let initialReduxState: InitialReduxStateActionPayload = payload;
+
+ let threadStoreOperations: ThreadStoreOperation[] = [];
if (clientDBStore.threadStore) {
- const { threadStore, ...rest } = payload;
- dispatch({ type: setInitialReduxState, payload: rest });
- return;
+ const { threadStore, ...rest } = initialReduxState;
+ initialReduxState = rest;
+ } else {
+ // When there is no data in the DB, it's necessary to migrate data
+ // from the keyserver payload to the DB
+ threadStoreOperations = entries(payload.threadStore.threadInfos).map(
+ ([id, threadInfo]: [
+ string,
+ LegacyRawThreadInfo | RawThreadInfo,
+ ]) => ({
+ type: 'replace',
+ payload: {
+ id,
+ threadInfo,
+ },
+ }),
+ );
+ }
+
+ let userStoreOperations: UserStoreOperation[] = [];
+ if (clientDBStore.users) {
+ const { userInfos, ...rest } = initialReduxState;
+ initialReduxState = rest;
+ } else {
+ userStoreOperations = values(payload.userInfos).map(userInfo => ({
+ type: 'replace_user',
+ payload: userInfo,
+ }));
}
- // When there is no data in the DB, it's necessary to migrate data
- // from the keyserver payload to the DB
- const {
- threadStore: { threadInfos },
- } = payload;
-
- const threadStoreOperations: ThreadStoreOperation[] = entries(
- threadInfos,
- ).map(
- ([id, threadInfo]: [
- string,
- LegacyRawThreadInfo | RawThreadInfo,
- ]) => ({
- type: 'replace',
- payload: {
- id,
- threadInfo,
+ if (
+ threadStoreOperations.length > 0 ||
+ userStoreOperations.length > 0
+ ) {
+ await processDBStoreOperations(
+ {
+ threadStoreOperations,
+ draftStoreOperations: [],
+ messageStoreOperations: [],
+ reportStoreOperations: [],
+ userStoreOperations,
+ keyserverStoreOperations: [],
+ communityStoreOperations: [],
+ integrityStoreOperations: [],
+ syncedMetadataStoreOperations: [],
+ auxUserStoreOperations: [],
},
- }),
- );
-
- await processDBStoreOperations(
- {
- threadStoreOperations,
- draftStoreOperations: [],
- messageStoreOperations: [],
- reportStoreOperations: [],
- userStoreOperations: [],
- keyserverStoreOperations: [],
- communityStoreOperations: [],
- integrityStoreOperations: [],
- syncedMetadataStoreOperations: [],
- auxUserStoreOperations: [],
- },
- currentLoggedInUserID,
- );
+ currentLoggedInUserID,
+ );
+ }
- dispatch({ type: setInitialReduxState, payload });
+ dispatch({
+ type: setInitialReduxState,
+ payload: initialReduxState,
+ });
} catch (err) {
setInitError(err);
}
diff --git a/web/redux/redux-setup.js b/web/redux/redux-setup.js
--- a/web/redux/redux-setup.js
+++ b/web/redux/redux-setup.js
@@ -69,7 +69,7 @@
import { reduceServicesAccessToken } from './services-access-token-reducer.js';
import { getVisibility } from './visibility.js';
import { activeThreadSelector } from '../selectors/nav-selectors.js';
-import type { InitialReduxState } from '../types/redux-types.js';
+import type { InitialReduxStateActionPayload } from '../types/redux-types.js';
export type WindowDimensions = { width: number, height: number };
@@ -142,7 +142,10 @@
+type: 'UPDATE_WINDOW_ACTIVE',
+payload: boolean,
}
- | { +type: 'SET_INITIAL_REDUX_STATE', +payload: InitialReduxState },
+ | {
+ +type: 'SET_INITIAL_REDUX_STATE',
+ +payload: InitialReduxStateActionPayload,
+ },
},
>;
@@ -197,27 +200,26 @@
},
});
}
- return validateStateAndQueueOpsProcessing(
- action,
- oldState,
- {
- ...state,
- ...rest,
- userStore: { userInfos },
- keyserverStore: keyserverStoreOpsHandlers.processStoreOperations(
- state.keyserverStore,
- replaceOperations,
- ),
- initialStateLoaded: true,
- },
- {
- ...storeOperations,
- keyserverStoreOperations: [
- ...storeOperations.keyserverStoreOperations,
- ...replaceOperations,
- ],
- },
- );
+ let newState = {
+ ...state,
+ ...rest,
+ keyserverStore: keyserverStoreOpsHandlers.processStoreOperations(
+ state.keyserverStore,
+ replaceOperations,
+ ),
+ initialStateLoaded: true,
+ };
+
+ if (userInfos) {
+ newState = { ...newState, userStore: { userInfos } };
+ }
+ return validateStateAndQueueOpsProcessing(action, oldState, newState, {
+ ...storeOperations,
+ keyserverStoreOperations: [
+ ...storeOperations.keyserverStoreOperations,
+ ...replaceOperations,
+ ],
+ });
} else if (action.type === updateWindowDimensionsActionType) {
return validateStateAndQueueOpsProcessing(
action,
diff --git a/web/shared-worker/utils/store.js b/web/shared-worker/utils/store.js
--- a/web/shared-worker/utils/store.js
+++ b/web/shared-worker/utils/store.js
@@ -7,6 +7,7 @@
import { reportStoreOpsHandlers } from 'lib/ops/report-store-ops.js';
import { syncedMetadataStoreOpsHandlers } from 'lib/ops/synced-metadata-store-ops.js';
import { threadStoreOpsHandlers } from 'lib/ops/thread-store-ops.js';
+import { userStoreOpsHandlers } from 'lib/ops/user-store-ops.js';
import { canUseDatabaseOnWeb } from 'lib/shared/web-database.js';
import type {
ClientStore,
@@ -98,6 +99,12 @@
),
};
}
+ if (data?.store?.users && data.store.users.length > 0) {
+ result = {
+ ...result,
+ users: userStoreOpsHandlers.translateClientDBData(data.store.users),
+ };
+ }
return result;
}
@@ -114,6 +121,7 @@
integrityStoreOperations,
syncedMetadataStoreOperations,
auxUserStoreOperations,
+ userStoreOperations,
} = storeOperations;
const canUseDatabase = canUseDatabaseOnWeb(userID);
@@ -135,6 +143,8 @@
);
const convertedAuxUserStoreOperations =
auxUserStoreOpsHandlers.convertOpsToClientDBOps(auxUserStoreOperations);
+ const convertedUserStoreOperations =
+ userStoreOpsHandlers.convertOpsToClientDBOps(userStoreOperations);
if (
convertedThreadStoreOperations.length === 0 &&
@@ -144,7 +154,8 @@
convertedCommunityStoreOperations.length === 0 &&
convertedIntegrityStoreOperations.length === 0 &&
convertedSyncedMetadataStoreOperations.length === 0 &&
- convertedAuxUserStoreOperations.length === 0
+ convertedAuxUserStoreOperations.length === 0 &&
+ convertedUserStoreOperations.length === 0
) {
return;
}
@@ -166,6 +177,7 @@
integrityStoreOperations: convertedIntegrityStoreOperations,
syncedMetadataStoreOperations: convertedSyncedMetadataStoreOperations,
auxUserStoreOperations: convertedAuxUserStoreOperations,
+ userStoreOperations: convertedUserStoreOperations,
},
});
} catch (e) {
diff --git a/web/shared-worker/worker/process-operations.js b/web/shared-worker/worker/process-operations.js
--- a/web/shared-worker/worker/process-operations.js
+++ b/web/shared-worker/worker/process-operations.js
@@ -7,6 +7,7 @@
import type { ClientDBReportStoreOperation } from 'lib/ops/report-store-ops.js';
import type { ClientDBSyncedMetadataStoreOperation } from 'lib/ops/synced-metadata-store-ops.js';
import type { ClientDBThreadStoreOperation } from 'lib/ops/thread-store-ops.js';
+import type { ClientDBUserStoreOperation } from 'lib/ops/user-store-ops.js';
import type {
ClientDBDraftStoreOperation,
DraftStoreOperation,
@@ -255,6 +256,34 @@
}
}
+function processUserStoreOperations(
+ sqliteQueryExecutor: SQLiteQueryExecutor,
+ operations: $ReadOnlyArray<ClientDBUserStoreOperation>,
+ module: EmscriptenModule,
+) {
+ for (const operation of operations) {
+ try {
+ if (operation.type === 'remove_users') {
+ const { ids } = operation.payload;
+ sqliteQueryExecutor.removeUsers(ids);
+ } else if (operation.type === 'replace_user') {
+ const user = operation.payload;
+ sqliteQueryExecutor.replaceUser(user);
+ } else if (operation.type === 'remove_all_users') {
+ sqliteQueryExecutor.removeAllUsers();
+ } else {
+ throw new Error('Unsupported user operation');
+ }
+ } catch (e) {
+ throw new Error(
+ `Error while processing ${
+ operation.type
+ } user operation: ${getProcessingStoreOpsExceptionMessage(e, module)}`,
+ );
+ }
+ }
+}
+
function processDBStoreOperations(
sqliteQueryExecutor: SQLiteQueryExecutor,
storeOperations: ClientDBStoreOperations,
@@ -269,6 +298,7 @@
integrityStoreOperations,
syncedMetadataStoreOperations,
auxUserStoreOperations,
+ userStoreOperations,
} = storeOperations;
try {
@@ -332,6 +362,13 @@
module,
);
}
+ if (userStoreOperations && userStoreOperations.length > 0) {
+ processUserStoreOperations(
+ sqliteQueryExecutor,
+ userStoreOperations,
+ module,
+ );
+ }
sqliteQueryExecutor.commitTransaction();
} catch (e) {
sqliteQueryExecutor.rollbackTransaction();
@@ -382,7 +419,7 @@
.map(t => webThreadToClientDBThreadInfo(t)),
messageStoreThreads: [],
reports: sqliteQueryExecutor.getAllReports(),
- users: [],
+ users: sqliteQueryExecutor.getAllUsers(),
keyservers: sqliteQueryExecutor.getAllKeyservers(),
communities: sqliteQueryExecutor.getAllCommunities(),
integrityThreadHashes: sqliteQueryExecutor.getAllIntegrityThreadHashes(),
diff --git a/web/types/redux-types.js b/web/types/redux-types.js
--- a/web/types/redux-types.js
+++ b/web/types/redux-types.js
@@ -23,7 +23,22 @@
+keyserverInfos: { +[keyserverID: string]: WebInitialKeyserverInfo },
};
+export type InitialReduxStateActionPayload = {
+ +navInfo: WebNavInfo,
+ +currentUserInfo: CurrentUserInfo,
+ +entryStore: EntryStore,
+ +threadStore?: ThreadStore,
+ +userInfos?: UserInfos,
+ +messageStore: MessageStore,
+ +pushApiPublicKey: ?string,
+ +inviteLinksStore: InviteLinksStore,
+ +dataLoaded: boolean,
+ +actualizedCalendarQuery: CalendarQuery,
+ +keyserverInfos: { +[keyserverID: string]: WebInitialKeyserverInfo },
+};
+
export type ExcludedData = {
+ +userStore?: boolean,
+threadStore?: boolean,
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 18, 6:35 AM (22 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2534130
Default Alt Text
D11538.id38840.diff (14 KB)
Attached To
Mode
D11538: [web] Persist userStore in db
Attached
Detach File
Event Timeline
Log In to Comment