diff --git a/lib/actions/activity-actions.js b/lib/actions/activity-actions.js --- a/lib/actions/activity-actions.js +++ b/lib/actions/activity-actions.js @@ -25,7 +25,7 @@ ): ((input: UpdateActivityInput) => Promise) => async input => { const { activityUpdates } = input; - const requests = {}; + const requests: { [string]: { +updates: ActivityUpdate[] } } = {}; for (const update of activityUpdates) { const keyserverID = extractKeyserverIDFromID(update.threadID); if (!requests[keyserverID]) { @@ -36,7 +36,7 @@ const responses = await callKeyserverEndpoint('update_activity', requests); - let unfocusedToUnread = []; + let unfocusedToUnread: $ReadOnlyArray = []; for (const keyserverID in responses) { unfocusedToUnread = unfocusedToUnread.concat( responses[keyserverID].unfocusedToUnread, diff --git a/lib/actions/entry-actions.js b/lib/actions/entry-actions.js --- a/lib/actions/entry-actions.js +++ b/lib/actions/entry-actions.js @@ -39,13 +39,13 @@ calendarQuery, allKeyserverIDs, ); - const requests = {}; + const requests: { [string]: CalendarQuery } = {}; for (const keyserverID of allKeyserverIDs) { requests[keyserverID] = calendarQueries[keyserverID]; } const responses = await callKeyserverEndpoint('fetch_entries', requests); - let rawEntryInfos = []; + let rawEntryInfos: $ReadOnlyArray = []; for (const keyserverID in responses) { rawEntryInfos = rawEntryInfos.concat( responses[keyserverID].rawEntryInfos, @@ -87,7 +87,7 @@ allKeyserverIDs, ); - const requests = {}; + const requests: { [string]: CalendarQuery } = {}; for (const keyserverID of allKeyserverIDs) { requests[keyserverID] = calendarQueries[keyserverID]; } @@ -96,8 +96,8 @@ 'update_calendar_query', requests, ); - let rawEntryInfos = []; - let deletedEntryIDs = []; + let rawEntryInfos: $ReadOnlyArray = []; + let deletedEntryIDs: $ReadOnlyArray = []; for (const keyserverID in responses) { rawEntryInfos = rawEntryInfos.concat( responses[keyserverID].rawEntryInfos, diff --git a/lib/actions/link-actions.js b/lib/actions/link-actions.js --- a/lib/actions/link-actions.js +++ b/lib/actions/link-actions.js @@ -49,7 +49,7 @@ allKeyserverIDs: $ReadOnlyArray, ): (() => Promise) => async () => { - const requests = {}; + const requests: { [string]: void } = {}; for (const keyserverID of allKeyserverIDs) { requests[keyserverID] = undefined; } @@ -57,7 +57,7 @@ 'fetch_primary_invite_links', requests, ); - let links = []; + let links: $ReadOnlyArray = []; for (const keyserverID in responses) { links = links.concat(responses[keyserverID].links); } diff --git a/lib/actions/message-actions.js b/lib/actions/message-actions.js --- a/lib/actions/message-actions.js +++ b/lib/actions/message-actions.js @@ -13,6 +13,9 @@ FetchPinnedMessagesResult, SearchMessagesRequest, SearchMessagesResponse, + FetchMessageInfosRequest, + RawMessageInfo, + MessageTruncationStatuses, } from '../types/message-types.js'; import type { MediaMessageServerDBContent } from '../types/messages/media.js'; import type { @@ -121,7 +124,7 @@ async threadIDs => { const sortedThreadIDs = sortThreadIDsPerKeyserver(threadIDs); - const requests = {}; + const requests: { [string]: FetchMessageInfosRequest } = {}; for (const keyserverID in sortedThreadIDs) { const cursors = Object.fromEntries( sortedThreadIDs[keyserverID].map(threadID => [threadID, null]), @@ -133,8 +136,8 @@ } const responses = await callKeyserverEndpoint('fetch_messages', requests); - let rawMessageInfos = []; - let truncationStatuses = {}; + let rawMessageInfos: $ReadOnlyArray = []; + let truncationStatuses: MessageTruncationStatuses = {}; for (const keyserverID in responses) { rawMessageInfos = rawMessageInfos.concat( responses[keyserverID].rawMessageInfos, diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js --- a/lib/actions/user-actions.js +++ b/lib/actions/user-actions.js @@ -296,7 +296,7 @@ allKeyserverIDs: $ReadOnlyArray, ): ((input: UpdateUserSettingsRequest) => Promise) => async input => { - const requests = {}; + const requests: { [string]: UpdateUserSettingsRequest } = {}; for (const keyserverID of allKeyserverIDs) { requests[keyserverID] = input; } diff --git a/lib/types/filter-types.js b/lib/types/filter-types.js --- a/lib/types/filter-types.js +++ b/lib/types/filter-types.js @@ -17,7 +17,7 @@ +type: 'threads', +threadIDs: $ReadOnlyArray, }; -type NotDeletedFilter = { +type: 'not_deleted' }; +export type NotDeletedFilter = { +type: 'not_deleted' }; export type CalendarFilter = NotDeletedFilter | CalendarThreadFilter; export const calendarFilterValidator: TUnion = t.union([ diff --git a/lib/utils/action-utils.js b/lib/utils/action-utils.js --- a/lib/utils/action-utils.js +++ b/lib/utils/action-utils.js @@ -22,6 +22,7 @@ import type { PlatformDetails } from '../types/device-types.js'; import type { Endpoint, SocketAPIHandler } from '../types/endpoints.js'; import type { CalendarQuery } from '../types/entry-types.js'; +import type { NotDeletedFilter } from '../types/filter-types.js'; import type { LoadingOptions, LoadingInfo } from '../types/loading-types.js'; import type { ActionPayload, @@ -466,7 +467,7 @@ function sortThreadIDsPerKeyserver(threadIDs: $ReadOnlyArray): { +[keyserverID: string]: $ReadOnlyArray, } { - const results = {}; + const results: { [string]: string[] } = {}; for (const threadID of threadIDs) { const keyserverID = extractKeyserverIDFromID(threadID); invariant(keyserverID, 'keyserver data missing from thread id'); @@ -478,6 +479,18 @@ return results; } +type CalendarThreadFilterWithWritableThreadIDs = { + +type: 'threads', + +threadIDs: string[], +}; +type CalendarFilterWithWritableThreadIDs = + | NotDeletedFilter + | CalendarThreadFilterWithWritableThreadIDs; +type CalendarQueryWithWritableFilters = { + +startDate: string, + +endDate: string, + +filters: CalendarFilterWithWritableThreadIDs[], +}; function sortCalendarQueryPerKeyserver( calendarQuery: CalendarQuery, keyserverIDs: $ReadOnlyArray, @@ -485,7 +498,7 @@ +[keyserverID: string]: CalendarQuery, } { const { startDate, endDate, filters } = calendarQuery; - const results = {}; + const results: { [string]: CalendarQueryWithWritableFilters } = {}; for (const keyserverID of keyserverIDs) { results[keyserverID] = { @@ -509,6 +522,10 @@ let threadFilter = results[keyserverID].filters.find( flt => flt.type === 'threads', ); + invariant( + !threadFilter || threadFilter.type === 'threads', + 'should only match CalendarThreadFilter', + ); if (!threadFilter) { threadFilter = { type: 'threads', threadIDs: [] }; results[keyserverID].filters.push(threadFilter); diff --git a/lib/utils/keyserver-call.js b/lib/utils/keyserver-call.js --- a/lib/utils/keyserver-call.js +++ b/lib/utils/keyserver-call.js @@ -2,7 +2,6 @@ import _memoize from 'lodash/memoize.js'; import * as React from 'react'; -import { useDispatch } from 'react-redux'; import { createSelector } from 'reselect'; import { bindCookieAndUtilsIntoCallServerEndpoint } from './action-utils.js'; @@ -12,7 +11,7 @@ CallServerEndpointOptions, } from './call-server-endpoint.js'; import { promiseAll } from './promises.js'; -import { useSelector } from './redux-utils.js'; +import { useSelector, useDispatch } from './redux-utils.js'; import type { PlatformDetails } from '../types/device-types.js'; import type { Endpoint } from '../types/endpoints.js'; import type { KeyserverInfo } from '../types/keyserver-types.js'; @@ -80,7 +79,12 @@ +keyserverInfos: { +[keyserverID: string]: KeyserverInfo }, }; -const bindCallKeyserverEndpointSelector = createSelector( +const bindCallKeyserverEndpointSelector: BindKeyserverCallParams => < + Args: mixed, + Return, +>( + keyserverCall: ActionFunc, +) => Args => Promise = createSelector( (state: BindKeyserverCallParams) => state.dispatch, (state: BindKeyserverCallParams) => state.currentUserInfo, (state: BindKeyserverCallParams) => state.keyserverInfos, @@ -126,7 +130,7 @@ ); }; - const promises = {}; + const promises: { [string]: Promise } = {}; for (const keyserverID in requests) { promises[keyserverID] = bindCallKeyserverEndpoint(keyserverID); }