stream-chat 9.3.0 → 9.5.0
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.cjs +843 -146
- package/dist/cjs/index.browser.cjs.map +4 -4
- package/dist/cjs/index.node.cjs +859 -152
- package/dist/cjs/index.node.cjs.map +4 -4
- package/dist/esm/index.js +846 -149
- package/dist/esm/index.js.map +4 -4
- package/dist/types/client.d.ts +52 -19
- package/dist/types/events.d.ts +4 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/messageComposer/middleware/textComposer/commands.d.ts +2 -2
- package/dist/types/messageComposer/middleware/textComposer/mentions.d.ts +2 -2
- package/dist/types/messageComposer/middleware/textComposer/types.d.ts +1 -1
- package/dist/types/pagination/BasePaginator.d.ts +69 -0
- package/dist/types/pagination/ReminderPaginator.d.ts +12 -0
- package/dist/types/pagination/index.d.ts +2 -0
- package/dist/types/reminders/Reminder.d.ts +37 -0
- package/dist/types/reminders/ReminderManager.d.ts +65 -0
- package/dist/types/reminders/ReminderTimer.d.ts +17 -0
- package/dist/types/reminders/index.d.ts +3 -0
- package/dist/types/search/BaseSearchSource.d.ts +87 -0
- package/dist/types/search/ChannelSearchSource.d.ts +17 -0
- package/dist/types/search/MessageSearchSource.d.ts +23 -0
- package/dist/types/search/SearchController.d.ts +44 -0
- package/dist/types/search/UserSearchSource.d.ts +16 -0
- package/dist/types/search/index.d.ts +5 -0
- package/dist/types/store.d.ts +114 -5
- package/dist/types/types.d.ts +48 -3
- package/package.json +4 -4
- package/src/channel.ts +2 -1
- package/src/client.ts +108 -39
- package/src/events.ts +6 -0
- package/src/index.ts +3 -1
- package/src/messageComposer/middleware/textComposer/commands.ts +2 -2
- package/src/messageComposer/middleware/textComposer/mentions.ts +2 -2
- package/src/messageComposer/middleware/textComposer/types.ts +1 -1
- package/src/pagination/BasePaginator.ts +184 -0
- package/src/pagination/ReminderPaginator.ts +38 -0
- package/src/pagination/index.ts +2 -0
- package/src/reminders/Reminder.ts +89 -0
- package/src/reminders/ReminderManager.ts +284 -0
- package/src/reminders/ReminderTimer.ts +86 -0
- package/src/reminders/index.ts +3 -0
- package/src/search/BaseSearchSource.ts +227 -0
- package/src/search/ChannelSearchSource.ts +34 -0
- package/src/search/MessageSearchSource.ts +88 -0
- package/src/search/SearchController.ts +154 -0
- package/src/search/UserSearchSource.ts +35 -0
- package/src/search/index.ts +5 -0
- package/src/store.ts +237 -11
- package/src/token_manager.ts +3 -1
- package/src/types.ts +91 -1
- package/dist/types/search_controller.d.ts +0 -174
- package/src/search_controller.ts +0 -523
|
@@ -159,6 +159,7 @@ __export(index_exports, {
|
|
|
159
159
|
AnyResource: () => AnyResource,
|
|
160
160
|
AnyRole: () => AnyRole,
|
|
161
161
|
AttachmentManager: () => AttachmentManager,
|
|
162
|
+
BasePaginator: () => BasePaginator,
|
|
162
163
|
BaseSearchSource: () => BaseSearchSource,
|
|
163
164
|
BuiltinPermissions: () => BuiltinPermissions,
|
|
164
165
|
BuiltinRoles: () => BuiltinRoles,
|
|
@@ -176,6 +177,9 @@ __export(index_exports, {
|
|
|
176
177
|
DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS: () => DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS,
|
|
177
178
|
DEFAULT_COMPOSER_CONFIG: () => DEFAULT_COMPOSER_CONFIG,
|
|
178
179
|
DEFAULT_LINK_PREVIEW_MANAGER_CONFIG: () => DEFAULT_LINK_PREVIEW_MANAGER_CONFIG,
|
|
180
|
+
DEFAULT_PAGINATION_OPTIONS: () => DEFAULT_PAGINATION_OPTIONS,
|
|
181
|
+
DEFAULT_REMINDER_MANAGER_CONFIG: () => DEFAULT_REMINDER_MANAGER_CONFIG,
|
|
182
|
+
DEFAULT_STOP_REFRESH_BOUNDARY_MS: () => DEFAULT_STOP_REFRESH_BOUNDARY_MS,
|
|
179
183
|
DEFAULT_TEXT_COMPOSER_CONFIG: () => DEFAULT_TEXT_COMPOSER_CONFIG,
|
|
180
184
|
Deny: () => Deny,
|
|
181
185
|
DenyAll: () => DenyAll,
|
|
@@ -192,6 +196,7 @@ __export(index_exports, {
|
|
|
192
196
|
MODERATION_ENTITY_TYPES: () => MODERATION_ENTITY_TYPES,
|
|
193
197
|
MaxPriority: () => MaxPriority,
|
|
194
198
|
MentionsSearchSource: () => MentionsSearchSource,
|
|
199
|
+
MergedStateStore: () => MergedStateStore,
|
|
195
200
|
MessageComposer: () => MessageComposer,
|
|
196
201
|
MessageComposerMiddlewareExecutor: () => MessageComposerMiddlewareExecutor,
|
|
197
202
|
MessageDraftComposerMiddlewareExecutor: () => MessageDraftComposerMiddlewareExecutor,
|
|
@@ -207,6 +212,10 @@ __export(index_exports, {
|
|
|
207
212
|
PollComposerCompositionMiddlewareExecutor: () => PollComposerCompositionMiddlewareExecutor,
|
|
208
213
|
PollComposerStateMiddlewareExecutor: () => PollComposerStateMiddlewareExecutor,
|
|
209
214
|
PollManager: () => PollManager,
|
|
215
|
+
Reminder: () => Reminder,
|
|
216
|
+
ReminderManager: () => ReminderManager,
|
|
217
|
+
ReminderPaginator: () => ReminderPaginator,
|
|
218
|
+
ReminderTimer: () => ReminderTimer,
|
|
210
219
|
SearchController: () => SearchController,
|
|
211
220
|
Segment: () => Segment,
|
|
212
221
|
StableWSConnection: () => StableWSConnection,
|
|
@@ -294,7 +303,8 @@ __export(index_exports, {
|
|
|
294
303
|
readFileAsArrayBuffer: () => readFileAsArrayBuffer,
|
|
295
304
|
removeDiacritics: () => removeDiacritics,
|
|
296
305
|
replaceWordWithEntity: () => replaceWordWithEntity,
|
|
297
|
-
textIsEmpty: () => textIsEmpty
|
|
306
|
+
textIsEmpty: () => textIsEmpty,
|
|
307
|
+
timeLeftMs: () => timeLeftMs
|
|
298
308
|
});
|
|
299
309
|
module.exports = __toCommonJS(index_exports);
|
|
300
310
|
|
|
@@ -4048,26 +4058,14 @@ var ensureIsLocalAttachment = (attachment) => {
|
|
|
4048
4058
|
|
|
4049
4059
|
// src/store.ts
|
|
4050
4060
|
var isPatch = (value) => typeof value === "function";
|
|
4061
|
+
var noop2 = () => {
|
|
4062
|
+
};
|
|
4051
4063
|
var StateStore = class {
|
|
4052
4064
|
constructor(value) {
|
|
4053
4065
|
this.value = value;
|
|
4054
|
-
this.
|
|
4055
|
-
this.
|
|
4056
|
-
const newValue = isPatch(newValueOrPatch) ? newValueOrPatch(this.value) : newValueOrPatch;
|
|
4057
|
-
if (newValue === this.value) return;
|
|
4058
|
-
const oldValue = this.value;
|
|
4059
|
-
this.value = newValue;
|
|
4060
|
-
this.handlerSet.forEach((handler) => handler(this.value, oldValue));
|
|
4061
|
-
};
|
|
4066
|
+
this.handlers = /* @__PURE__ */ new Set();
|
|
4067
|
+
this.preprocessors = /* @__PURE__ */ new Set();
|
|
4062
4068
|
this.partialNext = (partial) => this.next((current) => ({ ...current, ...partial }));
|
|
4063
|
-
this.getLatestValue = () => this.value;
|
|
4064
|
-
this.subscribe = (handler) => {
|
|
4065
|
-
handler(this.value, void 0);
|
|
4066
|
-
this.handlerSet.add(handler);
|
|
4067
|
-
return () => {
|
|
4068
|
-
this.handlerSet.delete(handler);
|
|
4069
|
-
};
|
|
4070
|
-
};
|
|
4071
4069
|
this.subscribeWithSelector = (selector, handler) => {
|
|
4072
4070
|
let previouslySelectedValues;
|
|
4073
4071
|
const wrappedHandler = (nextValue) => {
|
|
@@ -4086,6 +4084,183 @@ var StateStore = class {
|
|
|
4086
4084
|
return this.subscribe(wrappedHandler);
|
|
4087
4085
|
};
|
|
4088
4086
|
}
|
|
4087
|
+
/**
|
|
4088
|
+
* Allows merging two stores only if their keys differ otherwise there's no way to ensure the data type stability.
|
|
4089
|
+
* @experimental
|
|
4090
|
+
* This method is experimental and may change in future versions.
|
|
4091
|
+
*/
|
|
4092
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4093
|
+
merge(stateStore) {
|
|
4094
|
+
return new MergedStateStore({
|
|
4095
|
+
original: this,
|
|
4096
|
+
merged: stateStore
|
|
4097
|
+
});
|
|
4098
|
+
}
|
|
4099
|
+
next(newValueOrPatch) {
|
|
4100
|
+
const newValue = isPatch(newValueOrPatch) ? newValueOrPatch(this.value) : newValueOrPatch;
|
|
4101
|
+
if (newValue === this.value) return;
|
|
4102
|
+
this.preprocessors.forEach((preprocessor) => preprocessor(newValue, this.value));
|
|
4103
|
+
const oldValue = this.value;
|
|
4104
|
+
this.value = newValue;
|
|
4105
|
+
this.handlers.forEach((handler) => handler(this.value, oldValue));
|
|
4106
|
+
}
|
|
4107
|
+
getLatestValue() {
|
|
4108
|
+
return this.value;
|
|
4109
|
+
}
|
|
4110
|
+
subscribe(handler) {
|
|
4111
|
+
handler(this.value, void 0);
|
|
4112
|
+
this.handlers.add(handler);
|
|
4113
|
+
return () => {
|
|
4114
|
+
this.handlers.delete(handler);
|
|
4115
|
+
};
|
|
4116
|
+
}
|
|
4117
|
+
/**
|
|
4118
|
+
* Registers a preprocessor function that will be called before the state is updated.
|
|
4119
|
+
*
|
|
4120
|
+
* Preprocessors are invoked with the new and previous values whenever `next` or `partialNext` methods
|
|
4121
|
+
* are called, allowing you to mutate or react to the new value before it is set. Preprocessors run in the
|
|
4122
|
+
* order they were registered.
|
|
4123
|
+
*
|
|
4124
|
+
* @example
|
|
4125
|
+
* ```ts
|
|
4126
|
+
* const store = new StateStore<{ count: number; isMaxValue: bool; }>({ count: 0, isMaxValue: false });
|
|
4127
|
+
*
|
|
4128
|
+
* store.addPreprocessor((nextValue, prevValue) => {
|
|
4129
|
+
* if (nextValue.count > 10) {
|
|
4130
|
+
* nextValue.count = 10; // Clamp the value to a maximum of 10
|
|
4131
|
+
* }
|
|
4132
|
+
*
|
|
4133
|
+
* if (nextValue.count === 10) {
|
|
4134
|
+
* nextValue.isMaxValue = true; // Set isMaxValue to true if count is 10
|
|
4135
|
+
* } else {
|
|
4136
|
+
* nextValue.isMaxValue = false; // Reset isMaxValue otherwise
|
|
4137
|
+
* }
|
|
4138
|
+
* });
|
|
4139
|
+
*
|
|
4140
|
+
* store.partialNext({ count: 15 });
|
|
4141
|
+
*
|
|
4142
|
+
* store.getLatestValue(); // { count: 10, isMaxValue: true }
|
|
4143
|
+
*
|
|
4144
|
+
* store.partialNext({ count: 5 });
|
|
4145
|
+
*
|
|
4146
|
+
* store.getLatestValue(); // { count: 5, isMaxValue: false }
|
|
4147
|
+
* ```
|
|
4148
|
+
*
|
|
4149
|
+
* @param preprocessor - The function to be called with the next and previous values before the state is updated.
|
|
4150
|
+
* @returns A `RemovePreprocessor` function that removes the preprocessor when called.
|
|
4151
|
+
*/
|
|
4152
|
+
addPreprocessor(preprocessor) {
|
|
4153
|
+
this.preprocessors.add(preprocessor);
|
|
4154
|
+
return () => {
|
|
4155
|
+
this.preprocessors.delete(preprocessor);
|
|
4156
|
+
};
|
|
4157
|
+
}
|
|
4158
|
+
};
|
|
4159
|
+
var MergedStateStore = class _MergedStateStore extends StateStore {
|
|
4160
|
+
constructor({ original, merged }) {
|
|
4161
|
+
const originalValue = original.getLatestValue();
|
|
4162
|
+
const mergedValue = merged.getLatestValue();
|
|
4163
|
+
super({
|
|
4164
|
+
...originalValue,
|
|
4165
|
+
...mergedValue
|
|
4166
|
+
});
|
|
4167
|
+
// override original methods and "disable" them
|
|
4168
|
+
this.next = () => {
|
|
4169
|
+
console.warn(
|
|
4170
|
+
`${_MergedStateStore.name}.next is disabled, call original.next or merged.next instead`
|
|
4171
|
+
);
|
|
4172
|
+
};
|
|
4173
|
+
this.partialNext = () => {
|
|
4174
|
+
console.warn(
|
|
4175
|
+
`${_MergedStateStore.name}.partialNext is disabled, call original.partialNext or merged.partialNext instead`
|
|
4176
|
+
);
|
|
4177
|
+
};
|
|
4178
|
+
this.cachedOriginalValue = originalValue;
|
|
4179
|
+
this.cachedMergedValue = mergedValue;
|
|
4180
|
+
this.original = original;
|
|
4181
|
+
this.merged = merged;
|
|
4182
|
+
}
|
|
4183
|
+
/**
|
|
4184
|
+
* Subscribes to changes in the merged state store.
|
|
4185
|
+
*
|
|
4186
|
+
* This method extends the base subscribe functionality to handle the merged nature of this store:
|
|
4187
|
+
* 1. The first subscriber triggers registration of helper subscribers that listen to both source stores
|
|
4188
|
+
* 2. Changes from either source store are propagated to this merged store
|
|
4189
|
+
* 3. Source store values are cached to prevent unnecessary updates
|
|
4190
|
+
*
|
|
4191
|
+
* When the first subscriber is added, the method sets up listeners on both original and merged stores.
|
|
4192
|
+
* These listeners update the combined store value whenever either source store changes.
|
|
4193
|
+
* All subscriptions (helpers and the actual handler) are tracked so they can be properly cleaned up.
|
|
4194
|
+
*
|
|
4195
|
+
* @param handler - The callback function that will be executed when the state changes
|
|
4196
|
+
* @returns An unsubscribe function that, when called, removes the subscription and any helper subscriptions
|
|
4197
|
+
*/
|
|
4198
|
+
subscribe(handler) {
|
|
4199
|
+
const unsubscribeFunctions = [];
|
|
4200
|
+
if (!this.handlers.size) {
|
|
4201
|
+
const base = (nextValue) => {
|
|
4202
|
+
super.next((currentValue) => ({
|
|
4203
|
+
...currentValue,
|
|
4204
|
+
...nextValue
|
|
4205
|
+
}));
|
|
4206
|
+
};
|
|
4207
|
+
unsubscribeFunctions.push(
|
|
4208
|
+
this.original.subscribe((nextValue) => {
|
|
4209
|
+
if (nextValue === this.cachedOriginalValue) return;
|
|
4210
|
+
this.cachedOriginalValue = nextValue;
|
|
4211
|
+
base(nextValue);
|
|
4212
|
+
}),
|
|
4213
|
+
this.merged.subscribe((nextValue) => {
|
|
4214
|
+
if (nextValue === this.cachedMergedValue) return;
|
|
4215
|
+
this.cachedMergedValue = nextValue;
|
|
4216
|
+
base(nextValue);
|
|
4217
|
+
})
|
|
4218
|
+
);
|
|
4219
|
+
}
|
|
4220
|
+
unsubscribeFunctions.push(super.subscribe(handler));
|
|
4221
|
+
return () => {
|
|
4222
|
+
unsubscribeFunctions.forEach((unsubscribe) => unsubscribe());
|
|
4223
|
+
};
|
|
4224
|
+
}
|
|
4225
|
+
/**
|
|
4226
|
+
* Retrieves the latest combined state from both original and merged stores.
|
|
4227
|
+
*
|
|
4228
|
+
* This method extends the base getLatestValue functionality to ensure the merged store
|
|
4229
|
+
* remains in sync with its source stores even when there are no active subscribers.
|
|
4230
|
+
*
|
|
4231
|
+
* When there are no handlers registered, the method:
|
|
4232
|
+
* 1. Fetches the latest values from both source stores
|
|
4233
|
+
* 2. Compares them with the cached values to detect changes
|
|
4234
|
+
* 3. If changes are detected, updates the internal value and caches
|
|
4235
|
+
* the new source values to maintain consistency
|
|
4236
|
+
*
|
|
4237
|
+
* This approach ensures that calling getLatestValue() always returns the most
|
|
4238
|
+
* up-to-date combined state, even if the merged store hasn't been actively
|
|
4239
|
+
* receiving updates through subscriptions.
|
|
4240
|
+
*
|
|
4241
|
+
* @returns The latest combined state from both original and merged stores
|
|
4242
|
+
*/
|
|
4243
|
+
getLatestValue() {
|
|
4244
|
+
if (!this.handlers.size) {
|
|
4245
|
+
const originalValue = this.original.getLatestValue();
|
|
4246
|
+
const mergedValue = this.merged.getLatestValue();
|
|
4247
|
+
if (originalValue !== this.cachedOriginalValue || mergedValue !== this.cachedMergedValue) {
|
|
4248
|
+
this.value = {
|
|
4249
|
+
...originalValue,
|
|
4250
|
+
...mergedValue
|
|
4251
|
+
};
|
|
4252
|
+
this.cachedMergedValue = mergedValue;
|
|
4253
|
+
this.cachedOriginalValue = originalValue;
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
4256
|
+
return super.getLatestValue();
|
|
4257
|
+
}
|
|
4258
|
+
addPreprocessor() {
|
|
4259
|
+
console.warn(
|
|
4260
|
+
`${_MergedStateStore.name}.addPreprocessor is disabled, call original.addPreprocessor or merged.addPreprocessor instead`
|
|
4261
|
+
);
|
|
4262
|
+
return noop2;
|
|
4263
|
+
}
|
|
4089
4264
|
};
|
|
4090
4265
|
|
|
4091
4266
|
// src/utils/mergeWith/mergeWithCore.ts
|
|
@@ -5505,7 +5680,9 @@ var ErrorFromResponse = class extends Error {
|
|
|
5505
5680
|
return {
|
|
5506
5681
|
message: `(${joinable.join(", ")}) - ${this.message}`,
|
|
5507
5682
|
stack: this.stack,
|
|
5508
|
-
name: this.name
|
|
5683
|
+
name: this.name,
|
|
5684
|
+
code: this.code,
|
|
5685
|
+
status: this.status
|
|
5509
5686
|
};
|
|
5510
5687
|
}
|
|
5511
5688
|
};
|
|
@@ -6073,7 +6250,7 @@ var MessageDraftComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
|
6073
6250
|
}
|
|
6074
6251
|
};
|
|
6075
6252
|
|
|
6076
|
-
// src/
|
|
6253
|
+
// src/search/BaseSearchSource.ts
|
|
6077
6254
|
var DEFAULT_SEARCH_SOURCE_OPTIONS = {
|
|
6078
6255
|
debounceMs: 300,
|
|
6079
6256
|
pageSize: 10
|
|
@@ -6199,6 +6376,112 @@ var BaseSearchSource = class {
|
|
|
6199
6376
|
this.activate();
|
|
6200
6377
|
}
|
|
6201
6378
|
};
|
|
6379
|
+
|
|
6380
|
+
// src/search/SearchController.ts
|
|
6381
|
+
var SearchController = class {
|
|
6382
|
+
constructor({ config, sources } = {}) {
|
|
6383
|
+
this.addSource = (source) => {
|
|
6384
|
+
this.state.partialNext({
|
|
6385
|
+
sources: [...this.sources, source]
|
|
6386
|
+
});
|
|
6387
|
+
};
|
|
6388
|
+
this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
|
|
6389
|
+
this.removeSource = (sourceType) => {
|
|
6390
|
+
const newSources = this.sources.filter((s) => s.type !== sourceType);
|
|
6391
|
+
if (newSources.length === this.sources.length) return;
|
|
6392
|
+
this.state.partialNext({ sources: newSources });
|
|
6393
|
+
};
|
|
6394
|
+
this.activateSource = (sourceType) => {
|
|
6395
|
+
const source = this.getSource(sourceType);
|
|
6396
|
+
if (!source || source.isActive) return;
|
|
6397
|
+
if (this.config.keepSingleActiveSource) {
|
|
6398
|
+
this.sources.forEach((s) => {
|
|
6399
|
+
if (s.type !== sourceType) {
|
|
6400
|
+
s.deactivate();
|
|
6401
|
+
}
|
|
6402
|
+
});
|
|
6403
|
+
}
|
|
6404
|
+
source.activate();
|
|
6405
|
+
this.state.partialNext({ sources: [...this.sources] });
|
|
6406
|
+
};
|
|
6407
|
+
this.deactivateSource = (sourceType) => {
|
|
6408
|
+
const source = this.getSource(sourceType);
|
|
6409
|
+
if (!source?.isActive) return;
|
|
6410
|
+
if (this.activeSources.length === 1) return;
|
|
6411
|
+
source.deactivate();
|
|
6412
|
+
this.state.partialNext({ sources: [...this.sources] });
|
|
6413
|
+
};
|
|
6414
|
+
this.activate = () => {
|
|
6415
|
+
if (!this.activeSources.length) {
|
|
6416
|
+
const sourcesToActivate = this.config.keepSingleActiveSource ? this.sources.slice(0, 1) : this.sources;
|
|
6417
|
+
sourcesToActivate.forEach((s) => s.activate());
|
|
6418
|
+
}
|
|
6419
|
+
if (this.isActive) return;
|
|
6420
|
+
this.state.partialNext({ isActive: true });
|
|
6421
|
+
};
|
|
6422
|
+
this.search = async (searchQuery) => {
|
|
6423
|
+
const searchedSources = this.activeSources;
|
|
6424
|
+
this.state.partialNext({
|
|
6425
|
+
searchQuery
|
|
6426
|
+
});
|
|
6427
|
+
await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
|
|
6428
|
+
};
|
|
6429
|
+
this.cancelSearchQueries = () => {
|
|
6430
|
+
this.activeSources.forEach((s) => s.cancelScheduledQuery());
|
|
6431
|
+
};
|
|
6432
|
+
this.clear = () => {
|
|
6433
|
+
this.cancelSearchQueries();
|
|
6434
|
+
this.sources.forEach(
|
|
6435
|
+
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
6436
|
+
);
|
|
6437
|
+
this.state.next((current) => ({
|
|
6438
|
+
...current,
|
|
6439
|
+
isActive: true,
|
|
6440
|
+
queriesInProgress: [],
|
|
6441
|
+
searchQuery: ""
|
|
6442
|
+
}));
|
|
6443
|
+
};
|
|
6444
|
+
this.exit = () => {
|
|
6445
|
+
this.cancelSearchQueries();
|
|
6446
|
+
this.sources.forEach(
|
|
6447
|
+
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
6448
|
+
);
|
|
6449
|
+
this.state.next((current) => ({
|
|
6450
|
+
...current,
|
|
6451
|
+
isActive: false,
|
|
6452
|
+
queriesInProgress: [],
|
|
6453
|
+
searchQuery: ""
|
|
6454
|
+
}));
|
|
6455
|
+
};
|
|
6456
|
+
this.state = new StateStore({
|
|
6457
|
+
isActive: false,
|
|
6458
|
+
searchQuery: "",
|
|
6459
|
+
sources: sources ?? []
|
|
6460
|
+
});
|
|
6461
|
+
this._internalState = new StateStore({});
|
|
6462
|
+
this.config = { keepSingleActiveSource: true, ...config };
|
|
6463
|
+
}
|
|
6464
|
+
get hasNext() {
|
|
6465
|
+
return this.sources.some((source) => source.hasNext);
|
|
6466
|
+
}
|
|
6467
|
+
get sources() {
|
|
6468
|
+
return this.state.getLatestValue().sources;
|
|
6469
|
+
}
|
|
6470
|
+
get activeSources() {
|
|
6471
|
+
return this.state.getLatestValue().sources.filter((s) => s.isActive);
|
|
6472
|
+
}
|
|
6473
|
+
get isActive() {
|
|
6474
|
+
return this.state.getLatestValue().isActive;
|
|
6475
|
+
}
|
|
6476
|
+
get searchQuery() {
|
|
6477
|
+
return this.state.getLatestValue().searchQuery;
|
|
6478
|
+
}
|
|
6479
|
+
get searchSourceTypes() {
|
|
6480
|
+
return this.sources.map((s) => s.type);
|
|
6481
|
+
}
|
|
6482
|
+
};
|
|
6483
|
+
|
|
6484
|
+
// src/search/UserSearchSource.ts
|
|
6202
6485
|
var UserSearchSource = class extends BaseSearchSource {
|
|
6203
6486
|
constructor(client, options) {
|
|
6204
6487
|
super(options);
|
|
@@ -6222,6 +6505,8 @@ var UserSearchSource = class extends BaseSearchSource {
|
|
|
6222
6505
|
return items.filter((u) => u.id !== this.client.user?.id);
|
|
6223
6506
|
}
|
|
6224
6507
|
};
|
|
6508
|
+
|
|
6509
|
+
// src/search/ChannelSearchSource.ts
|
|
6225
6510
|
var ChannelSearchSource = class extends BaseSearchSource {
|
|
6226
6511
|
constructor(client, options) {
|
|
6227
6512
|
super(options);
|
|
@@ -6243,6 +6528,8 @@ var ChannelSearchSource = class extends BaseSearchSource {
|
|
|
6243
6528
|
return items;
|
|
6244
6529
|
}
|
|
6245
6530
|
};
|
|
6531
|
+
|
|
6532
|
+
// src/search/MessageSearchSource.ts
|
|
6246
6533
|
var MessageSearchSource = class extends BaseSearchSource {
|
|
6247
6534
|
constructor(client, options) {
|
|
6248
6535
|
super(options);
|
|
@@ -6303,108 +6590,6 @@ var MessageSearchSource = class extends BaseSearchSource {
|
|
|
6303
6590
|
return items;
|
|
6304
6591
|
}
|
|
6305
6592
|
};
|
|
6306
|
-
var SearchController = class {
|
|
6307
|
-
constructor({ config, sources } = {}) {
|
|
6308
|
-
this.addSource = (source) => {
|
|
6309
|
-
this.state.partialNext({
|
|
6310
|
-
sources: [...this.sources, source]
|
|
6311
|
-
});
|
|
6312
|
-
};
|
|
6313
|
-
this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
|
|
6314
|
-
this.removeSource = (sourceType) => {
|
|
6315
|
-
const newSources = this.sources.filter((s) => s.type !== sourceType);
|
|
6316
|
-
if (newSources.length === this.sources.length) return;
|
|
6317
|
-
this.state.partialNext({ sources: newSources });
|
|
6318
|
-
};
|
|
6319
|
-
this.activateSource = (sourceType) => {
|
|
6320
|
-
const source = this.getSource(sourceType);
|
|
6321
|
-
if (!source || source.isActive) return;
|
|
6322
|
-
if (this.config.keepSingleActiveSource) {
|
|
6323
|
-
this.sources.forEach((s) => {
|
|
6324
|
-
if (s.type !== sourceType) {
|
|
6325
|
-
s.deactivate();
|
|
6326
|
-
}
|
|
6327
|
-
});
|
|
6328
|
-
}
|
|
6329
|
-
source.activate();
|
|
6330
|
-
this.state.partialNext({ sources: [...this.sources] });
|
|
6331
|
-
};
|
|
6332
|
-
this.deactivateSource = (sourceType) => {
|
|
6333
|
-
const source = this.getSource(sourceType);
|
|
6334
|
-
if (!source?.isActive) return;
|
|
6335
|
-
if (this.activeSources.length === 1) return;
|
|
6336
|
-
source.deactivate();
|
|
6337
|
-
this.state.partialNext({ sources: [...this.sources] });
|
|
6338
|
-
};
|
|
6339
|
-
this.activate = () => {
|
|
6340
|
-
if (!this.activeSources.length) {
|
|
6341
|
-
const sourcesToActivate = this.config.keepSingleActiveSource ? this.sources.slice(0, 1) : this.sources;
|
|
6342
|
-
sourcesToActivate.forEach((s) => s.activate());
|
|
6343
|
-
}
|
|
6344
|
-
if (this.isActive) return;
|
|
6345
|
-
this.state.partialNext({ isActive: true });
|
|
6346
|
-
};
|
|
6347
|
-
this.search = async (searchQuery) => {
|
|
6348
|
-
const searchedSources = this.activeSources;
|
|
6349
|
-
this.state.partialNext({
|
|
6350
|
-
searchQuery
|
|
6351
|
-
});
|
|
6352
|
-
await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
|
|
6353
|
-
};
|
|
6354
|
-
this.cancelSearchQueries = () => {
|
|
6355
|
-
this.activeSources.forEach((s) => s.cancelScheduledQuery());
|
|
6356
|
-
};
|
|
6357
|
-
this.clear = () => {
|
|
6358
|
-
this.cancelSearchQueries();
|
|
6359
|
-
this.sources.forEach(
|
|
6360
|
-
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
6361
|
-
);
|
|
6362
|
-
this.state.next((current) => ({
|
|
6363
|
-
...current,
|
|
6364
|
-
isActive: true,
|
|
6365
|
-
queriesInProgress: [],
|
|
6366
|
-
searchQuery: ""
|
|
6367
|
-
}));
|
|
6368
|
-
};
|
|
6369
|
-
this.exit = () => {
|
|
6370
|
-
this.cancelSearchQueries();
|
|
6371
|
-
this.sources.forEach(
|
|
6372
|
-
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
6373
|
-
);
|
|
6374
|
-
this.state.next((current) => ({
|
|
6375
|
-
...current,
|
|
6376
|
-
isActive: false,
|
|
6377
|
-
queriesInProgress: [],
|
|
6378
|
-
searchQuery: ""
|
|
6379
|
-
}));
|
|
6380
|
-
};
|
|
6381
|
-
this.state = new StateStore({
|
|
6382
|
-
isActive: false,
|
|
6383
|
-
searchQuery: "",
|
|
6384
|
-
sources: sources ?? []
|
|
6385
|
-
});
|
|
6386
|
-
this._internalState = new StateStore({});
|
|
6387
|
-
this.config = { keepSingleActiveSource: true, ...config };
|
|
6388
|
-
}
|
|
6389
|
-
get hasNext() {
|
|
6390
|
-
return this.sources.some((source) => source.hasNext);
|
|
6391
|
-
}
|
|
6392
|
-
get sources() {
|
|
6393
|
-
return this.state.getLatestValue().sources;
|
|
6394
|
-
}
|
|
6395
|
-
get activeSources() {
|
|
6396
|
-
return this.state.getLatestValue().sources.filter((s) => s.isActive);
|
|
6397
|
-
}
|
|
6398
|
-
get isActive() {
|
|
6399
|
-
return this.state.getLatestValue().isActive;
|
|
6400
|
-
}
|
|
6401
|
-
get searchQuery() {
|
|
6402
|
-
return this.state.getLatestValue().searchQuery;
|
|
6403
|
-
}
|
|
6404
|
-
get searchSourceTypes() {
|
|
6405
|
-
return this.sources.map((s) => s.type);
|
|
6406
|
-
}
|
|
6407
|
-
};
|
|
6408
6593
|
|
|
6409
6594
|
// src/messageComposer/middleware/textComposer/textMiddlewareUtils.ts
|
|
6410
6595
|
var getTriggerCharWithToken = ({
|
|
@@ -7638,7 +7823,7 @@ var initState5 = (composition) => {
|
|
|
7638
7823
|
pollId: message.poll_id ?? null
|
|
7639
7824
|
};
|
|
7640
7825
|
};
|
|
7641
|
-
var
|
|
7826
|
+
var noop3 = () => void 0;
|
|
7642
7827
|
var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
7643
7828
|
// todo: mediaRecorder: MediaRecorderController;
|
|
7644
7829
|
constructor({
|
|
@@ -7666,7 +7851,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
7666
7851
|
this.initEditingAuditState = (composition) => initEditingAuditState(composition);
|
|
7667
7852
|
this.registerSubscriptions = () => {
|
|
7668
7853
|
if (this.hasSubscriptions) {
|
|
7669
|
-
return
|
|
7854
|
+
return noop3;
|
|
7670
7855
|
}
|
|
7671
7856
|
this.addUnsubscribeFunction(this.subscribeMessageComposerSetupStateChange());
|
|
7672
7857
|
this.addUnsubscribeFunction(this.subscribeMessageUpdated());
|
|
@@ -9183,6 +9368,7 @@ var Channel = class {
|
|
|
9183
9368
|
})
|
|
9184
9369
|
};
|
|
9185
9370
|
this.getClient().polls.hydratePollCache(state.messages, true);
|
|
9371
|
+
this.getClient().reminders.hydrateState(state.messages);
|
|
9186
9372
|
if (state.draft) {
|
|
9187
9373
|
this.messageComposer.initState({ composition: state.draft });
|
|
9188
9374
|
}
|
|
@@ -10474,7 +10660,9 @@ var TokenManager = class {
|
|
|
10474
10660
|
try {
|
|
10475
10661
|
this.token = await this.tokenProvider();
|
|
10476
10662
|
} catch (e) {
|
|
10477
|
-
return reject(
|
|
10663
|
+
return reject(
|
|
10664
|
+
new Error(`Call to tokenProvider failed with message: ${e}`, { cause: e })
|
|
10665
|
+
);
|
|
10478
10666
|
}
|
|
10479
10667
|
resolve(this.token);
|
|
10480
10668
|
}
|
|
@@ -12224,6 +12412,458 @@ var NotificationManager = class {
|
|
|
12224
12412
|
}
|
|
12225
12413
|
};
|
|
12226
12414
|
|
|
12415
|
+
// src/reminders/ReminderTimer.ts
|
|
12416
|
+
var oneMinute = 60 * 1e3;
|
|
12417
|
+
var oneHour = 60 * oneMinute;
|
|
12418
|
+
var oneDay = 24 * oneHour;
|
|
12419
|
+
var oneWeek = 7 * oneDay;
|
|
12420
|
+
var GROUP_BOUNDS = {
|
|
12421
|
+
minute: { lower: oneMinute, upper: oneHour },
|
|
12422
|
+
hour: { lower: oneHour, upper: oneDay },
|
|
12423
|
+
day: { lower: oneDay, upper: oneWeek }
|
|
12424
|
+
};
|
|
12425
|
+
var DEFAULT_STOP_REFRESH_BOUNDARY_MS = 2 * oneWeek;
|
|
12426
|
+
var ReminderTimer = class {
|
|
12427
|
+
constructor({
|
|
12428
|
+
reminder,
|
|
12429
|
+
config
|
|
12430
|
+
}) {
|
|
12431
|
+
this.timeout = null;
|
|
12432
|
+
this.stopRefreshBoundaryMs = DEFAULT_STOP_REFRESH_BOUNDARY_MS;
|
|
12433
|
+
this.getRefreshIntervalLength = () => {
|
|
12434
|
+
if (!this.reminder.remindAt) return null;
|
|
12435
|
+
const distanceFromDeadlineMs = Math.abs(timeLeftMs(this.reminder.remindAt.getTime()));
|
|
12436
|
+
let refreshInterval;
|
|
12437
|
+
if (distanceFromDeadlineMs === 0) {
|
|
12438
|
+
refreshInterval = oneMinute;
|
|
12439
|
+
} else if (distanceFromDeadlineMs < GROUP_BOUNDS.minute.lower) {
|
|
12440
|
+
refreshInterval = distanceFromDeadlineMs;
|
|
12441
|
+
} else if (distanceFromDeadlineMs <= GROUP_BOUNDS.minute.upper) {
|
|
12442
|
+
refreshInterval = oneMinute;
|
|
12443
|
+
} else if (distanceFromDeadlineMs <= GROUP_BOUNDS.hour.upper) {
|
|
12444
|
+
refreshInterval = oneHour;
|
|
12445
|
+
} else {
|
|
12446
|
+
refreshInterval = oneDay;
|
|
12447
|
+
}
|
|
12448
|
+
return refreshInterval;
|
|
12449
|
+
};
|
|
12450
|
+
this.init = () => {
|
|
12451
|
+
if (!this.reminder.remindAt) return null;
|
|
12452
|
+
const timeoutLength = this.getRefreshIntervalLength();
|
|
12453
|
+
if (timeoutLength === null) return null;
|
|
12454
|
+
const boundaryTimestamp = this.reminder.remindAt?.getTime() + this.stopRefreshBoundaryMs;
|
|
12455
|
+
const timeLeftToBoundary = boundaryTimestamp - Date.now();
|
|
12456
|
+
if (timeLeftToBoundary <= 0) {
|
|
12457
|
+
this.timeout = null;
|
|
12458
|
+
return;
|
|
12459
|
+
}
|
|
12460
|
+
if (this.timeout) clearTimeout(this.timeout);
|
|
12461
|
+
this.timeout = setTimeout(() => {
|
|
12462
|
+
this.reminder.refreshTimeLeft();
|
|
12463
|
+
this.init();
|
|
12464
|
+
}, timeoutLength);
|
|
12465
|
+
};
|
|
12466
|
+
this.clear = () => {
|
|
12467
|
+
if (this.timeout) {
|
|
12468
|
+
clearInterval(this.timeout);
|
|
12469
|
+
this.timeout = null;
|
|
12470
|
+
}
|
|
12471
|
+
};
|
|
12472
|
+
this.reminder = reminder;
|
|
12473
|
+
if (typeof config?.stopRefreshBoundaryMs === "number") {
|
|
12474
|
+
this.stopRefreshBoundaryMs = config.stopRefreshBoundaryMs;
|
|
12475
|
+
}
|
|
12476
|
+
}
|
|
12477
|
+
};
|
|
12478
|
+
|
|
12479
|
+
// src/reminders/Reminder.ts
|
|
12480
|
+
var timeLeftMs = (remindAt) => remindAt - (/* @__PURE__ */ new Date()).getTime();
|
|
12481
|
+
var _Reminder = class _Reminder {
|
|
12482
|
+
constructor({ data, config }) {
|
|
12483
|
+
this.setState = (data) => {
|
|
12484
|
+
this.state.next((current) => {
|
|
12485
|
+
const newState = { ...current, ..._Reminder.toStateValue(data) };
|
|
12486
|
+
if (newState.remind_at) {
|
|
12487
|
+
newState.timeLeftMs = timeLeftMs(newState.remind_at.getTime());
|
|
12488
|
+
}
|
|
12489
|
+
return newState;
|
|
12490
|
+
});
|
|
12491
|
+
if (data.remind_at) {
|
|
12492
|
+
this.initTimer();
|
|
12493
|
+
} else if (!data.remind_at) {
|
|
12494
|
+
this.clearTimer();
|
|
12495
|
+
}
|
|
12496
|
+
};
|
|
12497
|
+
this.refreshTimeLeft = () => {
|
|
12498
|
+
if (!this.remindAt) return;
|
|
12499
|
+
this.state.partialNext({ timeLeftMs: timeLeftMs(this.remindAt.getTime()) });
|
|
12500
|
+
};
|
|
12501
|
+
this.initTimer = () => {
|
|
12502
|
+
this.timer.init();
|
|
12503
|
+
};
|
|
12504
|
+
this.clearTimer = () => {
|
|
12505
|
+
this.timer.clear();
|
|
12506
|
+
};
|
|
12507
|
+
this.state = new StateStore(_Reminder.toStateValue(data));
|
|
12508
|
+
this.timer = new ReminderTimer({ reminder: this, config });
|
|
12509
|
+
this.initTimer();
|
|
12510
|
+
}
|
|
12511
|
+
get id() {
|
|
12512
|
+
return this.state.getLatestValue().message_id;
|
|
12513
|
+
}
|
|
12514
|
+
get remindAt() {
|
|
12515
|
+
return this.state.getLatestValue().remind_at;
|
|
12516
|
+
}
|
|
12517
|
+
get timeLeftMs() {
|
|
12518
|
+
return this.state.getLatestValue().timeLeftMs;
|
|
12519
|
+
}
|
|
12520
|
+
};
|
|
12521
|
+
_Reminder.toStateValue = (data) => ({
|
|
12522
|
+
...data,
|
|
12523
|
+
created_at: new Date(data.created_at),
|
|
12524
|
+
message: data.message || null,
|
|
12525
|
+
remind_at: data.remind_at ? new Date(data.remind_at) : null,
|
|
12526
|
+
timeLeftMs: data.remind_at ? timeLeftMs(new Date(data.remind_at).getTime()) : null,
|
|
12527
|
+
updated_at: new Date(data.updated_at),
|
|
12528
|
+
user: data.user || null
|
|
12529
|
+
});
|
|
12530
|
+
var Reminder = _Reminder;
|
|
12531
|
+
|
|
12532
|
+
// src/pagination/BasePaginator.ts
|
|
12533
|
+
var DEFAULT_PAGINATION_OPTIONS = {
|
|
12534
|
+
debounceMs: 300,
|
|
12535
|
+
pageSize: 10
|
|
12536
|
+
};
|
|
12537
|
+
var BasePaginator = class {
|
|
12538
|
+
constructor(options) {
|
|
12539
|
+
this._isCursorPagination = false;
|
|
12540
|
+
this.setDebounceOptions = ({ debounceMs }) => {
|
|
12541
|
+
this._executeQueryDebounced = debounce(this.executeQuery.bind(this), debounceMs);
|
|
12542
|
+
};
|
|
12543
|
+
this.canExecuteQuery = (direction) => !this.isLoading && direction === "next" && this.hasNext || direction === "prev" && this.hasPrev;
|
|
12544
|
+
this.next = () => this.executeQuery({ direction: "next" });
|
|
12545
|
+
this.prev = () => this.executeQuery({ direction: "prev" });
|
|
12546
|
+
this.nextDebounced = () => {
|
|
12547
|
+
this._executeQueryDebounced({ direction: "next" });
|
|
12548
|
+
};
|
|
12549
|
+
this.prevDebounced = () => {
|
|
12550
|
+
this._executeQueryDebounced({ direction: "prev" });
|
|
12551
|
+
};
|
|
12552
|
+
const { debounceMs, pageSize } = { ...DEFAULT_PAGINATION_OPTIONS, ...options };
|
|
12553
|
+
this.pageSize = pageSize;
|
|
12554
|
+
this.state = new StateStore(this.initialState);
|
|
12555
|
+
this.setDebounceOptions({ debounceMs });
|
|
12556
|
+
}
|
|
12557
|
+
get lastQueryError() {
|
|
12558
|
+
return this.state.getLatestValue().lastQueryError;
|
|
12559
|
+
}
|
|
12560
|
+
get hasNext() {
|
|
12561
|
+
return this.state.getLatestValue().hasNext;
|
|
12562
|
+
}
|
|
12563
|
+
get hasPrev() {
|
|
12564
|
+
return this.state.getLatestValue().hasPrev;
|
|
12565
|
+
}
|
|
12566
|
+
get hasResults() {
|
|
12567
|
+
return Array.isArray(this.state.getLatestValue().items);
|
|
12568
|
+
}
|
|
12569
|
+
get isLoading() {
|
|
12570
|
+
return this.state.getLatestValue().isLoading;
|
|
12571
|
+
}
|
|
12572
|
+
get initialState() {
|
|
12573
|
+
return {
|
|
12574
|
+
hasNext: true,
|
|
12575
|
+
hasPrev: true,
|
|
12576
|
+
//todo: check if optimistic value does not cause problems in UI
|
|
12577
|
+
isLoading: false,
|
|
12578
|
+
items: void 0,
|
|
12579
|
+
lastQueryError: void 0,
|
|
12580
|
+
cursor: void 0,
|
|
12581
|
+
offset: 0
|
|
12582
|
+
};
|
|
12583
|
+
}
|
|
12584
|
+
get items() {
|
|
12585
|
+
return this.state.getLatestValue().items;
|
|
12586
|
+
}
|
|
12587
|
+
get cursor() {
|
|
12588
|
+
return this.state.getLatestValue().cursor;
|
|
12589
|
+
}
|
|
12590
|
+
get offset() {
|
|
12591
|
+
return this.state.getLatestValue().offset;
|
|
12592
|
+
}
|
|
12593
|
+
getStateBeforeFirstQuery() {
|
|
12594
|
+
return {
|
|
12595
|
+
...this.initialState,
|
|
12596
|
+
isLoading: true
|
|
12597
|
+
};
|
|
12598
|
+
}
|
|
12599
|
+
getStateAfterQuery(stateUpdate, isFirstPage) {
|
|
12600
|
+
const current = this.state.getLatestValue();
|
|
12601
|
+
return {
|
|
12602
|
+
...current,
|
|
12603
|
+
lastQueryError: void 0,
|
|
12604
|
+
// reset lastQueryError that can be overridden by the stateUpdate
|
|
12605
|
+
...stateUpdate,
|
|
12606
|
+
isLoading: false,
|
|
12607
|
+
items: isFirstPage ? stateUpdate.items : [...this.items ?? [], ...stateUpdate.items || []]
|
|
12608
|
+
};
|
|
12609
|
+
}
|
|
12610
|
+
async executeQuery({ direction }) {
|
|
12611
|
+
if (!this.canExecuteQuery(direction)) return;
|
|
12612
|
+
const isFirstPage = typeof this.items === "undefined";
|
|
12613
|
+
if (isFirstPage) {
|
|
12614
|
+
this.state.next(this.getStateBeforeFirstQuery());
|
|
12615
|
+
} else {
|
|
12616
|
+
this.state.partialNext({ isLoading: true });
|
|
12617
|
+
}
|
|
12618
|
+
const stateUpdate = {};
|
|
12619
|
+
try {
|
|
12620
|
+
const results = await this.query({ direction });
|
|
12621
|
+
if (!results) return;
|
|
12622
|
+
const { items, next, prev } = results;
|
|
12623
|
+
if (isFirstPage && (next || prev)) {
|
|
12624
|
+
this._isCursorPagination = true;
|
|
12625
|
+
}
|
|
12626
|
+
if (this._isCursorPagination) {
|
|
12627
|
+
stateUpdate.cursor = { next: next || null, prev: prev || null };
|
|
12628
|
+
stateUpdate.hasNext = !!next;
|
|
12629
|
+
stateUpdate.hasPrev = !!prev;
|
|
12630
|
+
} else {
|
|
12631
|
+
stateUpdate.offset = (this.offset ?? 0) + items.length;
|
|
12632
|
+
stateUpdate.hasNext = items.length === this.pageSize;
|
|
12633
|
+
}
|
|
12634
|
+
stateUpdate.items = await this.filterQueryResults(items);
|
|
12635
|
+
} catch (e) {
|
|
12636
|
+
stateUpdate.lastQueryError = e;
|
|
12637
|
+
} finally {
|
|
12638
|
+
this.state.next(this.getStateAfterQuery(stateUpdate, isFirstPage));
|
|
12639
|
+
}
|
|
12640
|
+
}
|
|
12641
|
+
cancelScheduledQuery() {
|
|
12642
|
+
this._executeQueryDebounced.cancel();
|
|
12643
|
+
}
|
|
12644
|
+
resetState() {
|
|
12645
|
+
this.state.next(this.initialState);
|
|
12646
|
+
}
|
|
12647
|
+
};
|
|
12648
|
+
|
|
12649
|
+
// src/pagination/ReminderPaginator.ts
|
|
12650
|
+
var ReminderPaginator = class extends BasePaginator {
|
|
12651
|
+
constructor(client, options) {
|
|
12652
|
+
super(options);
|
|
12653
|
+
this.query = async ({
|
|
12654
|
+
direction
|
|
12655
|
+
}) => {
|
|
12656
|
+
const cursor = this.cursor?.[direction];
|
|
12657
|
+
const {
|
|
12658
|
+
reminders: items,
|
|
12659
|
+
next,
|
|
12660
|
+
prev
|
|
12661
|
+
} = await this.client.queryReminders({
|
|
12662
|
+
filter: this.filters,
|
|
12663
|
+
sort: this.sort,
|
|
12664
|
+
limit: this.pageSize,
|
|
12665
|
+
[direction]: cursor
|
|
12666
|
+
});
|
|
12667
|
+
return { items, next, prev };
|
|
12668
|
+
};
|
|
12669
|
+
this.filterQueryResults = (items) => items;
|
|
12670
|
+
this.client = client;
|
|
12671
|
+
}
|
|
12672
|
+
};
|
|
12673
|
+
|
|
12674
|
+
// src/reminders/ReminderManager.ts
|
|
12675
|
+
var oneMinute2 = 60 * 1e3;
|
|
12676
|
+
var oneHour2 = 60 * oneMinute2;
|
|
12677
|
+
var oneDay2 = 24 * oneHour2;
|
|
12678
|
+
var DEFAULT_REMINDER_MANAGER_CONFIG = {
|
|
12679
|
+
scheduledOffsetsMs: [
|
|
12680
|
+
2 * oneMinute2,
|
|
12681
|
+
30 * oneMinute2,
|
|
12682
|
+
oneHour2,
|
|
12683
|
+
2 * oneHour2,
|
|
12684
|
+
8 * oneHour2,
|
|
12685
|
+
oneDay2
|
|
12686
|
+
]
|
|
12687
|
+
};
|
|
12688
|
+
var isReminderExistsError = (error) => error.message.match("already has reminder created for this message_id");
|
|
12689
|
+
var isReminderDoesNotExistError = (error) => error.message.match("reminder does not exist");
|
|
12690
|
+
var _ReminderManager = class _ReminderManager extends WithSubscriptions {
|
|
12691
|
+
constructor({ client, config }) {
|
|
12692
|
+
super();
|
|
12693
|
+
this.upsertToState = ({
|
|
12694
|
+
data,
|
|
12695
|
+
overwrite = true
|
|
12696
|
+
}) => {
|
|
12697
|
+
if (!this.client._cacheEnabled()) {
|
|
12698
|
+
return;
|
|
12699
|
+
}
|
|
12700
|
+
const cachedReminder = this.getFromState(data.message_id);
|
|
12701
|
+
if (!cachedReminder) {
|
|
12702
|
+
const reminder = new Reminder({
|
|
12703
|
+
data,
|
|
12704
|
+
config: { stopRefreshBoundaryMs: this.stopTimerRefreshBoundaryMs }
|
|
12705
|
+
});
|
|
12706
|
+
this.state.partialNext({
|
|
12707
|
+
reminders: new Map(this.reminders.set(data.message_id, reminder))
|
|
12708
|
+
});
|
|
12709
|
+
} else if (overwrite) {
|
|
12710
|
+
cachedReminder.setState(data);
|
|
12711
|
+
}
|
|
12712
|
+
return cachedReminder;
|
|
12713
|
+
};
|
|
12714
|
+
this.removeFromState = (messageId) => {
|
|
12715
|
+
const cachedReminder = this.getFromState(messageId);
|
|
12716
|
+
if (!cachedReminder) return;
|
|
12717
|
+
cachedReminder.clearTimer();
|
|
12718
|
+
const reminders = this.reminders;
|
|
12719
|
+
reminders.delete(messageId);
|
|
12720
|
+
this.state.partialNext({ reminders: new Map(reminders) });
|
|
12721
|
+
};
|
|
12722
|
+
this.hydrateState = (messages) => {
|
|
12723
|
+
messages.forEach(({ reminder }) => {
|
|
12724
|
+
if (reminder) {
|
|
12725
|
+
this.upsertToState({ data: reminder });
|
|
12726
|
+
}
|
|
12727
|
+
});
|
|
12728
|
+
};
|
|
12729
|
+
// State API END //
|
|
12730
|
+
// Timers API START //
|
|
12731
|
+
this.initTimers = () => {
|
|
12732
|
+
this.reminders.forEach((reminder) => reminder.initTimer());
|
|
12733
|
+
};
|
|
12734
|
+
this.clearTimers = () => {
|
|
12735
|
+
this.reminders.forEach((reminder) => reminder.clearTimer());
|
|
12736
|
+
};
|
|
12737
|
+
this.registerSubscriptions = () => {
|
|
12738
|
+
if (this.hasSubscriptions) return;
|
|
12739
|
+
this.addUnsubscribeFunction(this.subscribeReminderCreated());
|
|
12740
|
+
this.addUnsubscribeFunction(this.subscribeReminderUpdated());
|
|
12741
|
+
this.addUnsubscribeFunction(this.subscribeReminderDeleted());
|
|
12742
|
+
this.addUnsubscribeFunction(this.subscribeNotificationReminderDue());
|
|
12743
|
+
this.addUnsubscribeFunction(this.subscribeMessageDeleted());
|
|
12744
|
+
this.addUnsubscribeFunction(this.subscribeMessageUndeleted());
|
|
12745
|
+
this.addUnsubscribeFunction(this.subscribePaginatorStateUpdated());
|
|
12746
|
+
this.addUnsubscribeFunction(this.subscribeConfigStateUpdated());
|
|
12747
|
+
};
|
|
12748
|
+
this.subscribeReminderCreated = () => this.client.on("reminder.created", (event) => {
|
|
12749
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
12750
|
+
const { reminder } = event;
|
|
12751
|
+
this.upsertToState({ data: reminder });
|
|
12752
|
+
}).unsubscribe;
|
|
12753
|
+
this.subscribeReminderUpdated = () => this.client.on("reminder.updated", (event) => {
|
|
12754
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
12755
|
+
const { reminder } = event;
|
|
12756
|
+
this.upsertToState({ data: reminder });
|
|
12757
|
+
}).unsubscribe;
|
|
12758
|
+
this.subscribeReminderDeleted = () => this.client.on("reminder.deleted", (event) => {
|
|
12759
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
12760
|
+
this.removeFromState(event.message_id);
|
|
12761
|
+
}).unsubscribe;
|
|
12762
|
+
this.subscribeMessageDeleted = () => this.client.on("message.deleted", (event) => {
|
|
12763
|
+
if (!event.message?.id) return;
|
|
12764
|
+
this.removeFromState(event.message.id);
|
|
12765
|
+
}).unsubscribe;
|
|
12766
|
+
this.subscribeMessageUndeleted = () => this.client.on("message.undeleted", (event) => {
|
|
12767
|
+
if (!event.message?.reminder) return;
|
|
12768
|
+
this.upsertToState({ data: event.message.reminder });
|
|
12769
|
+
}).unsubscribe;
|
|
12770
|
+
this.subscribeNotificationReminderDue = () => this.client.on("notification.reminder_due", () => null).unsubscribe;
|
|
12771
|
+
// todo: what should be performed on this event?
|
|
12772
|
+
this.subscribePaginatorStateUpdated = () => this.paginator.state.subscribeWithSelector(
|
|
12773
|
+
({ items }) => [items],
|
|
12774
|
+
([items]) => {
|
|
12775
|
+
if (!items) return;
|
|
12776
|
+
for (const reminder of items) {
|
|
12777
|
+
this.upsertToState({ data: reminder });
|
|
12778
|
+
}
|
|
12779
|
+
}
|
|
12780
|
+
);
|
|
12781
|
+
this.subscribeConfigStateUpdated = () => this.configState.subscribeWithSelector(
|
|
12782
|
+
({ stopTimerRefreshBoundaryMs }) => ({ stopTimerRefreshBoundaryMs }),
|
|
12783
|
+
({ stopTimerRefreshBoundaryMs }, previousValue) => {
|
|
12784
|
+
if (typeof stopTimerRefreshBoundaryMs === "number" && stopTimerRefreshBoundaryMs !== previousValue?.stopTimerRefreshBoundaryMs) {
|
|
12785
|
+
this.reminders.forEach((reminder) => {
|
|
12786
|
+
if (reminder.timer) {
|
|
12787
|
+
reminder.timer.stopRefreshBoundaryMs = stopTimerRefreshBoundaryMs;
|
|
12788
|
+
}
|
|
12789
|
+
});
|
|
12790
|
+
}
|
|
12791
|
+
}
|
|
12792
|
+
);
|
|
12793
|
+
// WS event handling END //
|
|
12794
|
+
// API calls START //
|
|
12795
|
+
this.upsertReminder = async (options) => {
|
|
12796
|
+
const { messageId } = options;
|
|
12797
|
+
if (this.getFromState(messageId)) {
|
|
12798
|
+
try {
|
|
12799
|
+
return await this.updateReminder(options);
|
|
12800
|
+
} catch (error) {
|
|
12801
|
+
if (isReminderDoesNotExistError(error)) {
|
|
12802
|
+
return await this.createReminder(options);
|
|
12803
|
+
}
|
|
12804
|
+
throw error;
|
|
12805
|
+
}
|
|
12806
|
+
} else {
|
|
12807
|
+
try {
|
|
12808
|
+
return await this.createReminder(options);
|
|
12809
|
+
} catch (error) {
|
|
12810
|
+
if (isReminderExistsError(error)) {
|
|
12811
|
+
return await this.updateReminder(options);
|
|
12812
|
+
}
|
|
12813
|
+
throw error;
|
|
12814
|
+
}
|
|
12815
|
+
}
|
|
12816
|
+
};
|
|
12817
|
+
this.createReminder = async (options) => {
|
|
12818
|
+
const { reminder } = await this.client.createReminder(options);
|
|
12819
|
+
return this.upsertToState({ data: reminder, overwrite: false });
|
|
12820
|
+
};
|
|
12821
|
+
this.updateReminder = async (options) => {
|
|
12822
|
+
const { reminder } = await this.client.updateReminder(options);
|
|
12823
|
+
return this.upsertToState({ data: reminder });
|
|
12824
|
+
};
|
|
12825
|
+
this.deleteReminder = async (messageId) => {
|
|
12826
|
+
await this.client.deleteReminder(messageId);
|
|
12827
|
+
this.removeFromState(messageId);
|
|
12828
|
+
};
|
|
12829
|
+
this.queryNextReminders = async () => {
|
|
12830
|
+
await this.paginator.next();
|
|
12831
|
+
};
|
|
12832
|
+
this.queryPreviousReminders = async () => {
|
|
12833
|
+
await this.paginator.prev();
|
|
12834
|
+
};
|
|
12835
|
+
this.client = client;
|
|
12836
|
+
this.configState = new StateStore({
|
|
12837
|
+
scheduledOffsetsMs: config?.scheduledOffsetsMs ?? DEFAULT_REMINDER_MANAGER_CONFIG.scheduledOffsetsMs
|
|
12838
|
+
});
|
|
12839
|
+
this.state = new StateStore({ reminders: /* @__PURE__ */ new Map() });
|
|
12840
|
+
this.paginator = new ReminderPaginator(client);
|
|
12841
|
+
}
|
|
12842
|
+
// Config API START //
|
|
12843
|
+
updateConfig(config) {
|
|
12844
|
+
this.configState.partialNext(config);
|
|
12845
|
+
}
|
|
12846
|
+
get stopTimerRefreshBoundaryMs() {
|
|
12847
|
+
return this.configState.getLatestValue().stopTimerRefreshBoundaryMs;
|
|
12848
|
+
}
|
|
12849
|
+
get scheduledOffsetsMs() {
|
|
12850
|
+
return this.configState.getLatestValue().scheduledOffsetsMs;
|
|
12851
|
+
}
|
|
12852
|
+
// Config API END //
|
|
12853
|
+
// State API START //
|
|
12854
|
+
get reminders() {
|
|
12855
|
+
return this.state.getLatestValue().reminders;
|
|
12856
|
+
}
|
|
12857
|
+
getFromState(messageId) {
|
|
12858
|
+
return this.reminders.get(messageId);
|
|
12859
|
+
}
|
|
12860
|
+
// API calls END //
|
|
12861
|
+
};
|
|
12862
|
+
// Timers API END //
|
|
12863
|
+
// WS event handling START //
|
|
12864
|
+
_ReminderManager.isReminderWsEventPayload = (event) => !!event.reminder && (event.type.startsWith("reminder.") || event.type === "notification.reminder_due");
|
|
12865
|
+
var ReminderManager = _ReminderManager;
|
|
12866
|
+
|
|
12227
12867
|
// src/client.ts
|
|
12228
12868
|
function isString3(x) {
|
|
12229
12869
|
return typeof x === "string" || x instanceof String;
|
|
@@ -12239,6 +12879,9 @@ var StreamChat = class _StreamChat {
|
|
|
12239
12879
|
});
|
|
12240
12880
|
this._getConnectionID = () => this.wsConnection?.connectionID || this.wsFallback?.connectionID;
|
|
12241
12881
|
this._hasConnectionID = () => Boolean(this._getConnectionID());
|
|
12882
|
+
this.setMessageComposerSetupFunction = (setupFunction) => {
|
|
12883
|
+
this._messageComposerSetupState.partialNext({ setupFunction });
|
|
12884
|
+
};
|
|
12242
12885
|
/**
|
|
12243
12886
|
* connectUser - Set the current user and open a WebSocket connection
|
|
12244
12887
|
*
|
|
@@ -12807,9 +13450,6 @@ var StreamChat = class _StreamChat {
|
|
|
12807
13450
|
device: this.options.device,
|
|
12808
13451
|
client_request_id
|
|
12809
13452
|
});
|
|
12810
|
-
this.setMessageComposerSetupFunction = (setupFunction) => {
|
|
12811
|
-
this._messageComposerSetupState.partialNext({ setupFunction });
|
|
12812
|
-
};
|
|
12813
13453
|
this.key = key;
|
|
12814
13454
|
this.listeners = {};
|
|
12815
13455
|
this.state = new ClientState({ client: this });
|
|
@@ -12864,6 +13504,7 @@ var StreamChat = class _StreamChat {
|
|
|
12864
13504
|
this.recoverStateOnReconnect = this.options.recoverStateOnReconnect;
|
|
12865
13505
|
this.threads = new ThreadManager({ client: this });
|
|
12866
13506
|
this.polls = new PollManager({ client: this });
|
|
13507
|
+
this.reminders = new ReminderManager({ client: this });
|
|
12867
13508
|
}
|
|
12868
13509
|
static getInstance(key, secretOrOptions, options) {
|
|
12869
13510
|
if (!_StreamChat._instance) {
|
|
@@ -12999,15 +13640,15 @@ var StreamChat = class _StreamChat {
|
|
|
12999
13640
|
* @param {string} userID User ID. If user has no devices, it will error
|
|
13000
13641
|
* @param {TestPushDataInput} [data] Overrides for push templates/message used
|
|
13001
13642
|
* IE: {
|
|
13002
|
-
|
|
13003
|
-
|
|
13004
|
-
|
|
13005
|
-
|
|
13006
|
-
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
|
|
13010
|
-
|
|
13643
|
+
messageID: 'id-of-message', // will error if message does not exist
|
|
13644
|
+
apnTemplate: '{}', // if app doesn't have apn configured it will error
|
|
13645
|
+
firebaseTemplate: '{}', // if app doesn't have firebase configured it will error
|
|
13646
|
+
firebaseDataTemplate: '{}', // if app doesn't have firebase configured it will error
|
|
13647
|
+
skipDevices: true, // skip config/device checks and sending to real devices
|
|
13648
|
+
pushProviderName: 'staging' // one of your configured push providers
|
|
13649
|
+
pushProviderType: 'apn' // one of supported provider types
|
|
13650
|
+
}
|
|
13651
|
+
*/
|
|
13011
13652
|
async testPushSettings(userID, data = {}) {
|
|
13012
13653
|
return await this.post(this.baseURL + "/check_push", {
|
|
13013
13654
|
user_id: userID,
|
|
@@ -13025,10 +13666,10 @@ var StreamChat = class _StreamChat {
|
|
|
13025
13666
|
*
|
|
13026
13667
|
* @param {TestSQSDataInput} [data] Overrides SQS settings for testing if needed
|
|
13027
13668
|
* IE: {
|
|
13028
|
-
|
|
13029
|
-
|
|
13030
|
-
|
|
13031
|
-
|
|
13669
|
+
sqs_key: 'auth_key',
|
|
13670
|
+
sqs_secret: 'auth_secret',
|
|
13671
|
+
sqs_url: 'url_to_queue',
|
|
13672
|
+
}
|
|
13032
13673
|
*/
|
|
13033
13674
|
async testSQSSettings(data = {}) {
|
|
13034
13675
|
return await this.post(this.baseURL + "/check_sqs", data);
|
|
@@ -13038,10 +13679,10 @@ var StreamChat = class _StreamChat {
|
|
|
13038
13679
|
*
|
|
13039
13680
|
* @param {TestSNSDataInput} [data] Overrides SNS settings for testing if needed
|
|
13040
13681
|
* IE: {
|
|
13041
|
-
|
|
13042
|
-
|
|
13043
|
-
|
|
13044
|
-
|
|
13682
|
+
sns_key: 'auth_key',
|
|
13683
|
+
sns_secret: 'auth_secret',
|
|
13684
|
+
sns_topic_arn: 'topic_to_publish_to',
|
|
13685
|
+
}
|
|
13045
13686
|
*/
|
|
13046
13687
|
async testSNSSettings(data = {}) {
|
|
13047
13688
|
return await this.post(this.baseURL + "/check_sns", data);
|
|
@@ -13522,6 +14163,7 @@ var StreamChat = class _StreamChat {
|
|
|
13522
14163
|
})
|
|
13523
14164
|
};
|
|
13524
14165
|
this.polls.hydratePollCache(channelState.messages, true);
|
|
14166
|
+
this.reminders.hydrateState(channelState.messages);
|
|
13525
14167
|
}
|
|
13526
14168
|
if (channelState.draft) {
|
|
13527
14169
|
c.messageComposer.initState({ composition: channelState.draft });
|
|
@@ -14442,7 +15084,7 @@ var StreamChat = class _StreamChat {
|
|
|
14442
15084
|
if (this.userAgent) {
|
|
14443
15085
|
return this.userAgent;
|
|
14444
15086
|
}
|
|
14445
|
-
const version = "9.
|
|
15087
|
+
const version = "9.5.0";
|
|
14446
15088
|
const clientBundle = "browser-cjs";
|
|
14447
15089
|
let userAgentString = "";
|
|
14448
15090
|
if (this.sdkIdentifier) {
|
|
@@ -15481,6 +16123,56 @@ var StreamChat = class _StreamChat {
|
|
|
15481
16123
|
};
|
|
15482
16124
|
return await this.post(this.baseURL + "/drafts/query", payload);
|
|
15483
16125
|
}
|
|
16126
|
+
/**
|
|
16127
|
+
* createReminder - Creates a reminder for a message
|
|
16128
|
+
*
|
|
16129
|
+
* @param {CreateReminderOptions} options The options for creating the reminder
|
|
16130
|
+
* @returns {Promise<ReminderAPIResponse>}
|
|
16131
|
+
*/
|
|
16132
|
+
async createReminder({ messageId, ...options }) {
|
|
16133
|
+
return await this.post(
|
|
16134
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
16135
|
+
options
|
|
16136
|
+
);
|
|
16137
|
+
}
|
|
16138
|
+
/**
|
|
16139
|
+
* updateReminder - Updates an existing reminder for a message
|
|
16140
|
+
*
|
|
16141
|
+
* @param {UpdateReminderOptions} options The options for updating the reminder
|
|
16142
|
+
* @returns {Promise<ReminderAPIResponse>}
|
|
16143
|
+
*/
|
|
16144
|
+
async updateReminder({ messageId, ...options }) {
|
|
16145
|
+
return await this.patch(
|
|
16146
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
16147
|
+
options
|
|
16148
|
+
);
|
|
16149
|
+
}
|
|
16150
|
+
/**
|
|
16151
|
+
* deleteReminder - Deletes a reminder for a message
|
|
16152
|
+
*
|
|
16153
|
+
* @param {string} messageId The ID of the message whose reminder to delete
|
|
16154
|
+
* @param {string} [userId] Optional user ID, required for server-side operations
|
|
16155
|
+
* @returns {Promise<APIResponse>}
|
|
16156
|
+
*/
|
|
16157
|
+
async deleteReminder(messageId, userId) {
|
|
16158
|
+
return await this.delete(
|
|
16159
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
16160
|
+
userId ? { user_id: userId } : {}
|
|
16161
|
+
);
|
|
16162
|
+
}
|
|
16163
|
+
/**
|
|
16164
|
+
* queryReminders - Queries reminders based on given filters
|
|
16165
|
+
*
|
|
16166
|
+
* @param {QueryRemindersOptions} options The options for querying reminders
|
|
16167
|
+
* @returns {Promise<QueryRemindersResponse>}
|
|
16168
|
+
*/
|
|
16169
|
+
async queryReminders({ filter: filter2, sort, ...rest } = {}) {
|
|
16170
|
+
return await this.post(`${this.baseURL}/reminders/query`, {
|
|
16171
|
+
filter_conditions: filter2,
|
|
16172
|
+
sort: sort && normalizeQuerySort(sort),
|
|
16173
|
+
...rest
|
|
16174
|
+
});
|
|
16175
|
+
}
|
|
15484
16176
|
};
|
|
15485
16177
|
|
|
15486
16178
|
// src/events.ts
|
|
@@ -15547,7 +16239,12 @@ var EVENT_MAP = {
|
|
|
15547
16239
|
"connection.changed": true,
|
|
15548
16240
|
"connection.recovered": true,
|
|
15549
16241
|
"transport.changed": true,
|
|
15550
|
-
"capabilities.changed": true
|
|
16242
|
+
"capabilities.changed": true,
|
|
16243
|
+
// Reminder events
|
|
16244
|
+
"reminder.created": true,
|
|
16245
|
+
"reminder.updated": true,
|
|
16246
|
+
"reminder.deleted": true,
|
|
16247
|
+
"notification.reminder_due": true
|
|
15551
16248
|
};
|
|
15552
16249
|
|
|
15553
16250
|
// src/permissions.ts
|