stream-chat 9.50.3 → 10.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.browser.js +19798 -14472
- package/dist/cjs/index.browser.js.map +4 -4
- package/dist/cjs/index.node.js +19817 -14482
- package/dist/cjs/index.node.js.map +4 -4
- package/dist/esm/index.mjs +19795 -14469
- package/dist/esm/index.mjs.map +4 -4
- package/dist/types/ChannelManager.d.ts +221 -0
- package/dist/types/EventHandlerPipeline.d.ts +104 -0
- package/dist/types/api-client.d.ts +26 -0
- package/dist/types/campaign.d.ts +0 -44
- package/dist/types/channel.d.ts +454 -479
- package/dist/types/channel_batch_updater.d.ts +0 -93
- package/dist/types/channel_state.d.ts +53 -201
- package/dist/types/client.d.ts +451 -1920
- package/dist/types/client_state.d.ts +4 -4
- package/dist/types/configuration/InstanceConfigurationService.d.ts +26 -0
- package/dist/types/configuration/index.d.ts +1 -0
- package/dist/types/configuration/types.d.ts +53 -0
- package/dist/types/connection.d.ts +49 -41
- package/dist/types/connection_fallback.d.ts +6 -4
- package/dist/types/constants.d.ts +0 -4
- package/dist/types/custom_types.d.ts +2 -0
- package/dist/types/entityStore/EntityStore.d.ts +111 -0
- package/dist/types/entityStore/StoreBackedItemIndex.d.ts +60 -0
- package/dist/types/entityStore/applyReactionLocally.d.ts +26 -0
- package/dist/types/entityStore/index.d.ts +2 -0
- package/dist/types/errors.d.ts +10 -2
- package/dist/types/gen/chat/ChannelApi.d.ts +45 -0
- package/dist/types/gen/chat/ChatApi.d.ts +334 -0
- package/dist/types/gen/model-decoders/decoders.d.ts +3 -0
- package/dist/types/gen/model-decoders/event-decoder-mapping.d.ts +6 -0
- package/dist/types/gen/models/index.d.ts +8836 -0
- package/dist/types/gen/moderation/ModerationApi.d.ts +50 -0
- package/dist/types/gen-imports.d.ts +3 -0
- package/dist/types/index.d.ts +8 -7
- package/dist/types/insights.d.ts +9 -8
- package/dist/types/logger.d.ts +9 -0
- package/dist/types/messageComposer/LocationComposer.d.ts +7 -4
- package/dist/types/messageComposer/attachmentIdentity.d.ts +2 -2
- package/dist/types/messageComposer/attachmentManager.d.ts +8 -4
- package/dist/types/messageComposer/configuration/types.d.ts +11 -11
- package/dist/types/messageComposer/linkPreviewsManager.d.ts +25 -13
- package/dist/types/messageComposer/messageComposer.d.ts +10 -10
- package/dist/types/messageComposer/middleware/messageComposer/types.d.ts +3 -3
- package/dist/types/messageComposer/middleware/pollComposer/types.d.ts +4 -7
- package/dist/types/messageComposer/middleware/textComposer/commandUtils.d.ts +3 -3
- package/dist/types/messageComposer/middleware/textComposer/commands.d.ts +7 -7
- package/dist/types/messageComposer/middleware/textComposer/mentions.d.ts +218 -4
- package/dist/types/messageComposer/middleware/textComposer/types.d.ts +9 -4
- package/dist/types/messageComposer/pollComposer.d.ts +5 -4
- package/dist/types/messageComposer/textComposer.d.ts +8 -3
- package/dist/types/messageComposer/types.d.ts +6 -28
- package/dist/types/messageDelivery/MessageDeliveryReporter.d.ts +40 -25
- package/dist/types/messageDelivery/MessageReceiptsTracker.d.ts +53 -12
- package/dist/types/messageOperations/MessageOperationStatePolicy.d.ts +19 -0
- package/dist/types/messageOperations/MessageOperations.d.ts +17 -0
- package/dist/types/messageOperations/index.d.ts +3 -0
- package/dist/types/messageOperations/types.d.ts +49 -0
- package/dist/types/moderation.d.ts +21 -203
- package/dist/types/notifications/types.d.ts +8 -7
- package/dist/types/offline-support/offline_support_api.d.ts +111 -87
- package/dist/types/offline-support/offline_sync_manager.d.ts +0 -7
- package/dist/types/offline-support/types.d.ts +19 -23
- package/dist/types/offline-support/util.d.ts +4 -2
- package/dist/types/pagination/FilterBuilder.d.ts +1 -1
- package/dist/types/pagination/ItemIndex.d.ts +25 -0
- package/dist/types/pagination/cursorDerivation/createdAtAroundPaginationFlags.d.ts +9 -0
- package/dist/types/pagination/cursorDerivation/idAroundPaginationFlags.d.ts +6 -0
- package/dist/types/pagination/cursorDerivation/index.d.ts +1 -0
- package/dist/types/pagination/cursorDerivation/linearPaginationFlags.d.ts +6 -0
- package/dist/types/pagination/filterCompiler.d.ts +7 -0
- package/dist/types/pagination/index.d.ts +1 -3
- package/dist/types/pagination/paginators/BasePaginator.d.ts +848 -0
- package/dist/types/pagination/paginators/ChannelPaginator.d.ts +212 -0
- package/dist/types/pagination/paginators/MessageIntervalPaginator.d.ts +282 -0
- package/dist/types/pagination/paginators/MessagePaginator.d.ts +208 -0
- package/dist/types/pagination/paginators/PinnedMessagePaginator.d.ts +39 -0
- package/dist/types/pagination/paginators/ReminderPaginator.d.ts +19 -0
- package/dist/types/pagination/paginators/UserGroupPaginator.d.ts +24 -0
- package/dist/types/pagination/paginators/index.d.ts +7 -0
- package/dist/types/pagination/paginators/stateThrottling.d.ts +2 -0
- package/dist/types/pagination/sortCompiler.d.ts +49 -0
- package/dist/types/pagination/types.normalization.d.ts +11 -0
- package/dist/types/pagination/utility.normalization.d.ts +18 -0
- package/dist/types/pagination/utility.queryChannel.d.ts +26 -0
- package/dist/types/pagination/utility.search.d.ts +13 -0
- package/dist/types/permissions.d.ts +1 -1
- package/dist/types/poll.d.ts +29 -32
- package/dist/types/poll_manager.d.ts +2 -2
- package/dist/types/reminders/Reminder.d.ts +2 -5
- package/dist/types/reminders/ReminderManager.d.ts +2 -9
- package/dist/types/search/MessageSearchSource.d.ts +4 -4
- package/dist/types/search/UserSearchSource.d.ts +1 -1
- package/dist/types/search/types.d.ts +3 -3
- package/dist/types/segment.d.ts +0 -34
- package/dist/types/signing.d.ts +105 -65
- package/dist/types/store.d.ts +1 -0
- package/dist/types/thread.d.ts +70 -34
- package/dist/types/thread_manager.d.ts +3 -3
- package/dist/types/token_manager.d.ts +15 -10
- package/dist/types/types.d.ts +197 -3404
- package/dist/types/utils/FixedSizeQueueCache.d.ts +12 -6
- package/dist/types/utils/WithSubscriptions.d.ts +2 -1
- package/dist/types/utils/concurrency.d.ts +4 -4
- package/dist/types/utils/mergeWith/mergeWith.d.ts +3 -3
- package/dist/types/utils/mergeWith/mergeWithCore.d.ts +8 -3
- package/dist/types/utils/retryable.d.ts +34 -0
- package/dist/types/utils/throttling/throttle.d.ts +36 -0
- package/dist/types/utils.d.ts +100 -194
- package/package.json +7 -3
- package/src/ChannelManager.ts +724 -0
- package/src/CooldownTimer.ts +2 -2
- package/src/EventHandlerPipeline.ts +228 -0
- package/src/LiveLocationManager.ts +12 -11
- package/src/api-client.ts +275 -0
- package/src/campaign.ts +1 -77
- package/src/channel.ts +1344 -1282
- package/src/channel_batch_updater.ts +1 -211
- package/src/channel_state.ts +144 -1013
- package/src/client.ts +936 -3995
- package/src/client_state.ts +4 -4
- package/src/configuration/InstanceConfigurationService.ts +73 -0
- package/src/configuration/index.ts +1 -0
- package/src/configuration/types.ts +81 -0
- package/src/connection.ts +145 -94
- package/src/connection_fallback.ts +29 -27
- package/src/constants.ts +1 -5
- package/src/custom_types.ts +4 -1
- package/src/entityStore/EntityStore.ts +208 -0
- package/src/entityStore/StoreBackedItemIndex.ts +115 -0
- package/src/entityStore/applyReactionLocally.ts +113 -0
- package/src/entityStore/index.ts +2 -0
- package/src/errors.ts +14 -2
- package/src/gen/chat/ChannelApi.ts +275 -0
- package/src/gen/chat/ChatApi.ts +2554 -0
- package/src/gen/model-decoders/decoders.ts +2680 -0
- package/src/gen/model-decoders/event-decoder-mapping.ts +198 -0
- package/src/gen/models/index.ts +12673 -0
- package/src/gen/moderation/ModerationApi.ts +607 -0
- package/src/gen-imports.ts +3 -0
- package/src/index.ts +11 -12
- package/src/insights.ts +6 -5
- package/src/logger.ts +28 -0
- package/src/messageComposer/LocationComposer.ts +9 -5
- package/src/messageComposer/MessageComposerEffectHandlers.ts +1 -0
- package/src/messageComposer/attachmentIdentity.ts +16 -9
- package/src/messageComposer/attachmentManager.ts +13 -8
- package/src/messageComposer/configuration/types.ts +11 -11
- package/src/messageComposer/linkPreviewsManager.ts +9 -10
- package/src/messageComposer/messageComposer.ts +57 -53
- package/src/messageComposer/middleware/messageComposer/attachments.ts +1 -2
- package/src/messageComposer/middleware/messageComposer/cleanData.ts +1 -1
- package/src/messageComposer/middleware/messageComposer/compositionValidation.ts +2 -2
- package/src/messageComposer/middleware/messageComposer/messageComposerState.ts +2 -2
- package/src/messageComposer/middleware/messageComposer/sharedLocation.ts +4 -3
- package/src/messageComposer/middleware/messageComposer/textComposer.ts +2 -2
- package/src/messageComposer/middleware/messageComposer/types.ts +3 -4
- package/src/messageComposer/middleware/messageComposer/userDataInjection.ts +9 -5
- package/src/messageComposer/middleware/pollComposer/state.ts +0 -2
- package/src/messageComposer/middleware/pollComposer/types.ts +4 -7
- package/src/messageComposer/middleware/textComposer/TextComposerMiddlewareExecutor.ts +10 -1
- package/src/messageComposer/middleware/textComposer/commandEffects.ts +4 -4
- package/src/messageComposer/middleware/textComposer/commandUtils.ts +3 -6
- package/src/messageComposer/middleware/textComposer/commands.ts +3 -3
- package/src/messageComposer/middleware/textComposer/mentionUtils.ts +1 -1
- package/src/messageComposer/middleware/textComposer/mentions.ts +31 -15
- package/src/messageComposer/middleware/textComposer/types.ts +9 -4
- package/src/messageComposer/pollComposer.ts +6 -8
- package/src/messageComposer/textComposer.ts +27 -2
- package/src/messageComposer/types.ts +6 -28
- package/src/messageDelivery/MessageDeliveryReporter.ts +101 -45
- package/src/messageDelivery/MessageReceiptsTracker.ts +294 -21
- package/src/messageOperations/MessageOperationStatePolicy.ts +77 -0
- package/src/messageOperations/MessageOperations.ts +212 -0
- package/src/messageOperations/index.ts +10 -0
- package/src/messageOperations/types.ts +64 -0
- package/src/moderation.ts +38 -431
- package/src/notifications/types.ts +8 -7
- package/src/offline-support/offline_support_api.ts +200 -133
- package/src/offline-support/offline_sync_manager.ts +23 -44
- package/src/offline-support/types.ts +23 -26
- package/src/offline-support/util.ts +5 -4
- package/src/pagination/FilterBuilder.ts +4 -1
- package/src/pagination/ItemIndex.ts +25 -0
- package/src/pagination/cursorDerivation/createdAtAroundPaginationFlags.ts +73 -0
- package/src/pagination/cursorDerivation/idAroundPaginationFlags.ts +53 -0
- package/src/pagination/cursorDerivation/index.ts +1 -0
- package/src/pagination/cursorDerivation/linearPaginationFlags.ts +86 -0
- package/src/pagination/filterCompiler.ts +196 -0
- package/src/pagination/index.ts +1 -3
- package/src/pagination/paginators/BasePaginator.ts +2859 -0
- package/src/pagination/paginators/ChannelPaginator.ts +729 -0
- package/src/pagination/paginators/MessageIntervalPaginator.ts +1116 -0
- package/src/pagination/paginators/MessagePaginator.ts +508 -0
- package/src/pagination/paginators/PinnedMessagePaginator.ts +108 -0
- package/src/pagination/paginators/ReminderPaginator.ts +107 -0
- package/src/pagination/paginators/UserGroupPaginator.ts +127 -0
- package/src/pagination/paginators/index.ts +7 -0
- package/src/pagination/paginators/stateThrottling.ts +31 -0
- package/src/pagination/sortCompiler.ts +193 -0
- package/src/pagination/types.normalization.ts +14 -0
- package/src/pagination/utility.normalization.ts +106 -0
- package/src/pagination/utility.queryChannel.ts +84 -0
- package/src/pagination/utility.search.ts +80 -0
- package/src/permissions.ts +7 -8
- package/src/poll.ts +101 -110
- package/src/poll_manager.ts +14 -8
- package/src/reminders/Reminder.ts +2 -5
- package/src/reminders/ReminderManager.ts +19 -21
- package/src/search/BaseSearchSource.ts +0 -3
- package/src/search/ChannelMemberSearchSource.ts +7 -1
- package/src/search/ChannelSearchSource.ts +10 -3
- package/src/search/MessageSearchSource.ts +29 -30
- package/src/search/UserSearchSource.ts +12 -8
- package/src/search/types.ts +3 -4
- package/src/segment.ts +1 -95
- package/src/signing.ts +107 -67
- package/src/store.ts +2 -1
- package/src/thread.ts +562 -238
- package/src/thread_manager.ts +37 -16
- package/src/token_manager.ts +21 -10
- package/src/types.ts +364 -4533
- package/src/uploadManager.ts +8 -0
- package/src/utils/FixedSizeQueueCache.ts +12 -6
- package/src/utils/WithSubscriptions.ts +2 -1
- package/src/utils/concurrency.ts +4 -4
- package/src/utils/mergeWith/mergeWith.ts +3 -3
- package/src/utils/mergeWith/mergeWithCore.ts +140 -164
- package/src/utils/mergeWith/mergeWithDiff.ts +3 -3
- package/src/utils/retryable.ts +117 -0
- package/src/utils/throttling/throttle.ts +130 -0
- package/src/utils.ts +208 -754
- package/dist/types/channel_manager.d.ts +0 -122
- package/dist/types/events.d.ts +0 -72
- package/dist/types/pagination/BasePaginator.d.ts +0 -69
- package/dist/types/pagination/ReminderPaginator.d.ts +0 -16
- package/dist/types/pagination/UserGroupPaginator.d.ts +0 -21
- package/src/channel_manager.ts +0 -830
- package/src/events.ts +0 -75
- package/src/pagination/BasePaginator.ts +0 -184
- package/src/pagination/ReminderPaginator.ts +0 -56
- package/src/pagination/UserGroupPaginator.ts +0 -93
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
2
|
+
APIError,
|
|
3
3
|
ChannelResponse,
|
|
4
4
|
Event,
|
|
5
|
+
EventPayload,
|
|
6
|
+
EventType,
|
|
5
7
|
LocalMessage,
|
|
6
|
-
|
|
8
|
+
MessageRequest,
|
|
7
9
|
MessageResponse,
|
|
10
|
+
OwnUserResponse,
|
|
11
|
+
RequireLiteral,
|
|
8
12
|
} from '../types';
|
|
9
13
|
|
|
10
14
|
import type {
|
|
@@ -14,18 +18,24 @@ import type {
|
|
|
14
18
|
PrepareBatchDBQueries,
|
|
15
19
|
} from './types';
|
|
16
20
|
import { OfflineError } from './types';
|
|
21
|
+
import { isEphemeral } from '../errors';
|
|
17
22
|
import type { StreamChat } from '../client';
|
|
18
23
|
import type { AxiosError } from 'axios';
|
|
19
24
|
import { OfflineDBSyncManager } from './offline_sync_manager';
|
|
25
|
+
import { chatLoggerSystem } from '../logger';
|
|
20
26
|
import { StateStore } from '../store';
|
|
21
27
|
import {
|
|
22
28
|
channelHasReadEvents,
|
|
23
29
|
channelTracksReadLocally,
|
|
30
|
+
formatMessage,
|
|
24
31
|
localMessageToNewMessagePayload,
|
|
25
32
|
runDetached,
|
|
26
33
|
} from '../utils';
|
|
27
34
|
import { isMessageUpdateReplayable } from './util';
|
|
28
35
|
|
|
36
|
+
const logger = chatLoggerSystem.getLogger('offline-db');
|
|
37
|
+
import type { WSEvent } from '../gen/models';
|
|
38
|
+
|
|
29
39
|
/**
|
|
30
40
|
* Abstract base class for an offline database implementation used with StreamChat.
|
|
31
41
|
*
|
|
@@ -45,12 +55,11 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
45
55
|
this.syncManager = new OfflineDBSyncManager({ client, offlineDb: this });
|
|
46
56
|
this.state = new StateStore<OfflineDBState>({
|
|
47
57
|
initialized: false,
|
|
48
|
-
userId: this.client.
|
|
58
|
+
userId: this.client.userId,
|
|
49
59
|
});
|
|
50
60
|
}
|
|
51
61
|
|
|
52
62
|
/**
|
|
53
|
-
* @abstract
|
|
54
63
|
* Inserts a reaction into the DB.
|
|
55
64
|
* Will write to:
|
|
56
65
|
* - The reactions table with the new reaction
|
|
@@ -58,24 +67,24 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
58
67
|
* - The users table with any users associated
|
|
59
68
|
* Will return the prepared queries for delayed execution (even if they are
|
|
60
69
|
* already executed).
|
|
70
|
+
*
|
|
61
71
|
* @param {DBInsertReactionType} options
|
|
62
72
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
63
73
|
*/
|
|
64
74
|
abstract insertReaction: OfflineDBApi['insertReaction'];
|
|
65
75
|
|
|
66
76
|
/**
|
|
67
|
-
* @abstract
|
|
68
77
|
* Upserts the list of CIDs for a filter + sort query hash.
|
|
69
78
|
* Will write to only the table containing the cids.
|
|
70
79
|
* Will return the prepared queries for delayed execution (even if they are
|
|
71
80
|
* already executed).
|
|
81
|
+
*
|
|
72
82
|
* @param {DBUpsertCidsForQueryType} options
|
|
73
83
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
74
84
|
*/
|
|
75
85
|
abstract upsertCidsForQuery: OfflineDBApi['upsertCidsForQuery'];
|
|
76
86
|
|
|
77
87
|
/**
|
|
78
|
-
* @abstract
|
|
79
88
|
* Upserts the channels passed as an argument within the DB. Relies on
|
|
80
89
|
* writing the properties we need from a ChannelResponse into the adequate
|
|
81
90
|
* tables.
|
|
@@ -89,72 +98,72 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
89
98
|
* - The reads table for each user
|
|
90
99
|
* Will return the prepared queries for delayed execution (even if they are
|
|
91
100
|
* already executed).
|
|
101
|
+
*
|
|
92
102
|
* @param {DBUpsertChannelsType} options
|
|
93
103
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
94
104
|
*/
|
|
95
105
|
abstract upsertChannels: OfflineDBApi['upsertChannels'];
|
|
96
106
|
|
|
97
107
|
/**
|
|
98
|
-
* @abstract
|
|
99
108
|
* Upserts the current active user's sync status.
|
|
100
109
|
* Will only write to the sync status table.
|
|
101
110
|
* Will return the prepared queries for delayed execution (even if they are
|
|
102
111
|
* already executed).
|
|
112
|
+
*
|
|
103
113
|
* @param {DBUpsertUserSyncStatusType} options
|
|
104
114
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
105
115
|
*/
|
|
106
116
|
abstract upsertUserSyncStatus: OfflineDBApi['upsertUserSyncStatus'];
|
|
107
117
|
|
|
108
118
|
/**
|
|
109
|
-
* @abstract
|
|
110
119
|
* Upserts the app settings for the current Stream App into the DB. It
|
|
111
120
|
* is only intended to be run once per lifecycle of the app.
|
|
112
121
|
* Will only write to the respective app settings table.
|
|
113
122
|
* Will return the prepared queries for delayed execution (even if they are
|
|
114
123
|
* already executed).
|
|
124
|
+
*
|
|
115
125
|
* @param {DBUpsertAppSettingsType} options
|
|
116
126
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
117
127
|
*/
|
|
118
128
|
abstract upsertAppSettings: OfflineDBApi['upsertAppSettings'];
|
|
119
129
|
|
|
120
130
|
/**
|
|
121
|
-
* @abstract
|
|
122
131
|
* Upserts a poll fully in the DB.
|
|
123
132
|
* Will write to the polls table. It should not update the message
|
|
124
133
|
* associated due to how the poll state works.
|
|
125
134
|
* Will return the prepared queries for delayed execution (even if they are
|
|
126
135
|
* already executed).
|
|
136
|
+
*
|
|
127
137
|
* @param {DBUpsertPollType} options
|
|
128
138
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
129
139
|
*/
|
|
130
140
|
abstract upsertPoll: OfflineDBApi['upsertPoll'];
|
|
131
141
|
|
|
132
142
|
/**
|
|
133
|
-
* @abstract
|
|
134
143
|
* Upserts only the channel.data for the provided channels in the DB.
|
|
135
144
|
* Will only write to the channels table.
|
|
136
145
|
* Will return the prepared queries for delayed execution (even if they are
|
|
137
146
|
* already executed).
|
|
147
|
+
*
|
|
138
148
|
* @param {DBUpsertChannelDataType} options
|
|
139
149
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
140
150
|
*/
|
|
141
151
|
abstract upsertChannelData: OfflineDBApi['upsertChannelData'];
|
|
142
152
|
|
|
143
153
|
/**
|
|
144
|
-
* @abstract
|
|
145
154
|
* Upserts the provided reads in the DB.
|
|
146
155
|
* Will write to:
|
|
147
156
|
* - The reads table
|
|
148
157
|
* - The users table for each user associated with a read
|
|
149
158
|
* Will return the prepared queries for delayed execution (even if they are
|
|
150
159
|
* already executed).
|
|
160
|
+
*
|
|
151
161
|
* @param {DBUpsertReadsType} options
|
|
152
162
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
153
163
|
*/
|
|
154
164
|
abstract upsertReads: OfflineDBApi['upsertReads'];
|
|
155
165
|
|
|
156
166
|
/**
|
|
157
|
-
* @abstract
|
|
158
167
|
* Upserts the messages in the DB.
|
|
159
168
|
* Will write to:
|
|
160
169
|
* - The messages table
|
|
@@ -164,287 +173,288 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
164
173
|
* - The users table
|
|
165
174
|
* Will return the prepared queries for delayed execution (even if they are
|
|
166
175
|
* already executed).
|
|
176
|
+
*
|
|
167
177
|
* @param {DBUpsertMessagesType} options
|
|
168
178
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
169
179
|
*/
|
|
170
180
|
abstract upsertMessages: OfflineDBApi['upsertMessages'];
|
|
171
181
|
|
|
172
182
|
/**
|
|
173
|
-
* @abstract
|
|
174
183
|
* Upserts the members in the DB.
|
|
175
184
|
* Will write to:
|
|
176
185
|
* - The users table (for each user associated with a member)
|
|
177
186
|
* - The members table
|
|
178
187
|
* Will return the prepared queries for delayed execution (even if they are
|
|
179
188
|
* already executed).
|
|
189
|
+
*
|
|
180
190
|
* @param {DBUpsertMembersType} options
|
|
181
191
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
182
192
|
*/
|
|
183
193
|
abstract upsertMembers: OfflineDBApi['upsertMembers'];
|
|
184
194
|
|
|
185
195
|
/**
|
|
186
|
-
* @abstract
|
|
187
196
|
* Updates a reaction in the DB. Will update the DB the same way
|
|
188
197
|
* a reaction.updated event would (it assumes enforce_unique is true
|
|
189
198
|
* and removes all other reactions associated with the user.
|
|
190
199
|
* Will write to the reactions table.
|
|
191
200
|
* Will return the prepared queries for delayed execution (even if they are
|
|
192
201
|
* already executed).
|
|
202
|
+
*
|
|
193
203
|
* @param {DBUpdateReactionType} options
|
|
194
204
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
195
205
|
*/
|
|
196
206
|
abstract updateReaction: OfflineDBApi['updateReaction'];
|
|
197
207
|
|
|
198
208
|
/**
|
|
199
|
-
* @abstract
|
|
200
209
|
* Updates a single message in the DB. This is used as a faster
|
|
201
210
|
* alternative to upsertMessages with more optimized queries.
|
|
202
211
|
* Will write to the messages table.
|
|
203
212
|
* Will return the prepared queries for delayed execution (even if they are
|
|
204
213
|
* already executed).
|
|
214
|
+
*
|
|
205
215
|
* @param {DBUpdateMessageType} options
|
|
206
216
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
207
217
|
*/
|
|
208
218
|
abstract updateMessage: OfflineDBApi['updateMessage'];
|
|
209
219
|
|
|
210
220
|
/**
|
|
211
|
-
* @abstract
|
|
212
221
|
* Fetches the provided draft from the DB. Should return as close to
|
|
213
222
|
* the server side DraftResponse as possible.
|
|
223
|
+
*
|
|
214
224
|
* @param {DBGetDraftType} options
|
|
215
225
|
* @returns {Promise<DraftResponse | null>}
|
|
216
226
|
*/
|
|
217
227
|
abstract getDraft: OfflineDBApi['getDraft'];
|
|
218
228
|
/**
|
|
219
|
-
* @abstract
|
|
220
229
|
* Upserts a draft in the DB.
|
|
221
230
|
* Will write to the draft table upserting the draft.
|
|
222
231
|
* Will return the prepared queries for delayed execution (even if they are
|
|
223
232
|
* already executed).
|
|
233
|
+
*
|
|
224
234
|
* @param {DBUpsertDraftType} options
|
|
225
235
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
226
236
|
*/
|
|
227
237
|
abstract upsertDraft: OfflineDBApi['upsertDraft'];
|
|
228
238
|
/**
|
|
229
|
-
* @abstract
|
|
230
239
|
* Deletes a draft from the DB.
|
|
231
240
|
* Will write to the draft table removing the draft.
|
|
232
241
|
* Will return the prepared queries for delayed execution (even if they are
|
|
233
242
|
* already executed).
|
|
243
|
+
*
|
|
234
244
|
* @param {DBDeleteDraftType} options
|
|
235
245
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
236
246
|
*/
|
|
237
247
|
abstract deleteDraft: OfflineDBApi['deleteDraft'];
|
|
238
248
|
|
|
239
249
|
/**
|
|
240
|
-
* @abstract
|
|
241
250
|
* Fetches the provided channels from the DB and aggregates all data associated
|
|
242
|
-
* with them in a single
|
|
251
|
+
* with them in a single ChannelStateResponseFields. The implementation itself is responsible
|
|
243
252
|
* for aggregating and serialization of all of the data. Should return as close to
|
|
244
|
-
* the server side
|
|
253
|
+
* the server side ChannelStateResponseFields as possible.
|
|
254
|
+
*
|
|
245
255
|
* @param {DBGetChannelsType} options
|
|
246
|
-
* @returns {Promise<Omit<
|
|
256
|
+
* @returns {Promise<Omit<ChannelStateResponseFields, 'duration'>[] | null>}
|
|
247
257
|
*/
|
|
248
258
|
abstract getChannels: OfflineDBApi['getChannels'];
|
|
249
259
|
|
|
250
260
|
/**
|
|
251
|
-
* @abstract
|
|
252
261
|
* Fetches the channels from the DB that were the last known response to a filters & sort
|
|
253
|
-
* hash as a query and aggregates all data associated with them in a single
|
|
262
|
+
* hash as a query and aggregates all data associated with them in a single ChannelStateResponseFields.
|
|
254
263
|
* The implementation itself is responsible for aggregating and serialization of all of the data.
|
|
255
|
-
* Should return as close to the server side
|
|
264
|
+
* Should return as close to the server side ChannelStateResponseFields as possible.
|
|
265
|
+
*
|
|
256
266
|
* @param {DBGetChannelsForQueryType} options
|
|
257
|
-
* @returns {Promise<Omit<
|
|
267
|
+
* @returns {Promise<Omit<ChannelStateResponseFields, 'duration'>[] | null>}
|
|
258
268
|
*/
|
|
259
269
|
abstract getChannelsForQuery: OfflineDBApi['getChannelsForQuery'];
|
|
260
270
|
|
|
261
271
|
/**
|
|
262
|
-
* @abstract
|
|
263
272
|
* Will return a list of all available CIDs in the DB. The same can be achieved
|
|
264
273
|
* by fetching all channels, however this is meant to be much faster as a query.
|
|
274
|
+
*
|
|
265
275
|
* @returns {Promise<string[]>}
|
|
266
276
|
*/
|
|
267
277
|
abstract getAllChannelCids: OfflineDBApi['getAllChannelCids'];
|
|
268
278
|
|
|
269
279
|
/**
|
|
270
|
-
* @abstract
|
|
271
280
|
* Fetches the timestamp of the last sync of the DB.
|
|
281
|
+
*
|
|
272
282
|
* @param {DBGetLastSyncedAtType} options
|
|
273
283
|
* @returns {Promise<string | undefined>}
|
|
274
284
|
*/
|
|
275
285
|
abstract getLastSyncedAt: OfflineDBApi['getLastSyncedAt'];
|
|
276
286
|
|
|
277
287
|
/**
|
|
278
|
-
* @abstract
|
|
279
288
|
* Fetches all pending tasks from the DB. It will return them in an
|
|
280
289
|
* ordered fashion by the time they were created.
|
|
290
|
+
*
|
|
281
291
|
* @param {DBGetPendingTasksType} [conditions]
|
|
282
292
|
* @returns {Promise<PendingTask[]>}
|
|
283
293
|
*/
|
|
284
294
|
abstract getPendingTasks: OfflineDBApi['getPendingTasks'];
|
|
285
295
|
|
|
286
296
|
/**
|
|
287
|
-
* @abstract
|
|
288
297
|
* Fetches the app settings stored in the DB. Is mainly meant to be used
|
|
289
298
|
* only while offline and opening the application, as we only update the
|
|
290
299
|
* app settings whenever they are fetched again so it has the potential to
|
|
291
300
|
* be stale.
|
|
301
|
+
*
|
|
292
302
|
* @param {DBGetAppSettingsType} options
|
|
293
|
-
* @returns {Promise<
|
|
303
|
+
* @returns {Promise<GetApplicationResponse | null>}
|
|
294
304
|
*/
|
|
295
305
|
abstract getAppSettings: OfflineDBApi['getAppSettings'];
|
|
296
306
|
|
|
297
307
|
/**
|
|
298
|
-
* @abstract
|
|
299
308
|
* Fetches reactions from the DB for a given filter & sort hash and
|
|
300
309
|
* for a given message ID.
|
|
310
|
+
*
|
|
301
311
|
* @param {DBGetReactionsType} options
|
|
302
312
|
* @returns {Promise<ReactionResponse[] | null>}
|
|
303
313
|
*/
|
|
304
314
|
abstract getReactions: OfflineDBApi['getReactions'];
|
|
305
315
|
|
|
306
316
|
/**
|
|
307
|
-
* @abstract
|
|
308
317
|
* Executes multiple queries in a batched fashion. It will also be done
|
|
309
318
|
* within a transaction.
|
|
319
|
+
*
|
|
310
320
|
* @param {ExecuteBatchDBQueriesType} queries
|
|
311
321
|
* @returns {Promise<unknown>}
|
|
312
322
|
*/
|
|
313
323
|
abstract executeSqlBatch: OfflineDBApi['executeSqlBatch'];
|
|
314
324
|
|
|
315
325
|
/**
|
|
316
|
-
* @abstract
|
|
317
326
|
* Adds a pending task to the pending tasks table. Can only be one of the
|
|
318
327
|
* supported types of pending tasks, otherwise its execution will throw.
|
|
319
328
|
* Will return the prepared queries for delayed execution (even if they are
|
|
320
329
|
* already executed).
|
|
330
|
+
*
|
|
321
331
|
* @param {PendingTask} task
|
|
322
332
|
* @returns {Promise<() => Promise<void>>}
|
|
323
333
|
*/
|
|
324
334
|
abstract addPendingTask: OfflineDBApi['addPendingTask'];
|
|
325
335
|
|
|
326
336
|
/**
|
|
327
|
-
* @abstract
|
|
328
337
|
* Updates a pending task in the DB, given its ID.
|
|
329
338
|
* Will return the prepared queries for delayed execution (even if they are
|
|
330
339
|
* already executed).
|
|
340
|
+
*
|
|
331
341
|
* @param {DBUpdatePendingTaskType} options
|
|
332
342
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
333
343
|
*/
|
|
334
344
|
abstract updatePendingTask: OfflineDBApi['updatePendingTask'];
|
|
335
345
|
|
|
336
346
|
/**
|
|
337
|
-
* @abstract
|
|
338
347
|
* Deletes a pending task from the DB, given its ID.
|
|
339
348
|
* Will return the prepared queries for delayed execution (even if they are
|
|
340
349
|
* already executed).
|
|
350
|
+
*
|
|
341
351
|
* @param {DBDeletePendingTaskType} options
|
|
342
352
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
343
353
|
*/
|
|
344
354
|
abstract deletePendingTask: OfflineDBApi['deletePendingTask'];
|
|
345
355
|
|
|
346
356
|
/**
|
|
347
|
-
* @abstract
|
|
348
357
|
* Deletes a reaction from the DB.
|
|
349
358
|
* Will write to the reactions table removing the reaction.
|
|
350
359
|
* Will return the prepared queries for delayed execution (even if they are
|
|
351
360
|
* already executed).
|
|
361
|
+
*
|
|
352
362
|
* @param {DBDeleteReactionType} options
|
|
353
363
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
354
364
|
*/
|
|
355
365
|
abstract deleteReaction: OfflineDBApi['deleteReaction'];
|
|
356
366
|
|
|
357
367
|
/**
|
|
358
|
-
* @abstract
|
|
359
368
|
* Deletes a member from the DB.
|
|
360
369
|
* Will only write to the members table.
|
|
361
370
|
* Will return the prepared queries for delayed execution (even if they are
|
|
362
371
|
* already executed).
|
|
372
|
+
*
|
|
363
373
|
* @param {DBDeleteMemberType} options
|
|
364
374
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
365
375
|
*/
|
|
366
376
|
abstract deleteMember: OfflineDBApi['deleteMember'];
|
|
367
377
|
|
|
368
378
|
/**
|
|
369
|
-
* @abstract
|
|
370
379
|
* Deletes a channel from the DB.
|
|
371
380
|
* It will also delete all other entities associated with the channel in
|
|
372
381
|
* a cascading fashion (messages, reactions, members etc.).
|
|
373
382
|
* Will return the prepared queries for delayed execution (even if they are
|
|
374
383
|
* already executed).
|
|
384
|
+
*
|
|
375
385
|
* @param {DBDeleteChannelType} options
|
|
376
386
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
377
387
|
*/
|
|
378
388
|
abstract deleteChannel: OfflineDBApi['deleteChannel'];
|
|
379
389
|
|
|
380
390
|
/**
|
|
381
|
-
* @abstract
|
|
382
391
|
* Deletes multiple messages for a given channel. Works as `channel.truncated` would.
|
|
383
392
|
* Should remove entities primarily from the messages table and then from all associated
|
|
384
393
|
* tables in a cascading fashion (reactions, polls etc.).
|
|
385
394
|
* Will return the prepared queries for delayed execution (even if they are
|
|
386
395
|
* already executed).
|
|
396
|
+
*
|
|
387
397
|
* @param {DBDeleteMessagesForChannelType} options
|
|
388
398
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
389
399
|
*/
|
|
390
400
|
abstract deleteMessagesForChannel: OfflineDBApi['deleteMessagesForChannel'];
|
|
391
401
|
|
|
392
402
|
/**
|
|
393
|
-
* @abstract
|
|
394
403
|
* Deletes all pending tasks from the DB.
|
|
395
404
|
* Will only update the pending tasks table.
|
|
396
405
|
* Will return the prepared queries for delayed execution (even if they are
|
|
397
406
|
* already executed).
|
|
407
|
+
*
|
|
398
408
|
* @param {DBDropPendingTasksType} options
|
|
399
409
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
400
410
|
*/
|
|
401
411
|
abstract dropPendingTasks: OfflineDBApi['dropPendingTasks'];
|
|
402
412
|
|
|
403
413
|
/**
|
|
404
|
-
* @abstract
|
|
405
414
|
* Deletes a message from the DB.
|
|
406
415
|
* All other entities associated with the message will also be deleted
|
|
407
416
|
* in a cascading fashion (reactions, polls etc.).
|
|
408
417
|
* Will return the prepared queries for delayed execution (even if they are
|
|
409
418
|
* already executed).
|
|
419
|
+
*
|
|
410
420
|
* @param {DBDeleteMessageType} options
|
|
411
421
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
412
422
|
*/
|
|
413
423
|
abstract hardDeleteMessage: OfflineDBApi['hardDeleteMessage'];
|
|
414
424
|
|
|
415
425
|
/**
|
|
416
|
-
* @abstract
|
|
417
426
|
* Updates a message with a deleted_at value in the DB.
|
|
418
427
|
* Will only update the messages table, as the message is simply marked
|
|
419
428
|
* as deleted and not removed from the DB.
|
|
420
429
|
* Will return the prepared queries for delayed execution (even if they are
|
|
421
430
|
* already executed).
|
|
431
|
+
*
|
|
422
432
|
* @param {DBDeleteMessageType} options
|
|
423
433
|
* @returns {Promise<ExecuteBatchDBQueriesType>}
|
|
424
434
|
*/
|
|
425
435
|
abstract softDeleteMessage: OfflineDBApi['softDeleteMessage'];
|
|
426
436
|
|
|
427
437
|
/**
|
|
428
|
-
* @abstract
|
|
429
438
|
* Drops all tables and reinitializes the connection to the DB.
|
|
439
|
+
*
|
|
430
440
|
* @returns {Promise<unknown>}
|
|
431
441
|
*/
|
|
432
442
|
abstract resetDB: OfflineDBApi['resetDB'];
|
|
433
443
|
|
|
434
444
|
/**
|
|
435
|
-
* @abstract
|
|
436
445
|
* A utility query that checks whether a specific channel exists in the DB.
|
|
437
446
|
* Technically the same as actually fetching that channel through other queries,
|
|
438
447
|
* but much faster.
|
|
448
|
+
*
|
|
439
449
|
* @param {DBChannelExistsType} options
|
|
440
450
|
* @returns {Promise<boolean>}
|
|
441
451
|
*/
|
|
442
452
|
abstract channelExists: OfflineDBApi['channelExists'];
|
|
443
453
|
|
|
444
454
|
/**
|
|
445
|
-
* @abstract
|
|
446
455
|
* Initializes the DB (typically creating a simple file handle as a connection pointer for
|
|
447
456
|
* SQLite and likely similar for other DBs).
|
|
457
|
+
*
|
|
448
458
|
* @returns {Promise<boolean>}
|
|
449
459
|
*/
|
|
450
460
|
abstract initializeDB: OfflineDBApi['initializeDB'];
|
|
@@ -452,6 +462,7 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
452
462
|
/**
|
|
453
463
|
* Initializes the DB as well as its syncManager for a given userId.
|
|
454
464
|
* It will update the DBs reactive state with initialization values.
|
|
465
|
+
*
|
|
455
466
|
* @param userId - the user ID for which we want to initialize
|
|
456
467
|
*/
|
|
457
468
|
public init = async (userId: string) => {
|
|
@@ -469,13 +480,16 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
469
480
|
}
|
|
470
481
|
} catch (error) {
|
|
471
482
|
this.state.partialNext({ initialized: false, userId: undefined });
|
|
472
|
-
|
|
483
|
+
logger
|
|
484
|
+
.withExtraTags('init')
|
|
485
|
+
.error('Failed to initialize the offline database.', { error });
|
|
473
486
|
}
|
|
474
487
|
};
|
|
475
488
|
|
|
476
489
|
/**
|
|
477
490
|
* Checks whether the DB should be initialized or if it has been initialized already.
|
|
478
|
-
*
|
|
491
|
+
*
|
|
492
|
+
* @param userId - the user ID for which we want to check initialization
|
|
479
493
|
*/
|
|
480
494
|
public shouldInitialize(userId: string): boolean {
|
|
481
495
|
const { userId: userIdFromState, initialized } = this.state.getLatestValue();
|
|
@@ -487,6 +501,7 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
487
501
|
* passed uses a reference to the DB itself and will handle errors gracefully
|
|
488
502
|
* and silently. Only really meant to be used for write queries that need to
|
|
489
503
|
* be run in synchronous functions.
|
|
504
|
+
*
|
|
490
505
|
* @param queryCallback - a callback wrapping all query logic that is to be executed
|
|
491
506
|
* @param method - a utility parameter used for proper logging (will make sure the method
|
|
492
507
|
* is logged on failure)
|
|
@@ -515,21 +530,29 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
515
530
|
* If both fail, it will not execute the query as it would result in a foreign key constraint
|
|
516
531
|
* error.
|
|
517
532
|
*
|
|
518
|
-
* @param event -
|
|
519
|
-
* @param execute -
|
|
520
|
-
* @param forceUpdate -
|
|
521
|
-
* @param createQueries -
|
|
533
|
+
* @param event - The WS event we are trying to process.
|
|
534
|
+
* @param event.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
535
|
+
* @param event.forceUpdate - Whether to upsert the channel data anyway (optional, defaults to `false`).
|
|
536
|
+
* @param createQueries - A callback that creates the queries to execute.
|
|
537
|
+
* @returns The list of prepared queries (executed when `execute` is `true`).
|
|
522
538
|
*/
|
|
523
539
|
public queriesWithChannelGuard = async (
|
|
524
540
|
{
|
|
525
541
|
event,
|
|
526
542
|
execute = true,
|
|
527
543
|
forceUpdate = false,
|
|
528
|
-
}: {
|
|
544
|
+
}: {
|
|
545
|
+
event: Extract<
|
|
546
|
+
Event,
|
|
547
|
+
{ channel?: any; cid?: any; channel_type?: any; channel_id?: any }
|
|
548
|
+
>;
|
|
549
|
+
execute?: boolean;
|
|
550
|
+
forceUpdate?: boolean;
|
|
551
|
+
},
|
|
529
552
|
createQueries: (executeOverride?: boolean) => Promise<PrepareBatchDBQueries[]>,
|
|
530
553
|
) => {
|
|
531
|
-
const channelFromEvent = event.channel;
|
|
532
|
-
const cid = event.cid || channelFromEvent?.cid;
|
|
554
|
+
const channelFromEvent = (event as Extract<WSEvent, { channel?: any }>).channel;
|
|
555
|
+
const cid = (event as Extract<WSEvent, { cid?: any }>).cid || channelFromEvent?.cid;
|
|
533
556
|
const type = event.type;
|
|
534
557
|
|
|
535
558
|
if (!cid) {
|
|
@@ -542,11 +565,13 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
542
565
|
// This can happen for example when a message.new event is received for a channel that is not in the db due to a channel being hidden.
|
|
543
566
|
const shouldUpsertChannelData = forceUpdate || !(await this.channelExists({ cid }));
|
|
544
567
|
if (shouldUpsertChannelData) {
|
|
568
|
+
const event_ = event as Extract<WSEvent, { channel_type?: any }>;
|
|
569
|
+
|
|
545
570
|
let channelData = channelFromEvent;
|
|
546
|
-
if (!channelData &&
|
|
571
|
+
if (!channelData && event_.channel_type && event_.channel_id) {
|
|
547
572
|
const channelFromState = this.client.channel(
|
|
548
|
-
|
|
549
|
-
|
|
573
|
+
event_.channel_type,
|
|
574
|
+
event_.channel_id,
|
|
550
575
|
);
|
|
551
576
|
if (channelFromState.initialized && !channelFromState.disconnected) {
|
|
552
577
|
channelData = channelFromState.data as unknown as ChannelResponse;
|
|
@@ -565,17 +590,21 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
565
590
|
}
|
|
566
591
|
return newQueries;
|
|
567
592
|
} else {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
593
|
+
logger
|
|
594
|
+
.withExtraTags('queriesWithChannelGuard')
|
|
595
|
+
.warn(
|
|
596
|
+
`Could not create channel queries on a "${type}" event for an initialized channel that is not in the database. Skipping the event.`,
|
|
597
|
+
{ event },
|
|
598
|
+
);
|
|
572
599
|
return [];
|
|
573
600
|
}
|
|
574
601
|
} else {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
602
|
+
logger
|
|
603
|
+
.withExtraTags('queriesWithChannelGuard')
|
|
604
|
+
.warn(
|
|
605
|
+
`Received a "${type}" event for a non-initialized channel that is not in the database. Skipping the event.`,
|
|
606
|
+
{ event },
|
|
607
|
+
);
|
|
579
608
|
return [];
|
|
580
609
|
}
|
|
581
610
|
}
|
|
@@ -587,14 +616,15 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
587
616
|
* and it is going to make sure that both messages and reads are upserted. It will not
|
|
588
617
|
* try to fetch the reads from the DB first and it will rely on channel.state to handle
|
|
589
618
|
* the number of unreads.
|
|
590
|
-
*
|
|
591
|
-
* @param
|
|
619
|
+
*
|
|
620
|
+
* @param payload.event - the WS event we are trying to process
|
|
621
|
+
* @param payload.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
592
622
|
*/
|
|
593
623
|
public handleNewMessage = async ({
|
|
594
624
|
event,
|
|
595
625
|
execute = true,
|
|
596
626
|
}: {
|
|
597
|
-
event:
|
|
627
|
+
event: EventPayload<'message.new'>;
|
|
598
628
|
execute?: boolean;
|
|
599
629
|
}) => {
|
|
600
630
|
const client = this.client;
|
|
@@ -628,10 +658,13 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
628
658
|
execute: false,
|
|
629
659
|
reads: [
|
|
630
660
|
{
|
|
631
|
-
last_read:
|
|
661
|
+
last_read: ownReads?.last_read ?? new Date(0),
|
|
632
662
|
last_read_message_id: ownReads?.last_read_message_id,
|
|
633
663
|
unread_messages: unreadCount,
|
|
634
|
-
user: client.user
|
|
664
|
+
user: client.user as RequireLiteral<
|
|
665
|
+
OwnUserResponse,
|
|
666
|
+
'blocked_user_ids'
|
|
667
|
+
>, // TODO: drop RequireLiteral once the oapi spec is adjusted
|
|
635
668
|
},
|
|
636
669
|
],
|
|
637
670
|
});
|
|
@@ -652,14 +685,15 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
652
685
|
/**
|
|
653
686
|
* A handler for message deletion. It provides a channel guard and determines whether
|
|
654
687
|
* it should hard delete or soft delete the message.
|
|
655
|
-
*
|
|
656
|
-
* @param
|
|
688
|
+
*
|
|
689
|
+
* @param payload.event - the WS event we are trying to process
|
|
690
|
+
* @param payload.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
657
691
|
*/
|
|
658
692
|
public handleDeleteMessage = async ({
|
|
659
693
|
event,
|
|
660
694
|
execute = true,
|
|
661
695
|
}: {
|
|
662
|
-
event:
|
|
696
|
+
event: EventPayload<'message.deleted'>;
|
|
663
697
|
execute?: boolean;
|
|
664
698
|
}) => {
|
|
665
699
|
const { message, deleted_for_me, hard_delete = false } = event;
|
|
@@ -684,8 +718,9 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
684
718
|
* A utility method used for removing a message that has already failed from the
|
|
685
719
|
* state as well as the DB. We want to drop all pending tasks and finally hard
|
|
686
720
|
* delete the message from the DB.
|
|
687
|
-
*
|
|
688
|
-
* @param
|
|
721
|
+
*
|
|
722
|
+
* @param payload.messageId - The ID of the message we want to remove.
|
|
723
|
+
* @param payload.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
689
724
|
*/
|
|
690
725
|
public handleRemoveMessage = async ({
|
|
691
726
|
messageId,
|
|
@@ -717,22 +752,29 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
717
752
|
* The unreadMessages argument is useful for cases where we know the exact number of unreads
|
|
718
753
|
* (for example reading an entire channel), but `unread_messages` might not necessarily exist
|
|
719
754
|
* in the event (or it exists with a stale value if we know what we want to ultimately update to).
|
|
720
|
-
*
|
|
721
|
-
* @param
|
|
722
|
-
* @param
|
|
755
|
+
*
|
|
756
|
+
* @param payload.event - The WS event we are trying to process.
|
|
757
|
+
* @param payload.unreadMessages - An override of `unread_messages` that will be preferred when upserting reads.
|
|
758
|
+
* @param payload.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
723
759
|
*/
|
|
724
760
|
public handleRead = async ({
|
|
725
761
|
event,
|
|
726
762
|
unreadMessages,
|
|
727
763
|
execute = true,
|
|
728
764
|
}: {
|
|
729
|
-
event:
|
|
765
|
+
event: EventPayload<
|
|
766
|
+
| 'message.read'
|
|
767
|
+
| 'message.read_locally'
|
|
768
|
+
| 'notification.mark_read'
|
|
769
|
+
| 'notification.mark_unread'
|
|
770
|
+
>;
|
|
730
771
|
unreadMessages?: number;
|
|
731
772
|
execute?: boolean;
|
|
732
773
|
}) => {
|
|
733
774
|
const {
|
|
734
|
-
received_at: last_read,
|
|
775
|
+
received_at: last_read = new Date(),
|
|
735
776
|
last_read_message_id,
|
|
777
|
+
// @ts-expect-error property missing
|
|
736
778
|
unread_messages = 0,
|
|
737
779
|
user,
|
|
738
780
|
cid,
|
|
@@ -747,7 +789,7 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
747
789
|
execute: executeOverride,
|
|
748
790
|
reads: [
|
|
749
791
|
{
|
|
750
|
-
last_read
|
|
792
|
+
last_read,
|
|
751
793
|
last_read_message_id,
|
|
752
794
|
unread_messages: overriddenUnreadMessages,
|
|
753
795
|
user,
|
|
@@ -764,14 +806,15 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
764
806
|
* A utility method used to handle member events. It guards the processing
|
|
765
807
|
* of each event with a channel guard and also forces an update of member_count
|
|
766
808
|
* for the respective channel if applicable.
|
|
767
|
-
*
|
|
768
|
-
* @param
|
|
809
|
+
*
|
|
810
|
+
* @param payload.event - the WS event we are trying to process
|
|
811
|
+
* @param payload.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
769
812
|
*/
|
|
770
813
|
public handleMemberEvent = async ({
|
|
771
814
|
event,
|
|
772
815
|
execute = true,
|
|
773
816
|
}: {
|
|
774
|
-
event:
|
|
817
|
+
event: EventPayload<`member.${string}`>;
|
|
775
818
|
execute?: boolean;
|
|
776
819
|
}) => {
|
|
777
820
|
const { member, cid, type } = event;
|
|
@@ -802,14 +845,15 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
802
845
|
/**
|
|
803
846
|
* A utility method used to handle message.updated events. It guards each
|
|
804
847
|
* event handler within a channel guard.
|
|
805
|
-
*
|
|
806
|
-
* @param
|
|
848
|
+
*
|
|
849
|
+
* @param payload.event - the WS event we are trying to process
|
|
850
|
+
* @param payload.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
807
851
|
*/
|
|
808
852
|
public handleMessageUpdatedEvent = async ({
|
|
809
853
|
event,
|
|
810
854
|
execute = true,
|
|
811
855
|
}: {
|
|
812
|
-
event:
|
|
856
|
+
event: EventPayload<'message.updated' | 'message.undeleted'>;
|
|
813
857
|
execute?: boolean;
|
|
814
858
|
}) => {
|
|
815
859
|
const { message } = event;
|
|
@@ -831,14 +875,15 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
831
875
|
* simple upsertion is not enough.
|
|
832
876
|
* It will update the hidden property of a channel to true if handling the `channel.hidden`
|
|
833
877
|
* event and to false if handling `channel.visible`.
|
|
834
|
-
*
|
|
835
|
-
* @param
|
|
878
|
+
*
|
|
879
|
+
* @param payload. - the WS event we are trying to process
|
|
880
|
+
* @param payload.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
836
881
|
*/
|
|
837
882
|
public handleChannelVisibilityEvent = async ({
|
|
838
883
|
event,
|
|
839
884
|
execute = true,
|
|
840
885
|
}: {
|
|
841
|
-
event:
|
|
886
|
+
event: EventPayload<'channel.visible' | 'channel.hidden'>;
|
|
842
887
|
execute?: boolean;
|
|
843
888
|
}) => {
|
|
844
889
|
const { type, channel } = event;
|
|
@@ -858,14 +903,15 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
858
903
|
* A utility handler used to handle channel.truncated events. It handles both
|
|
859
904
|
* removing all messages and relying on truncated_at as well. It will also upsert
|
|
860
905
|
* reads adequately (and calculate the correct unread messages when truncating).
|
|
861
|
-
*
|
|
862
|
-
* @param
|
|
906
|
+
*
|
|
907
|
+
* @param payload.event - the WS event we are trying to process
|
|
908
|
+
* @param payload.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
863
909
|
*/
|
|
864
910
|
public handleChannelTruncatedEvent = async ({
|
|
865
911
|
event,
|
|
866
912
|
execute = true,
|
|
867
913
|
}: {
|
|
868
|
-
event:
|
|
914
|
+
event: EventPayload<'channel.truncated'>;
|
|
869
915
|
execute?: boolean;
|
|
870
916
|
}) => {
|
|
871
917
|
const { channel } = event;
|
|
@@ -900,10 +946,10 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
900
946
|
execute: false,
|
|
901
947
|
reads: [
|
|
902
948
|
{
|
|
903
|
-
last_read:
|
|
949
|
+
last_read: ownReads?.last_read ?? new Date(0),
|
|
904
950
|
last_read_message_id: ownReads?.last_read_message_id,
|
|
905
951
|
unread_messages: unreadCount,
|
|
906
|
-
user: ownUser,
|
|
952
|
+
user: ownUser as RequireLiteral<OwnUserResponse, 'blocked_user_ids'>, // TODO: drop RequireLiteral once the oapi spec is adjusted
|
|
907
953
|
},
|
|
908
954
|
],
|
|
909
955
|
});
|
|
@@ -926,14 +972,15 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
926
972
|
* - reaction.new -> insertReaction
|
|
927
973
|
* - reaction.updated -> updateReaction
|
|
928
974
|
* - reaction.deleted -> deleteReaction
|
|
929
|
-
*
|
|
930
|
-
* @param
|
|
975
|
+
*
|
|
976
|
+
* @param payload.event - the WS event we are trying to process
|
|
977
|
+
* @param payload.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
931
978
|
*/
|
|
932
979
|
public handleReactionEvent = async ({
|
|
933
980
|
event,
|
|
934
981
|
execute = true,
|
|
935
982
|
}: {
|
|
936
|
-
event:
|
|
983
|
+
event: EventPayload<`reaction.${string}`>;
|
|
937
984
|
execute?: boolean;
|
|
938
985
|
}) => {
|
|
939
986
|
const { type, message, reaction } = event;
|
|
@@ -942,7 +989,7 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
942
989
|
return [];
|
|
943
990
|
}
|
|
944
991
|
|
|
945
|
-
const getReactionMethod = (type:
|
|
992
|
+
const getReactionMethod = (type: EventType) => {
|
|
946
993
|
switch (type) {
|
|
947
994
|
case 'reaction.new':
|
|
948
995
|
return this.insertReaction;
|
|
@@ -968,14 +1015,15 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
968
1015
|
* A utility handler for all draft events:
|
|
969
1016
|
* - draft.updated -> updateDraft
|
|
970
1017
|
* - draft.deleted -> deleteDraft
|
|
971
|
-
*
|
|
972
|
-
* @param
|
|
1018
|
+
*
|
|
1019
|
+
* @param payload.event - the WS event we are trying to process
|
|
1020
|
+
* @param payload.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
973
1021
|
*/
|
|
974
1022
|
handleDraftEvent = async ({
|
|
975
1023
|
event,
|
|
976
1024
|
execute = true,
|
|
977
1025
|
}: {
|
|
978
|
-
event:
|
|
1026
|
+
event: EventPayload<`draft.${string}`>;
|
|
979
1027
|
execute?: boolean;
|
|
980
1028
|
}) => {
|
|
981
1029
|
const { cid, draft, type } = event;
|
|
@@ -1006,8 +1054,9 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1006
1054
|
* A generic event handler that decides which DB API to invoke based on
|
|
1007
1055
|
* event.type for all events we are currently handling. It is used to both
|
|
1008
1056
|
* react on WS events as well as process the sync API events.
|
|
1009
|
-
*
|
|
1010
|
-
* @param
|
|
1057
|
+
*
|
|
1058
|
+
* @param payload.event - the WS event we are trying to process
|
|
1059
|
+
* @param payload.execute - Whether to immediately execute the operation (optional, defaults to `true`).
|
|
1011
1060
|
*/
|
|
1012
1061
|
public handleEvent = async ({
|
|
1013
1062
|
event,
|
|
@@ -1016,10 +1065,13 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1016
1065
|
event: Event;
|
|
1017
1066
|
execute?: boolean;
|
|
1018
1067
|
}) => {
|
|
1019
|
-
const { type
|
|
1068
|
+
const { type } = event;
|
|
1020
1069
|
|
|
1021
1070
|
if (type.startsWith('reaction')) {
|
|
1022
|
-
return await this.handleReactionEvent({
|
|
1071
|
+
return await this.handleReactionEvent({
|
|
1072
|
+
event: event as EventPayload<`reaction.${string}`>,
|
|
1073
|
+
execute,
|
|
1074
|
+
});
|
|
1023
1075
|
}
|
|
1024
1076
|
|
|
1025
1077
|
if (type === 'message.new') {
|
|
@@ -1055,7 +1107,10 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1055
1107
|
}
|
|
1056
1108
|
|
|
1057
1109
|
if (type.startsWith('member.')) {
|
|
1058
|
-
return await this.handleMemberEvent({
|
|
1110
|
+
return await this.handleMemberEvent({
|
|
1111
|
+
event: event as EventPayload<`member.${string}`>,
|
|
1112
|
+
execute,
|
|
1113
|
+
});
|
|
1059
1114
|
}
|
|
1060
1115
|
|
|
1061
1116
|
if (type === 'channel.hidden' || type === 'channel.visible') {
|
|
@@ -1077,18 +1132,18 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1077
1132
|
(type === 'channel.updated' ||
|
|
1078
1133
|
type === 'notification.message_new' ||
|
|
1079
1134
|
type === 'notification.added_to_channel') &&
|
|
1080
|
-
channel
|
|
1135
|
+
event.channel
|
|
1081
1136
|
) {
|
|
1082
|
-
return await this.upsertChannelData({ channel, execute });
|
|
1137
|
+
return await this.upsertChannelData({ channel: event.channel, execute });
|
|
1083
1138
|
}
|
|
1084
1139
|
|
|
1085
1140
|
if (
|
|
1086
1141
|
(type === 'channel.deleted' ||
|
|
1087
1142
|
type === 'notification.channel_deleted' ||
|
|
1088
1143
|
type === 'notification.removed_from_channel') &&
|
|
1089
|
-
channel
|
|
1144
|
+
event.channel
|
|
1090
1145
|
) {
|
|
1091
|
-
return await this.deleteChannel({ cid: channel.cid, execute });
|
|
1146
|
+
return await this.deleteChannel({ cid: event.channel.cid, execute });
|
|
1092
1147
|
}
|
|
1093
1148
|
|
|
1094
1149
|
if (type === 'channel.truncated') {
|
|
@@ -1107,6 +1162,7 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1107
1162
|
* 3. If it is, it will insert the task in the pending tasks table
|
|
1108
1163
|
*
|
|
1109
1164
|
* It will return the response from the execution if it succeeded.
|
|
1165
|
+
*
|
|
1110
1166
|
* @param task - the pending task we want to execute
|
|
1111
1167
|
*/
|
|
1112
1168
|
public queueTask = async <T>({ task }: { task: PendingTask }): Promise<T> => {
|
|
@@ -1122,7 +1178,7 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1122
1178
|
try {
|
|
1123
1179
|
return await attemptTaskExecution();
|
|
1124
1180
|
} catch (e) {
|
|
1125
|
-
if (!this.shouldSkipQueueingTask(e as AxiosError<
|
|
1181
|
+
if (!this.shouldSkipQueueingTask(e as AxiosError<APIError>)) {
|
|
1126
1182
|
await this.handleAddPendingTask({ task });
|
|
1127
1183
|
}
|
|
1128
1184
|
throw e;
|
|
@@ -1130,27 +1186,28 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1130
1186
|
};
|
|
1131
1187
|
|
|
1132
1188
|
/**
|
|
1133
|
-
* A utility method that determines if a failed task should be added to the
|
|
1134
|
-
*
|
|
1135
|
-
*
|
|
1136
|
-
*
|
|
1137
|
-
*
|
|
1189
|
+
* A utility method that determines if a failed task should be skipped (NOT added to the queue) -
|
|
1190
|
+
* i.e. the failure is a definitive rejection rather than an ephemeral/retryable one. A task is
|
|
1191
|
+
* kept in the queue only when its error is {@link isEphemeral} (connection/network error or a
|
|
1192
|
+
* retryable server code). A non retryable server response (i.e bad request, not allowed etc) is
|
|
1193
|
+
* skipped since retrying it would never succeed.
|
|
1194
|
+
*
|
|
1195
|
+
* @param error - The error thrown while executing the failed task.
|
|
1138
1196
|
*/
|
|
1139
|
-
private shouldSkipQueueingTask = (error: AxiosError<
|
|
1140
|
-
error?.response?.data?.code === 4 || error?.response?.data?.code === 17;
|
|
1197
|
+
private shouldSkipQueueingTask = (error: AxiosError<APIError>) => !isEphemeral(error);
|
|
1141
1198
|
|
|
1142
1199
|
private mergeFailedMessageUpdateIntoPendingSendMessage = ({
|
|
1143
1200
|
editedMessage,
|
|
1144
1201
|
pendingMessage,
|
|
1145
1202
|
}: {
|
|
1146
1203
|
editedMessage: LocalMessage | Partial<MessageResponse>;
|
|
1147
|
-
pendingMessage:
|
|
1204
|
+
pendingMessage: MessageRequest;
|
|
1148
1205
|
}) => {
|
|
1149
1206
|
const normalizedEditedMessageSource = {
|
|
1150
1207
|
...editedMessage,
|
|
1151
1208
|
} as LocalMessage & { message_text_updated_at?: string };
|
|
1152
1209
|
|
|
1153
|
-
if (editedMessage.status === 'failed') {
|
|
1210
|
+
if ((editedMessage as LocalMessage).status === 'failed') {
|
|
1154
1211
|
delete normalizedEditedMessageSource.message_text_updated_at;
|
|
1155
1212
|
}
|
|
1156
1213
|
|
|
@@ -1165,7 +1222,7 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1165
1222
|
...(typeof pendingMessageStatus !== 'undefined'
|
|
1166
1223
|
? { status: pendingMessageStatus }
|
|
1167
1224
|
: {}),
|
|
1168
|
-
} as
|
|
1225
|
+
} as MessageRequest;
|
|
1169
1226
|
};
|
|
1170
1227
|
|
|
1171
1228
|
private isPendingSendMessageTask = (
|
|
@@ -1176,12 +1233,12 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1176
1233
|
private handleOfflineFailedUpdateMessagePendingTask = async (
|
|
1177
1234
|
task: Extract<PendingTask, { type: 'update-message' }>,
|
|
1178
1235
|
) => {
|
|
1179
|
-
const [message] = task.payload;
|
|
1180
|
-
if (!
|
|
1236
|
+
const [{ id, message }] = task.payload;
|
|
1237
|
+
if (!id) {
|
|
1181
1238
|
return;
|
|
1182
1239
|
}
|
|
1183
1240
|
|
|
1184
|
-
const pendingTasks = await this.getPendingTasks({ messageId:
|
|
1241
|
+
const pendingTasks = await this.getPendingTasks({ messageId: id });
|
|
1185
1242
|
const pendingSendMessageTask = pendingTasks.find(this.isPendingSendMessageTask);
|
|
1186
1243
|
|
|
1187
1244
|
if (!pendingSendMessageTask) {
|
|
@@ -1190,14 +1247,20 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1190
1247
|
|
|
1191
1248
|
const updatedPendingSendMessage = this.mergeFailedMessageUpdateIntoPendingSendMessage(
|
|
1192
1249
|
{
|
|
1193
|
-
|
|
1194
|
-
|
|
1250
|
+
// TODO: this is not good, we have too many message types, should probably only have two (request, response)
|
|
1251
|
+
editedMessage: message as unknown as LocalMessage,
|
|
1252
|
+
pendingMessage: pendingSendMessageTask.payload[0].message as MessageRequest,
|
|
1195
1253
|
},
|
|
1196
1254
|
);
|
|
1197
1255
|
|
|
1198
1256
|
const updatedPendingTask: Extract<PendingTask, { type: 'send-message' }> = {
|
|
1199
1257
|
...pendingSendMessageTask,
|
|
1200
|
-
payload: [
|
|
1258
|
+
payload: [
|
|
1259
|
+
{
|
|
1260
|
+
...pendingSendMessageTask.payload[0],
|
|
1261
|
+
message: updatedPendingSendMessage,
|
|
1262
|
+
},
|
|
1263
|
+
],
|
|
1201
1264
|
};
|
|
1202
1265
|
|
|
1203
1266
|
if (pendingSendMessageTask.id) {
|
|
@@ -1219,14 +1282,17 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1219
1282
|
* or rewrites an existing pending `send-message` task for offline edits of failed messages.
|
|
1220
1283
|
*/
|
|
1221
1284
|
public handleAddPendingTask = async ({ task }: { task: PendingTask }) => {
|
|
1222
|
-
if (
|
|
1285
|
+
if (
|
|
1286
|
+
task.type === 'update-message' &&
|
|
1287
|
+
!isMessageUpdateReplayable(task.payload[0].message ?? {})
|
|
1288
|
+
) {
|
|
1223
1289
|
return;
|
|
1224
1290
|
}
|
|
1225
1291
|
|
|
1226
1292
|
if (
|
|
1227
1293
|
task.type === 'update-message' &&
|
|
1228
1294
|
!this.client.wsConnection?.isHealthy &&
|
|
1229
|
-
task.payload[0].status === 'failed'
|
|
1295
|
+
(task.payload[0].message as { status?: string } | undefined)?.status === 'failed'
|
|
1230
1296
|
) {
|
|
1231
1297
|
await this.handleOfflineFailedUpdateMessagePendingTask(task);
|
|
1232
1298
|
return;
|
|
@@ -1246,6 +1312,7 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1246
1312
|
* - Creating a draft
|
|
1247
1313
|
* - Deleting a draft
|
|
1248
1314
|
* It will throw if we try to execute a pending task that is not supported.
|
|
1315
|
+
*
|
|
1249
1316
|
* @param task - The task we want to execute
|
|
1250
1317
|
* @param isPendingTask - a control value telling us if it's an actual pending task being executed
|
|
1251
1318
|
* or delayed execution
|
|
@@ -1293,7 +1360,7 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1293
1360
|
timestampChanged: true,
|
|
1294
1361
|
});
|
|
1295
1362
|
}
|
|
1296
|
-
channel.
|
|
1363
|
+
channel.messagePaginator.trackLastMessage(formatMessage(newMessage));
|
|
1297
1364
|
}
|
|
1298
1365
|
return newMessageResponse;
|
|
1299
1366
|
}
|
|
@@ -1325,7 +1392,7 @@ export abstract class AbstractOfflineDB implements OfflineDBApi {
|
|
|
1325
1392
|
true,
|
|
1326
1393
|
);
|
|
1327
1394
|
} catch (e) {
|
|
1328
|
-
const error = e as AxiosError<
|
|
1395
|
+
const error = e as AxiosError<APIError>;
|
|
1329
1396
|
if (!this.shouldSkipQueueingTask(error)) {
|
|
1330
1397
|
// executing the pending task has failed, so keep it in the queue
|
|
1331
1398
|
continue;
|