diff --git a/keyserver/src/creators/update-creator.js b/keyserver/src/creators/update-creator.js --- a/keyserver/src/creators/update-creator.js +++ b/keyserver/src/creators/update-creator.js @@ -8,16 +8,14 @@ keyForUpdateInfo, rawUpdateInfoFromUpdateData, } from 'lib/shared/update-utils.js'; +import type { UpdateInfosRawData } from 'lib/shared/updates/update-spec.js'; import { updateSpecs } from 'lib/shared/updates/update-specs.js'; import { - type RawEntryInfos, - type FetchEntryInfosBase, type CalendarQuery, defaultCalendarQuery, } from 'lib/types/entry-types.js'; import { defaultNumberPerThread, - type FetchMessageInfosResult, type MessageSelectionCriteria, } from 'lib/types/message-types.js'; import { @@ -25,7 +23,7 @@ redisMessageTypes, type NewUpdatesRedisMessage, } from 'lib/types/redis-types.js'; -import type { RawThreadInfo, RawThreadInfos } from 'lib/types/thread-types.js'; +import type { RawThreadInfo } from 'lib/types/thread-types.js'; import { updateTypes } from 'lib/types/update-types-enum.js'; import { type ServerUpdateInfo, @@ -33,7 +31,7 @@ type RawUpdateInfo, type CreateUpdatesResult, } from 'lib/types/update-types.js'; -import type { UserInfos, LoggedInUserInfo } from 'lib/types/user-types.js'; +import type { UserInfos } from 'lib/types/user-types.js'; import { promiseAll } from 'lib/utils/promises.js'; import createIDs from './id-creator.js'; @@ -484,27 +482,12 @@ }); } -export type UpdateInfosRawData = { - threadInfos: RawThreadInfos, - messageInfosResult: ?FetchMessageInfosResult, - calendarResult: ?FetchEntryInfosBase, - entryInfosResult: ?RawEntryInfos, - currentUserInfoResult: LoggedInUserInfo, -}; async function updateInfosFromRawUpdateInfos( viewer: Viewer, rawUpdateInfos: $ReadOnlyArray, rawData: UpdateInfosRawData, ): Promise { - const { - threadInfos, - messageInfosResult, - calendarResult, - entryInfosResult, - currentUserInfoResult, - } = rawData; - const updateInfos = []; - const userIDsToFetch = new Set(); + const { messageInfosResult, calendarResult } = rawData; const rawEntryInfosByThreadID = {}; for (const entryInfo of calendarResult?.rawEntryInfos ?? []) { @@ -522,114 +505,23 @@ rawMessageInfosByThreadID[messageInfo.threadID].push(messageInfo); } - for (const rawUpdateInfo of rawUpdateInfos) { - if (rawUpdateInfo.type === updateTypes.DELETE_ACCOUNT) { - updateInfos.push({ - type: updateTypes.DELETE_ACCOUNT, - id: rawUpdateInfo.id, - time: rawUpdateInfo.time, - deletedUserID: rawUpdateInfo.deletedUserID, - }); - } else if (rawUpdateInfo.type === updateTypes.UPDATE_THREAD) { - const threadInfo = threadInfos[rawUpdateInfo.threadID]; - if (!threadInfo) { - console.warn( - "failed to hydrate updateTypes.UPDATE_THREAD because we couldn't " + - `fetch RawThreadInfo for ${rawUpdateInfo.threadID}`, - ); - continue; - } - updateInfos.push({ - type: updateTypes.UPDATE_THREAD, - id: rawUpdateInfo.id, - time: rawUpdateInfo.time, - threadInfo, - }); - } else if (rawUpdateInfo.type === updateTypes.UPDATE_THREAD_READ_STATUS) { - updateInfos.push({ - type: updateTypes.UPDATE_THREAD_READ_STATUS, - id: rawUpdateInfo.id, - time: rawUpdateInfo.time, - threadID: rawUpdateInfo.threadID, - unread: rawUpdateInfo.unread, - }); - } else if (rawUpdateInfo.type === updateTypes.DELETE_THREAD) { - updateInfos.push({ - type: updateTypes.DELETE_THREAD, - id: rawUpdateInfo.id, - time: rawUpdateInfo.time, - threadID: rawUpdateInfo.threadID, - }); - } else if (rawUpdateInfo.type === updateTypes.JOIN_THREAD) { - const threadInfo = threadInfos[rawUpdateInfo.threadID]; - if (!threadInfo) { - console.warn( - "failed to hydrate updateTypes.JOIN_THREAD because we couldn't " + - `fetch RawThreadInfo for ${rawUpdateInfo.threadID}`, - ); - continue; - } - - invariant(calendarResult, 'should be set'); - const rawEntryInfos = - rawEntryInfosByThreadID[rawUpdateInfo.threadID] ?? []; - invariant(messageInfosResult, 'should be set'); - const rawMessageInfos = - rawMessageInfosByThreadID[rawUpdateInfo.threadID] ?? []; - - updateInfos.push({ - type: updateTypes.JOIN_THREAD, - id: rawUpdateInfo.id, - time: rawUpdateInfo.time, - threadInfo, - rawMessageInfos, - truncationStatus: - messageInfosResult.truncationStatuses[rawUpdateInfo.threadID], - rawEntryInfos, - }); - } else if (rawUpdateInfo.type === updateTypes.BAD_DEVICE_TOKEN) { - updateInfos.push({ - type: updateTypes.BAD_DEVICE_TOKEN, - id: rawUpdateInfo.id, - time: rawUpdateInfo.time, - deviceToken: rawUpdateInfo.deviceToken, - }); - } else if (rawUpdateInfo.type === updateTypes.UPDATE_ENTRY) { - invariant(entryInfosResult, 'should be set'); - const entryInfo = entryInfosResult[rawUpdateInfo.entryID]; - if (!entryInfo) { - console.warn( - "failed to hydrate updateTypes.UPDATE_ENTRY because we couldn't " + - `fetch RawEntryInfo for ${rawUpdateInfo.entryID}`, - ); - continue; - } - updateInfos.push({ - type: updateTypes.UPDATE_ENTRY, - id: rawUpdateInfo.id, - time: rawUpdateInfo.time, - entryInfo, - }); - } else if (rawUpdateInfo.type === updateTypes.UPDATE_CURRENT_USER) { - invariant(currentUserInfoResult, 'should be set'); - updateInfos.push({ - type: updateTypes.UPDATE_CURRENT_USER, - id: rawUpdateInfo.id, - time: rawUpdateInfo.time, - currentUserInfo: currentUserInfoResult, - }); - } else if (rawUpdateInfo.type === updateTypes.UPDATE_USER) { - updateInfos.push({ - type: updateTypes.UPDATE_USER, - id: rawUpdateInfo.id, - time: rawUpdateInfo.time, - updatedUserID: rawUpdateInfo.updatedUserID, - }); - userIDsToFetch.add(rawUpdateInfo.updatedUserID); - } else { - invariant(false, `unrecognized updateType ${rawUpdateInfo.type}`); - } - } + const userIDsToFetch = new Set( + rawUpdateInfos + .map(update => + update.type === updateTypes.UPDATE_USER ? update.updatedUserID : null, + ) + .filter(Boolean), + ); + const params = { + data: rawData, + rawEntryInfosByThreadID, + rawMessageInfosByThreadID, + }; + const updateInfos = rawUpdateInfos + .map(update => + updateSpecs[update.type].updateInfoFromRawInfo(update, params), + ) + .filter(Boolean); let userInfos = {}; if (userIDsToFetch.size > 0) { diff --git a/lib/shared/updates/bad-device-token-spec.js b/lib/shared/updates/bad-device-token-spec.js --- a/lib/shared/updates/bad-device-token-spec.js +++ b/lib/shared/updates/bad-device-token-spec.js @@ -26,4 +26,12 @@ const { deviceToken } = data; return JSON.stringify({ deviceToken }); }, + updateInfoFromRawInfo(info: BadDeviceTokenRawUpdateInfo) { + return { + type: updateTypes.BAD_DEVICE_TOKEN, + id: info.id, + time: info.time, + deviceToken: info.deviceToken, + }; + }, }); diff --git a/lib/shared/updates/delete-account-spec.js b/lib/shared/updates/delete-account-spec.js --- a/lib/shared/updates/delete-account-spec.js +++ b/lib/shared/updates/delete-account-spec.js @@ -61,4 +61,12 @@ updateContentForServerDB(data: AccountDeletionUpdateData) { return JSON.stringify({ deletedUserID: data.deletedUserID }); }, + updateInfoFromRawInfo(info: AccountDeletionRawUpdateInfo) { + return { + type: updateTypes.DELETE_ACCOUNT, + id: info.id, + time: info.time, + deletedUserID: info.deletedUserID, + }; + }, }); diff --git a/lib/shared/updates/delete-thread-spec.js b/lib/shared/updates/delete-thread-spec.js --- a/lib/shared/updates/delete-thread-spec.js +++ b/lib/shared/updates/delete-thread-spec.js @@ -52,4 +52,12 @@ const { threadID } = data; return JSON.stringify({ threadID }); }, + updateInfoFromRawInfo(info: ThreadDeletionRawUpdateInfo) { + return { + type: updateTypes.DELETE_THREAD, + id: info.id, + time: info.time, + threadID: info.threadID, + }; + }, }); diff --git a/lib/shared/updates/join-thread-spec.js b/lib/shared/updates/join-thread-spec.js --- a/lib/shared/updates/join-thread-spec.js +++ b/lib/shared/updates/join-thread-spec.js @@ -1,8 +1,9 @@ // @flow +import invariant from 'invariant'; import _isEqual from 'lodash/fp/isEqual.js'; -import type { UpdateSpec } from './update-spec.js'; +import type { UpdateInfoFromRawInfoParams, UpdateSpec } from './update-spec.js'; import type { RawEntryInfo } from '../../types/entry-types.js'; import type { RawMessageInfo, @@ -108,4 +109,34 @@ detailedThreadID: update.threadID, }; }, + updateInfoFromRawInfo( + info: ThreadJoinRawUpdateInfo, + params: UpdateInfoFromRawInfoParams, + ) { + const { data, rawEntryInfosByThreadID, rawMessageInfosByThreadID } = params; + const { threadInfos, calendarResult, messageInfosResult } = data; + const threadInfo = threadInfos[info.threadID]; + if (!threadInfo) { + console.warn( + "failed to hydrate updateTypes.JOIN_THREAD because we couldn't " + + `fetch RawThreadInfo for ${info.threadID}`, + ); + return null; + } + + invariant(calendarResult, 'should be set'); + const rawEntryInfos = rawEntryInfosByThreadID[info.threadID] ?? []; + invariant(messageInfosResult, 'should be set'); + const rawMessageInfos = rawMessageInfosByThreadID[info.threadID] ?? []; + + return { + type: updateTypes.JOIN_THREAD, + id: info.id, + time: info.time, + threadInfo, + rawMessageInfos, + truncationStatus: messageInfosResult.truncationStatuses[info.threadID], + rawEntryInfos, + }; + }, }); diff --git a/lib/shared/updates/update-current-user-spec.js b/lib/shared/updates/update-current-user-spec.js --- a/lib/shared/updates/update-current-user-spec.js +++ b/lib/shared/updates/update-current-user-spec.js @@ -1,8 +1,9 @@ // @flow +import invariant from 'invariant'; import _isEqual from 'lodash/fp/isEqual.js'; -import type { UpdateSpec } from './update-spec.js'; +import type { UpdateInfoFromRawInfoParams, UpdateSpec } from './update-spec.js'; import { updateTypes } from '../../types/update-types-enum.js'; import type { CurrentUserUpdateInfo, @@ -38,4 +39,17 @@ currentUser: true, }; }, + updateInfoFromRawInfo( + info: CurrentUserRawUpdateInfo, + params: UpdateInfoFromRawInfoParams, + ) { + const { currentUserInfoResult } = params.data; + invariant(currentUserInfoResult, 'should be set'); + return { + type: updateTypes.UPDATE_CURRENT_USER, + id: info.id, + time: info.time, + currentUserInfo: currentUserInfoResult, + }; + }, }); diff --git a/lib/shared/updates/update-entry-spec.js b/lib/shared/updates/update-entry-spec.js --- a/lib/shared/updates/update-entry-spec.js +++ b/lib/shared/updates/update-entry-spec.js @@ -1,6 +1,8 @@ // @flow -import type { UpdateSpec } from './update-spec.js'; +import invariant from 'invariant'; + +import type { UpdateInfoFromRawInfoParams, UpdateSpec } from './update-spec.js'; import type { RawEntryInfo } from '../../types/entry-types.js'; import { updateTypes } from '../../types/update-types-enum.js'; import type { @@ -45,4 +47,25 @@ entryID: update.entryID, }; }, + updateInfoFromRawInfo( + info: EntryRawUpdateInfo, + params: UpdateInfoFromRawInfoParams, + ) { + const { entryInfosResult } = params.data; + invariant(entryInfosResult, 'should be set'); + const entryInfo = entryInfosResult[info.entryID]; + if (!entryInfo) { + console.warn( + "failed to hydrate updateTypes.UPDATE_ENTRY because we couldn't " + + `fetch RawEntryInfo for ${info.entryID}`, + ); + return null; + } + return { + type: updateTypes.UPDATE_ENTRY, + id: info.id, + time: info.time, + entryInfo, + }; + }, }); diff --git a/lib/shared/updates/update-spec.js b/lib/shared/updates/update-spec.js --- a/lib/shared/updates/update-spec.js +++ b/lib/shared/updates/update-spec.js @@ -1,10 +1,15 @@ // @flow import type { ThreadStoreOperation } from '../../ops/thread-store-ops.js'; -import type { RawEntryInfo } from '../../types/entry-types.js'; +import type { + FetchEntryInfosBase, + RawEntryInfo, + RawEntryInfos, +} from '../../types/entry-types.js'; import type { RawMessageInfo, MessageTruncationStatuses, + FetchMessageInfosResult, } from '../../types/message-types.js'; import type { RawThreadInfos } from '../../types/thread-types.js'; import type { @@ -12,7 +17,29 @@ RawUpdateInfo, UpdateData, } from '../../types/update-types.js'; -import type { CurrentUserInfo, UserInfos } from '../../types/user-types.js'; +import type { + CurrentUserInfo, + LoggedInUserInfo, + UserInfos, +} from '../../types/user-types.js'; + +export type UpdateInfosRawData = { + +threadInfos: RawThreadInfos, + +messageInfosResult: ?FetchMessageInfosResult, + +calendarResult: ?FetchEntryInfosBase, + +entryInfosResult: ?RawEntryInfos, + +currentUserInfoResult: LoggedInUserInfo, +}; + +export type UpdateInfoFromRawInfoParams = { + +data: UpdateInfosRawData, + +rawEntryInfosByThreadID: { + +[id: string]: $ReadOnlyArray, + }, + +rawMessageInfosByThreadID: { + +[id: string]: $ReadOnlyArray, + }, +}; export type UpdateSpec< UpdateInfo: ClientUpdateInfo, @@ -52,4 +79,8 @@ +entryID?: string, +currentUser?: boolean, }, + +updateInfoFromRawInfo: ( + info: RawInfo, + params: UpdateInfoFromRawInfoParams, + ) => ?UpdateInfo, }; diff --git a/lib/shared/updates/update-thread-read-status-spec.js b/lib/shared/updates/update-thread-read-status-spec.js --- a/lib/shared/updates/update-thread-read-status-spec.js +++ b/lib/shared/updates/update-thread-read-status-spec.js @@ -59,4 +59,13 @@ const { threadID, unread } = data; return JSON.stringify({ threadID, unread }); }, + updateInfoFromRawInfo(info: ThreadReadStatusRawUpdateInfo) { + return { + type: updateTypes.UPDATE_THREAD_READ_STATUS, + id: info.id, + time: info.time, + threadID: info.threadID, + unread: info.unread, + }; + }, }); diff --git a/lib/shared/updates/update-thread-spec.js b/lib/shared/updates/update-thread-spec.js --- a/lib/shared/updates/update-thread-spec.js +++ b/lib/shared/updates/update-thread-spec.js @@ -2,7 +2,7 @@ import _isEqual from 'lodash/fp/isEqual.js'; -import type { UpdateSpec } from './update-spec.js'; +import type { UpdateInfoFromRawInfoParams, UpdateSpec } from './update-spec.js'; import type { RawThreadInfos } from '../../types/thread-types.js'; import { updateTypes } from '../../types/update-types-enum.js'; import type { @@ -65,4 +65,23 @@ threadID: update.threadID, }; }, + updateInfoFromRawInfo( + info: ThreadRawUpdateInfo, + params: UpdateInfoFromRawInfoParams, + ) { + const threadInfo = params.data.threadInfos[info.threadID]; + if (!threadInfo) { + console.warn( + "failed to hydrate updateTypes.UPDATE_THREAD because we couldn't " + + `fetch RawThreadInfo for ${info.threadID}`, + ); + return null; + } + return { + type: updateTypes.UPDATE_THREAD, + id: info.id, + time: info.time, + threadInfo, + }; + }, }); diff --git a/lib/shared/updates/update-user-spec.js b/lib/shared/updates/update-user-spec.js --- a/lib/shared/updates/update-user-spec.js +++ b/lib/shared/updates/update-user-spec.js @@ -26,4 +26,12 @@ const { updatedUserID } = data; return JSON.stringify({ updatedUserID }); }, + updateInfoFromRawInfo(info: UserRawUpdateInfo) { + return { + type: updateTypes.UPDATE_USER, + id: info.id, + time: info.time, + updatedUserID: info.updatedUserID, + }; + }, });