stream-chat 9.4.0 → 9.5.1
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 +663 -135
- package/dist/cjs/index.browser.cjs.map +4 -4
- package/dist/cjs/index.node.cjs +673 -136
- package/dist/cjs/index.node.cjs.map +4 -4
- package/dist/esm/index.js +663 -135
- package/dist/esm/index.js.map +4 -4
- package/dist/types/client.d.ts +53 -20
- 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/types.d.ts +43 -0
- package/package.json +1 -1
- package/src/channel.ts +2 -1
- package/src/client.ts +109 -40
- package/src/events.ts +6 -0
- package/src/index.ts +3 -1
- package/src/messageComposer/middleware/pollComposer/state.ts +4 -5
- 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/messageComposer/pollComposer.ts +3 -2
- 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/token_manager.ts +3 -1
- package/src/types.ts +88 -0
- 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,
|
|
@@ -208,6 +212,10 @@ __export(index_exports, {
|
|
|
208
212
|
PollComposerCompositionMiddlewareExecutor: () => PollComposerCompositionMiddlewareExecutor,
|
|
209
213
|
PollComposerStateMiddlewareExecutor: () => PollComposerStateMiddlewareExecutor,
|
|
210
214
|
PollManager: () => PollManager,
|
|
215
|
+
Reminder: () => Reminder,
|
|
216
|
+
ReminderManager: () => ReminderManager,
|
|
217
|
+
ReminderPaginator: () => ReminderPaginator,
|
|
218
|
+
ReminderTimer: () => ReminderTimer,
|
|
211
219
|
SearchController: () => SearchController,
|
|
212
220
|
Segment: () => Segment,
|
|
213
221
|
StableWSConnection: () => StableWSConnection,
|
|
@@ -295,7 +303,8 @@ __export(index_exports, {
|
|
|
295
303
|
readFileAsArrayBuffer: () => readFileAsArrayBuffer,
|
|
296
304
|
removeDiacritics: () => removeDiacritics,
|
|
297
305
|
replaceWordWithEntity: () => replaceWordWithEntity,
|
|
298
|
-
textIsEmpty: () => textIsEmpty
|
|
306
|
+
textIsEmpty: () => textIsEmpty,
|
|
307
|
+
timeLeftMs: () => timeLeftMs
|
|
299
308
|
});
|
|
300
309
|
module.exports = __toCommonJS(index_exports);
|
|
301
310
|
|
|
@@ -5431,15 +5440,14 @@ var pollStateChangeValidators = {
|
|
|
5431
5440
|
return { max_votes_allowed: "Type a number from 2 to 10" };
|
|
5432
5441
|
return { max_votes_allowed: void 0 };
|
|
5433
5442
|
},
|
|
5434
|
-
options: ({ value }) => {
|
|
5443
|
+
options: ({ value: options }) => {
|
|
5435
5444
|
const errors = {};
|
|
5436
5445
|
const seenOptions = /* @__PURE__ */ new Set();
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
if (seenOptions.has(trimmedText)) {
|
|
5446
|
+
options.forEach((option) => {
|
|
5447
|
+
if (seenOptions.has(option.text) && option.text.length) {
|
|
5440
5448
|
errors[option.id] = "Option already exists";
|
|
5441
5449
|
} else {
|
|
5442
|
-
seenOptions.add(
|
|
5450
|
+
seenOptions.add(option.text);
|
|
5443
5451
|
}
|
|
5444
5452
|
});
|
|
5445
5453
|
return Object.keys(errors).length > 0 ? { options: errors } : { options: void 0 };
|
|
@@ -5792,13 +5800,13 @@ var PollComposer = class {
|
|
|
5792
5800
|
}
|
|
5793
5801
|
get canCreatePoll() {
|
|
5794
5802
|
const { data, errors } = this.state.getLatestValue();
|
|
5795
|
-
const
|
|
5803
|
+
const hasAtLeastOneNonEmptyOption = data.options.filter((o) => !!o.text.trim()).length > 0;
|
|
5796
5804
|
const hasName = !!data.name;
|
|
5797
5805
|
const maxVotesAllowedNumber = parseInt(
|
|
5798
5806
|
data.max_votes_allowed?.match(VALID_MAX_VOTES_VALUE_REGEX)?.[0] || ""
|
|
5799
5807
|
);
|
|
5800
5808
|
const validMaxVotesAllowed = data.max_votes_allowed === "" || !!maxVotesAllowedNumber && (2 <= maxVotesAllowedNumber || maxVotesAllowedNumber <= 10);
|
|
5801
|
-
return
|
|
5809
|
+
return hasAtLeastOneNonEmptyOption && hasName && validMaxVotesAllowed && Object.values(errors).filter((errorText) => !!errorText).length === 0;
|
|
5802
5810
|
}
|
|
5803
5811
|
};
|
|
5804
5812
|
|
|
@@ -6241,7 +6249,7 @@ var MessageDraftComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
|
6241
6249
|
}
|
|
6242
6250
|
};
|
|
6243
6251
|
|
|
6244
|
-
// src/
|
|
6252
|
+
// src/search/BaseSearchSource.ts
|
|
6245
6253
|
var DEFAULT_SEARCH_SOURCE_OPTIONS = {
|
|
6246
6254
|
debounceMs: 300,
|
|
6247
6255
|
pageSize: 10
|
|
@@ -6367,6 +6375,112 @@ var BaseSearchSource = class {
|
|
|
6367
6375
|
this.activate();
|
|
6368
6376
|
}
|
|
6369
6377
|
};
|
|
6378
|
+
|
|
6379
|
+
// src/search/SearchController.ts
|
|
6380
|
+
var SearchController = class {
|
|
6381
|
+
constructor({ config, sources } = {}) {
|
|
6382
|
+
this.addSource = (source) => {
|
|
6383
|
+
this.state.partialNext({
|
|
6384
|
+
sources: [...this.sources, source]
|
|
6385
|
+
});
|
|
6386
|
+
};
|
|
6387
|
+
this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
|
|
6388
|
+
this.removeSource = (sourceType) => {
|
|
6389
|
+
const newSources = this.sources.filter((s) => s.type !== sourceType);
|
|
6390
|
+
if (newSources.length === this.sources.length) return;
|
|
6391
|
+
this.state.partialNext({ sources: newSources });
|
|
6392
|
+
};
|
|
6393
|
+
this.activateSource = (sourceType) => {
|
|
6394
|
+
const source = this.getSource(sourceType);
|
|
6395
|
+
if (!source || source.isActive) return;
|
|
6396
|
+
if (this.config.keepSingleActiveSource) {
|
|
6397
|
+
this.sources.forEach((s) => {
|
|
6398
|
+
if (s.type !== sourceType) {
|
|
6399
|
+
s.deactivate();
|
|
6400
|
+
}
|
|
6401
|
+
});
|
|
6402
|
+
}
|
|
6403
|
+
source.activate();
|
|
6404
|
+
this.state.partialNext({ sources: [...this.sources] });
|
|
6405
|
+
};
|
|
6406
|
+
this.deactivateSource = (sourceType) => {
|
|
6407
|
+
const source = this.getSource(sourceType);
|
|
6408
|
+
if (!source?.isActive) return;
|
|
6409
|
+
if (this.activeSources.length === 1) return;
|
|
6410
|
+
source.deactivate();
|
|
6411
|
+
this.state.partialNext({ sources: [...this.sources] });
|
|
6412
|
+
};
|
|
6413
|
+
this.activate = () => {
|
|
6414
|
+
if (!this.activeSources.length) {
|
|
6415
|
+
const sourcesToActivate = this.config.keepSingleActiveSource ? this.sources.slice(0, 1) : this.sources;
|
|
6416
|
+
sourcesToActivate.forEach((s) => s.activate());
|
|
6417
|
+
}
|
|
6418
|
+
if (this.isActive) return;
|
|
6419
|
+
this.state.partialNext({ isActive: true });
|
|
6420
|
+
};
|
|
6421
|
+
this.search = async (searchQuery) => {
|
|
6422
|
+
const searchedSources = this.activeSources;
|
|
6423
|
+
this.state.partialNext({
|
|
6424
|
+
searchQuery
|
|
6425
|
+
});
|
|
6426
|
+
await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
|
|
6427
|
+
};
|
|
6428
|
+
this.cancelSearchQueries = () => {
|
|
6429
|
+
this.activeSources.forEach((s) => s.cancelScheduledQuery());
|
|
6430
|
+
};
|
|
6431
|
+
this.clear = () => {
|
|
6432
|
+
this.cancelSearchQueries();
|
|
6433
|
+
this.sources.forEach(
|
|
6434
|
+
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
6435
|
+
);
|
|
6436
|
+
this.state.next((current) => ({
|
|
6437
|
+
...current,
|
|
6438
|
+
isActive: true,
|
|
6439
|
+
queriesInProgress: [],
|
|
6440
|
+
searchQuery: ""
|
|
6441
|
+
}));
|
|
6442
|
+
};
|
|
6443
|
+
this.exit = () => {
|
|
6444
|
+
this.cancelSearchQueries();
|
|
6445
|
+
this.sources.forEach(
|
|
6446
|
+
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
6447
|
+
);
|
|
6448
|
+
this.state.next((current) => ({
|
|
6449
|
+
...current,
|
|
6450
|
+
isActive: false,
|
|
6451
|
+
queriesInProgress: [],
|
|
6452
|
+
searchQuery: ""
|
|
6453
|
+
}));
|
|
6454
|
+
};
|
|
6455
|
+
this.state = new StateStore({
|
|
6456
|
+
isActive: false,
|
|
6457
|
+
searchQuery: "",
|
|
6458
|
+
sources: sources ?? []
|
|
6459
|
+
});
|
|
6460
|
+
this._internalState = new StateStore({});
|
|
6461
|
+
this.config = { keepSingleActiveSource: true, ...config };
|
|
6462
|
+
}
|
|
6463
|
+
get hasNext() {
|
|
6464
|
+
return this.sources.some((source) => source.hasNext);
|
|
6465
|
+
}
|
|
6466
|
+
get sources() {
|
|
6467
|
+
return this.state.getLatestValue().sources;
|
|
6468
|
+
}
|
|
6469
|
+
get activeSources() {
|
|
6470
|
+
return this.state.getLatestValue().sources.filter((s) => s.isActive);
|
|
6471
|
+
}
|
|
6472
|
+
get isActive() {
|
|
6473
|
+
return this.state.getLatestValue().isActive;
|
|
6474
|
+
}
|
|
6475
|
+
get searchQuery() {
|
|
6476
|
+
return this.state.getLatestValue().searchQuery;
|
|
6477
|
+
}
|
|
6478
|
+
get searchSourceTypes() {
|
|
6479
|
+
return this.sources.map((s) => s.type);
|
|
6480
|
+
}
|
|
6481
|
+
};
|
|
6482
|
+
|
|
6483
|
+
// src/search/UserSearchSource.ts
|
|
6370
6484
|
var UserSearchSource = class extends BaseSearchSource {
|
|
6371
6485
|
constructor(client, options) {
|
|
6372
6486
|
super(options);
|
|
@@ -6390,6 +6504,8 @@ var UserSearchSource = class extends BaseSearchSource {
|
|
|
6390
6504
|
return items.filter((u) => u.id !== this.client.user?.id);
|
|
6391
6505
|
}
|
|
6392
6506
|
};
|
|
6507
|
+
|
|
6508
|
+
// src/search/ChannelSearchSource.ts
|
|
6393
6509
|
var ChannelSearchSource = class extends BaseSearchSource {
|
|
6394
6510
|
constructor(client, options) {
|
|
6395
6511
|
super(options);
|
|
@@ -6411,6 +6527,8 @@ var ChannelSearchSource = class extends BaseSearchSource {
|
|
|
6411
6527
|
return items;
|
|
6412
6528
|
}
|
|
6413
6529
|
};
|
|
6530
|
+
|
|
6531
|
+
// src/search/MessageSearchSource.ts
|
|
6414
6532
|
var MessageSearchSource = class extends BaseSearchSource {
|
|
6415
6533
|
constructor(client, options) {
|
|
6416
6534
|
super(options);
|
|
@@ -6471,108 +6589,6 @@ var MessageSearchSource = class extends BaseSearchSource {
|
|
|
6471
6589
|
return items;
|
|
6472
6590
|
}
|
|
6473
6591
|
};
|
|
6474
|
-
var SearchController = class {
|
|
6475
|
-
constructor({ config, sources } = {}) {
|
|
6476
|
-
this.addSource = (source) => {
|
|
6477
|
-
this.state.partialNext({
|
|
6478
|
-
sources: [...this.sources, source]
|
|
6479
|
-
});
|
|
6480
|
-
};
|
|
6481
|
-
this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
|
|
6482
|
-
this.removeSource = (sourceType) => {
|
|
6483
|
-
const newSources = this.sources.filter((s) => s.type !== sourceType);
|
|
6484
|
-
if (newSources.length === this.sources.length) return;
|
|
6485
|
-
this.state.partialNext({ sources: newSources });
|
|
6486
|
-
};
|
|
6487
|
-
this.activateSource = (sourceType) => {
|
|
6488
|
-
const source = this.getSource(sourceType);
|
|
6489
|
-
if (!source || source.isActive) return;
|
|
6490
|
-
if (this.config.keepSingleActiveSource) {
|
|
6491
|
-
this.sources.forEach((s) => {
|
|
6492
|
-
if (s.type !== sourceType) {
|
|
6493
|
-
s.deactivate();
|
|
6494
|
-
}
|
|
6495
|
-
});
|
|
6496
|
-
}
|
|
6497
|
-
source.activate();
|
|
6498
|
-
this.state.partialNext({ sources: [...this.sources] });
|
|
6499
|
-
};
|
|
6500
|
-
this.deactivateSource = (sourceType) => {
|
|
6501
|
-
const source = this.getSource(sourceType);
|
|
6502
|
-
if (!source?.isActive) return;
|
|
6503
|
-
if (this.activeSources.length === 1) return;
|
|
6504
|
-
source.deactivate();
|
|
6505
|
-
this.state.partialNext({ sources: [...this.sources] });
|
|
6506
|
-
};
|
|
6507
|
-
this.activate = () => {
|
|
6508
|
-
if (!this.activeSources.length) {
|
|
6509
|
-
const sourcesToActivate = this.config.keepSingleActiveSource ? this.sources.slice(0, 1) : this.sources;
|
|
6510
|
-
sourcesToActivate.forEach((s) => s.activate());
|
|
6511
|
-
}
|
|
6512
|
-
if (this.isActive) return;
|
|
6513
|
-
this.state.partialNext({ isActive: true });
|
|
6514
|
-
};
|
|
6515
|
-
this.search = async (searchQuery) => {
|
|
6516
|
-
const searchedSources = this.activeSources;
|
|
6517
|
-
this.state.partialNext({
|
|
6518
|
-
searchQuery
|
|
6519
|
-
});
|
|
6520
|
-
await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
|
|
6521
|
-
};
|
|
6522
|
-
this.cancelSearchQueries = () => {
|
|
6523
|
-
this.activeSources.forEach((s) => s.cancelScheduledQuery());
|
|
6524
|
-
};
|
|
6525
|
-
this.clear = () => {
|
|
6526
|
-
this.cancelSearchQueries();
|
|
6527
|
-
this.sources.forEach(
|
|
6528
|
-
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
6529
|
-
);
|
|
6530
|
-
this.state.next((current) => ({
|
|
6531
|
-
...current,
|
|
6532
|
-
isActive: true,
|
|
6533
|
-
queriesInProgress: [],
|
|
6534
|
-
searchQuery: ""
|
|
6535
|
-
}));
|
|
6536
|
-
};
|
|
6537
|
-
this.exit = () => {
|
|
6538
|
-
this.cancelSearchQueries();
|
|
6539
|
-
this.sources.forEach(
|
|
6540
|
-
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
6541
|
-
);
|
|
6542
|
-
this.state.next((current) => ({
|
|
6543
|
-
...current,
|
|
6544
|
-
isActive: false,
|
|
6545
|
-
queriesInProgress: [],
|
|
6546
|
-
searchQuery: ""
|
|
6547
|
-
}));
|
|
6548
|
-
};
|
|
6549
|
-
this.state = new StateStore({
|
|
6550
|
-
isActive: false,
|
|
6551
|
-
searchQuery: "",
|
|
6552
|
-
sources: sources ?? []
|
|
6553
|
-
});
|
|
6554
|
-
this._internalState = new StateStore({});
|
|
6555
|
-
this.config = { keepSingleActiveSource: true, ...config };
|
|
6556
|
-
}
|
|
6557
|
-
get hasNext() {
|
|
6558
|
-
return this.sources.some((source) => source.hasNext);
|
|
6559
|
-
}
|
|
6560
|
-
get sources() {
|
|
6561
|
-
return this.state.getLatestValue().sources;
|
|
6562
|
-
}
|
|
6563
|
-
get activeSources() {
|
|
6564
|
-
return this.state.getLatestValue().sources.filter((s) => s.isActive);
|
|
6565
|
-
}
|
|
6566
|
-
get isActive() {
|
|
6567
|
-
return this.state.getLatestValue().isActive;
|
|
6568
|
-
}
|
|
6569
|
-
get searchQuery() {
|
|
6570
|
-
return this.state.getLatestValue().searchQuery;
|
|
6571
|
-
}
|
|
6572
|
-
get searchSourceTypes() {
|
|
6573
|
-
return this.sources.map((s) => s.type);
|
|
6574
|
-
}
|
|
6575
|
-
};
|
|
6576
6592
|
|
|
6577
6593
|
// src/messageComposer/middleware/textComposer/textMiddlewareUtils.ts
|
|
6578
6594
|
var getTriggerCharWithToken = ({
|
|
@@ -9351,6 +9367,7 @@ var Channel = class {
|
|
|
9351
9367
|
})
|
|
9352
9368
|
};
|
|
9353
9369
|
this.getClient().polls.hydratePollCache(state.messages, true);
|
|
9370
|
+
this.getClient().reminders.hydrateState(state.messages);
|
|
9354
9371
|
if (state.draft) {
|
|
9355
9372
|
this.messageComposer.initState({ composition: state.draft });
|
|
9356
9373
|
}
|
|
@@ -10642,7 +10659,9 @@ var TokenManager = class {
|
|
|
10642
10659
|
try {
|
|
10643
10660
|
this.token = await this.tokenProvider();
|
|
10644
10661
|
} catch (e) {
|
|
10645
|
-
return reject(
|
|
10662
|
+
return reject(
|
|
10663
|
+
new Error(`Call to tokenProvider failed with message: ${e}`, { cause: e })
|
|
10664
|
+
);
|
|
10646
10665
|
}
|
|
10647
10666
|
resolve(this.token);
|
|
10648
10667
|
}
|
|
@@ -12392,6 +12411,458 @@ var NotificationManager = class {
|
|
|
12392
12411
|
}
|
|
12393
12412
|
};
|
|
12394
12413
|
|
|
12414
|
+
// src/reminders/ReminderTimer.ts
|
|
12415
|
+
var oneMinute = 60 * 1e3;
|
|
12416
|
+
var oneHour = 60 * oneMinute;
|
|
12417
|
+
var oneDay = 24 * oneHour;
|
|
12418
|
+
var oneWeek = 7 * oneDay;
|
|
12419
|
+
var GROUP_BOUNDS = {
|
|
12420
|
+
minute: { lower: oneMinute, upper: oneHour },
|
|
12421
|
+
hour: { lower: oneHour, upper: oneDay },
|
|
12422
|
+
day: { lower: oneDay, upper: oneWeek }
|
|
12423
|
+
};
|
|
12424
|
+
var DEFAULT_STOP_REFRESH_BOUNDARY_MS = 2 * oneWeek;
|
|
12425
|
+
var ReminderTimer = class {
|
|
12426
|
+
constructor({
|
|
12427
|
+
reminder,
|
|
12428
|
+
config
|
|
12429
|
+
}) {
|
|
12430
|
+
this.timeout = null;
|
|
12431
|
+
this.stopRefreshBoundaryMs = DEFAULT_STOP_REFRESH_BOUNDARY_MS;
|
|
12432
|
+
this.getRefreshIntervalLength = () => {
|
|
12433
|
+
if (!this.reminder.remindAt) return null;
|
|
12434
|
+
const distanceFromDeadlineMs = Math.abs(timeLeftMs(this.reminder.remindAt.getTime()));
|
|
12435
|
+
let refreshInterval;
|
|
12436
|
+
if (distanceFromDeadlineMs === 0) {
|
|
12437
|
+
refreshInterval = oneMinute;
|
|
12438
|
+
} else if (distanceFromDeadlineMs < GROUP_BOUNDS.minute.lower) {
|
|
12439
|
+
refreshInterval = distanceFromDeadlineMs;
|
|
12440
|
+
} else if (distanceFromDeadlineMs <= GROUP_BOUNDS.minute.upper) {
|
|
12441
|
+
refreshInterval = oneMinute;
|
|
12442
|
+
} else if (distanceFromDeadlineMs <= GROUP_BOUNDS.hour.upper) {
|
|
12443
|
+
refreshInterval = oneHour;
|
|
12444
|
+
} else {
|
|
12445
|
+
refreshInterval = oneDay;
|
|
12446
|
+
}
|
|
12447
|
+
return refreshInterval;
|
|
12448
|
+
};
|
|
12449
|
+
this.init = () => {
|
|
12450
|
+
if (!this.reminder.remindAt) return null;
|
|
12451
|
+
const timeoutLength = this.getRefreshIntervalLength();
|
|
12452
|
+
if (timeoutLength === null) return null;
|
|
12453
|
+
const boundaryTimestamp = this.reminder.remindAt?.getTime() + this.stopRefreshBoundaryMs;
|
|
12454
|
+
const timeLeftToBoundary = boundaryTimestamp - Date.now();
|
|
12455
|
+
if (timeLeftToBoundary <= 0) {
|
|
12456
|
+
this.timeout = null;
|
|
12457
|
+
return;
|
|
12458
|
+
}
|
|
12459
|
+
if (this.timeout) clearTimeout(this.timeout);
|
|
12460
|
+
this.timeout = setTimeout(() => {
|
|
12461
|
+
this.reminder.refreshTimeLeft();
|
|
12462
|
+
this.init();
|
|
12463
|
+
}, timeoutLength);
|
|
12464
|
+
};
|
|
12465
|
+
this.clear = () => {
|
|
12466
|
+
if (this.timeout) {
|
|
12467
|
+
clearInterval(this.timeout);
|
|
12468
|
+
this.timeout = null;
|
|
12469
|
+
}
|
|
12470
|
+
};
|
|
12471
|
+
this.reminder = reminder;
|
|
12472
|
+
if (typeof config?.stopRefreshBoundaryMs === "number") {
|
|
12473
|
+
this.stopRefreshBoundaryMs = config.stopRefreshBoundaryMs;
|
|
12474
|
+
}
|
|
12475
|
+
}
|
|
12476
|
+
};
|
|
12477
|
+
|
|
12478
|
+
// src/reminders/Reminder.ts
|
|
12479
|
+
var timeLeftMs = (remindAt) => remindAt - (/* @__PURE__ */ new Date()).getTime();
|
|
12480
|
+
var _Reminder = class _Reminder {
|
|
12481
|
+
constructor({ data, config }) {
|
|
12482
|
+
this.setState = (data) => {
|
|
12483
|
+
this.state.next((current) => {
|
|
12484
|
+
const newState = { ...current, ..._Reminder.toStateValue(data) };
|
|
12485
|
+
if (newState.remind_at) {
|
|
12486
|
+
newState.timeLeftMs = timeLeftMs(newState.remind_at.getTime());
|
|
12487
|
+
}
|
|
12488
|
+
return newState;
|
|
12489
|
+
});
|
|
12490
|
+
if (data.remind_at) {
|
|
12491
|
+
this.initTimer();
|
|
12492
|
+
} else if (!data.remind_at) {
|
|
12493
|
+
this.clearTimer();
|
|
12494
|
+
}
|
|
12495
|
+
};
|
|
12496
|
+
this.refreshTimeLeft = () => {
|
|
12497
|
+
if (!this.remindAt) return;
|
|
12498
|
+
this.state.partialNext({ timeLeftMs: timeLeftMs(this.remindAt.getTime()) });
|
|
12499
|
+
};
|
|
12500
|
+
this.initTimer = () => {
|
|
12501
|
+
this.timer.init();
|
|
12502
|
+
};
|
|
12503
|
+
this.clearTimer = () => {
|
|
12504
|
+
this.timer.clear();
|
|
12505
|
+
};
|
|
12506
|
+
this.state = new StateStore(_Reminder.toStateValue(data));
|
|
12507
|
+
this.timer = new ReminderTimer({ reminder: this, config });
|
|
12508
|
+
this.initTimer();
|
|
12509
|
+
}
|
|
12510
|
+
get id() {
|
|
12511
|
+
return this.state.getLatestValue().message_id;
|
|
12512
|
+
}
|
|
12513
|
+
get remindAt() {
|
|
12514
|
+
return this.state.getLatestValue().remind_at;
|
|
12515
|
+
}
|
|
12516
|
+
get timeLeftMs() {
|
|
12517
|
+
return this.state.getLatestValue().timeLeftMs;
|
|
12518
|
+
}
|
|
12519
|
+
};
|
|
12520
|
+
_Reminder.toStateValue = (data) => ({
|
|
12521
|
+
...data,
|
|
12522
|
+
created_at: new Date(data.created_at),
|
|
12523
|
+
message: data.message || null,
|
|
12524
|
+
remind_at: data.remind_at ? new Date(data.remind_at) : null,
|
|
12525
|
+
timeLeftMs: data.remind_at ? timeLeftMs(new Date(data.remind_at).getTime()) : null,
|
|
12526
|
+
updated_at: new Date(data.updated_at),
|
|
12527
|
+
user: data.user || null
|
|
12528
|
+
});
|
|
12529
|
+
var Reminder = _Reminder;
|
|
12530
|
+
|
|
12531
|
+
// src/pagination/BasePaginator.ts
|
|
12532
|
+
var DEFAULT_PAGINATION_OPTIONS = {
|
|
12533
|
+
debounceMs: 300,
|
|
12534
|
+
pageSize: 10
|
|
12535
|
+
};
|
|
12536
|
+
var BasePaginator = class {
|
|
12537
|
+
constructor(options) {
|
|
12538
|
+
this._isCursorPagination = false;
|
|
12539
|
+
this.setDebounceOptions = ({ debounceMs }) => {
|
|
12540
|
+
this._executeQueryDebounced = debounce(this.executeQuery.bind(this), debounceMs);
|
|
12541
|
+
};
|
|
12542
|
+
this.canExecuteQuery = (direction) => !this.isLoading && direction === "next" && this.hasNext || direction === "prev" && this.hasPrev;
|
|
12543
|
+
this.next = () => this.executeQuery({ direction: "next" });
|
|
12544
|
+
this.prev = () => this.executeQuery({ direction: "prev" });
|
|
12545
|
+
this.nextDebounced = () => {
|
|
12546
|
+
this._executeQueryDebounced({ direction: "next" });
|
|
12547
|
+
};
|
|
12548
|
+
this.prevDebounced = () => {
|
|
12549
|
+
this._executeQueryDebounced({ direction: "prev" });
|
|
12550
|
+
};
|
|
12551
|
+
const { debounceMs, pageSize } = { ...DEFAULT_PAGINATION_OPTIONS, ...options };
|
|
12552
|
+
this.pageSize = pageSize;
|
|
12553
|
+
this.state = new StateStore(this.initialState);
|
|
12554
|
+
this.setDebounceOptions({ debounceMs });
|
|
12555
|
+
}
|
|
12556
|
+
get lastQueryError() {
|
|
12557
|
+
return this.state.getLatestValue().lastQueryError;
|
|
12558
|
+
}
|
|
12559
|
+
get hasNext() {
|
|
12560
|
+
return this.state.getLatestValue().hasNext;
|
|
12561
|
+
}
|
|
12562
|
+
get hasPrev() {
|
|
12563
|
+
return this.state.getLatestValue().hasPrev;
|
|
12564
|
+
}
|
|
12565
|
+
get hasResults() {
|
|
12566
|
+
return Array.isArray(this.state.getLatestValue().items);
|
|
12567
|
+
}
|
|
12568
|
+
get isLoading() {
|
|
12569
|
+
return this.state.getLatestValue().isLoading;
|
|
12570
|
+
}
|
|
12571
|
+
get initialState() {
|
|
12572
|
+
return {
|
|
12573
|
+
hasNext: true,
|
|
12574
|
+
hasPrev: true,
|
|
12575
|
+
//todo: check if optimistic value does not cause problems in UI
|
|
12576
|
+
isLoading: false,
|
|
12577
|
+
items: void 0,
|
|
12578
|
+
lastQueryError: void 0,
|
|
12579
|
+
cursor: void 0,
|
|
12580
|
+
offset: 0
|
|
12581
|
+
};
|
|
12582
|
+
}
|
|
12583
|
+
get items() {
|
|
12584
|
+
return this.state.getLatestValue().items;
|
|
12585
|
+
}
|
|
12586
|
+
get cursor() {
|
|
12587
|
+
return this.state.getLatestValue().cursor;
|
|
12588
|
+
}
|
|
12589
|
+
get offset() {
|
|
12590
|
+
return this.state.getLatestValue().offset;
|
|
12591
|
+
}
|
|
12592
|
+
getStateBeforeFirstQuery() {
|
|
12593
|
+
return {
|
|
12594
|
+
...this.initialState,
|
|
12595
|
+
isLoading: true
|
|
12596
|
+
};
|
|
12597
|
+
}
|
|
12598
|
+
getStateAfterQuery(stateUpdate, isFirstPage) {
|
|
12599
|
+
const current = this.state.getLatestValue();
|
|
12600
|
+
return {
|
|
12601
|
+
...current,
|
|
12602
|
+
lastQueryError: void 0,
|
|
12603
|
+
// reset lastQueryError that can be overridden by the stateUpdate
|
|
12604
|
+
...stateUpdate,
|
|
12605
|
+
isLoading: false,
|
|
12606
|
+
items: isFirstPage ? stateUpdate.items : [...this.items ?? [], ...stateUpdate.items || []]
|
|
12607
|
+
};
|
|
12608
|
+
}
|
|
12609
|
+
async executeQuery({ direction }) {
|
|
12610
|
+
if (!this.canExecuteQuery(direction)) return;
|
|
12611
|
+
const isFirstPage = typeof this.items === "undefined";
|
|
12612
|
+
if (isFirstPage) {
|
|
12613
|
+
this.state.next(this.getStateBeforeFirstQuery());
|
|
12614
|
+
} else {
|
|
12615
|
+
this.state.partialNext({ isLoading: true });
|
|
12616
|
+
}
|
|
12617
|
+
const stateUpdate = {};
|
|
12618
|
+
try {
|
|
12619
|
+
const results = await this.query({ direction });
|
|
12620
|
+
if (!results) return;
|
|
12621
|
+
const { items, next, prev } = results;
|
|
12622
|
+
if (isFirstPage && (next || prev)) {
|
|
12623
|
+
this._isCursorPagination = true;
|
|
12624
|
+
}
|
|
12625
|
+
if (this._isCursorPagination) {
|
|
12626
|
+
stateUpdate.cursor = { next: next || null, prev: prev || null };
|
|
12627
|
+
stateUpdate.hasNext = !!next;
|
|
12628
|
+
stateUpdate.hasPrev = !!prev;
|
|
12629
|
+
} else {
|
|
12630
|
+
stateUpdate.offset = (this.offset ?? 0) + items.length;
|
|
12631
|
+
stateUpdate.hasNext = items.length === this.pageSize;
|
|
12632
|
+
}
|
|
12633
|
+
stateUpdate.items = await this.filterQueryResults(items);
|
|
12634
|
+
} catch (e) {
|
|
12635
|
+
stateUpdate.lastQueryError = e;
|
|
12636
|
+
} finally {
|
|
12637
|
+
this.state.next(this.getStateAfterQuery(stateUpdate, isFirstPage));
|
|
12638
|
+
}
|
|
12639
|
+
}
|
|
12640
|
+
cancelScheduledQuery() {
|
|
12641
|
+
this._executeQueryDebounced.cancel();
|
|
12642
|
+
}
|
|
12643
|
+
resetState() {
|
|
12644
|
+
this.state.next(this.initialState);
|
|
12645
|
+
}
|
|
12646
|
+
};
|
|
12647
|
+
|
|
12648
|
+
// src/pagination/ReminderPaginator.ts
|
|
12649
|
+
var ReminderPaginator = class extends BasePaginator {
|
|
12650
|
+
constructor(client, options) {
|
|
12651
|
+
super(options);
|
|
12652
|
+
this.query = async ({
|
|
12653
|
+
direction
|
|
12654
|
+
}) => {
|
|
12655
|
+
const cursor = this.cursor?.[direction];
|
|
12656
|
+
const {
|
|
12657
|
+
reminders: items,
|
|
12658
|
+
next,
|
|
12659
|
+
prev
|
|
12660
|
+
} = await this.client.queryReminders({
|
|
12661
|
+
filter: this.filters,
|
|
12662
|
+
sort: this.sort,
|
|
12663
|
+
limit: this.pageSize,
|
|
12664
|
+
[direction]: cursor
|
|
12665
|
+
});
|
|
12666
|
+
return { items, next, prev };
|
|
12667
|
+
};
|
|
12668
|
+
this.filterQueryResults = (items) => items;
|
|
12669
|
+
this.client = client;
|
|
12670
|
+
}
|
|
12671
|
+
};
|
|
12672
|
+
|
|
12673
|
+
// src/reminders/ReminderManager.ts
|
|
12674
|
+
var oneMinute2 = 60 * 1e3;
|
|
12675
|
+
var oneHour2 = 60 * oneMinute2;
|
|
12676
|
+
var oneDay2 = 24 * oneHour2;
|
|
12677
|
+
var DEFAULT_REMINDER_MANAGER_CONFIG = {
|
|
12678
|
+
scheduledOffsetsMs: [
|
|
12679
|
+
2 * oneMinute2,
|
|
12680
|
+
30 * oneMinute2,
|
|
12681
|
+
oneHour2,
|
|
12682
|
+
2 * oneHour2,
|
|
12683
|
+
8 * oneHour2,
|
|
12684
|
+
oneDay2
|
|
12685
|
+
]
|
|
12686
|
+
};
|
|
12687
|
+
var isReminderExistsError = (error) => error.message.match("already has reminder created for this message_id");
|
|
12688
|
+
var isReminderDoesNotExistError = (error) => error.message.match("reminder does not exist");
|
|
12689
|
+
var _ReminderManager = class _ReminderManager extends WithSubscriptions {
|
|
12690
|
+
constructor({ client, config }) {
|
|
12691
|
+
super();
|
|
12692
|
+
this.upsertToState = ({
|
|
12693
|
+
data,
|
|
12694
|
+
overwrite = true
|
|
12695
|
+
}) => {
|
|
12696
|
+
if (!this.client._cacheEnabled()) {
|
|
12697
|
+
return;
|
|
12698
|
+
}
|
|
12699
|
+
const cachedReminder = this.getFromState(data.message_id);
|
|
12700
|
+
if (!cachedReminder) {
|
|
12701
|
+
const reminder = new Reminder({
|
|
12702
|
+
data,
|
|
12703
|
+
config: { stopRefreshBoundaryMs: this.stopTimerRefreshBoundaryMs }
|
|
12704
|
+
});
|
|
12705
|
+
this.state.partialNext({
|
|
12706
|
+
reminders: new Map(this.reminders.set(data.message_id, reminder))
|
|
12707
|
+
});
|
|
12708
|
+
} else if (overwrite) {
|
|
12709
|
+
cachedReminder.setState(data);
|
|
12710
|
+
}
|
|
12711
|
+
return cachedReminder;
|
|
12712
|
+
};
|
|
12713
|
+
this.removeFromState = (messageId) => {
|
|
12714
|
+
const cachedReminder = this.getFromState(messageId);
|
|
12715
|
+
if (!cachedReminder) return;
|
|
12716
|
+
cachedReminder.clearTimer();
|
|
12717
|
+
const reminders = this.reminders;
|
|
12718
|
+
reminders.delete(messageId);
|
|
12719
|
+
this.state.partialNext({ reminders: new Map(reminders) });
|
|
12720
|
+
};
|
|
12721
|
+
this.hydrateState = (messages) => {
|
|
12722
|
+
messages.forEach(({ reminder }) => {
|
|
12723
|
+
if (reminder) {
|
|
12724
|
+
this.upsertToState({ data: reminder });
|
|
12725
|
+
}
|
|
12726
|
+
});
|
|
12727
|
+
};
|
|
12728
|
+
// State API END //
|
|
12729
|
+
// Timers API START //
|
|
12730
|
+
this.initTimers = () => {
|
|
12731
|
+
this.reminders.forEach((reminder) => reminder.initTimer());
|
|
12732
|
+
};
|
|
12733
|
+
this.clearTimers = () => {
|
|
12734
|
+
this.reminders.forEach((reminder) => reminder.clearTimer());
|
|
12735
|
+
};
|
|
12736
|
+
this.registerSubscriptions = () => {
|
|
12737
|
+
if (this.hasSubscriptions) return;
|
|
12738
|
+
this.addUnsubscribeFunction(this.subscribeReminderCreated());
|
|
12739
|
+
this.addUnsubscribeFunction(this.subscribeReminderUpdated());
|
|
12740
|
+
this.addUnsubscribeFunction(this.subscribeReminderDeleted());
|
|
12741
|
+
this.addUnsubscribeFunction(this.subscribeNotificationReminderDue());
|
|
12742
|
+
this.addUnsubscribeFunction(this.subscribeMessageDeleted());
|
|
12743
|
+
this.addUnsubscribeFunction(this.subscribeMessageUndeleted());
|
|
12744
|
+
this.addUnsubscribeFunction(this.subscribePaginatorStateUpdated());
|
|
12745
|
+
this.addUnsubscribeFunction(this.subscribeConfigStateUpdated());
|
|
12746
|
+
};
|
|
12747
|
+
this.subscribeReminderCreated = () => this.client.on("reminder.created", (event) => {
|
|
12748
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
12749
|
+
const { reminder } = event;
|
|
12750
|
+
this.upsertToState({ data: reminder });
|
|
12751
|
+
}).unsubscribe;
|
|
12752
|
+
this.subscribeReminderUpdated = () => this.client.on("reminder.updated", (event) => {
|
|
12753
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
12754
|
+
const { reminder } = event;
|
|
12755
|
+
this.upsertToState({ data: reminder });
|
|
12756
|
+
}).unsubscribe;
|
|
12757
|
+
this.subscribeReminderDeleted = () => this.client.on("reminder.deleted", (event) => {
|
|
12758
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
12759
|
+
this.removeFromState(event.message_id);
|
|
12760
|
+
}).unsubscribe;
|
|
12761
|
+
this.subscribeMessageDeleted = () => this.client.on("message.deleted", (event) => {
|
|
12762
|
+
if (!event.message?.id) return;
|
|
12763
|
+
this.removeFromState(event.message.id);
|
|
12764
|
+
}).unsubscribe;
|
|
12765
|
+
this.subscribeMessageUndeleted = () => this.client.on("message.undeleted", (event) => {
|
|
12766
|
+
if (!event.message?.reminder) return;
|
|
12767
|
+
this.upsertToState({ data: event.message.reminder });
|
|
12768
|
+
}).unsubscribe;
|
|
12769
|
+
this.subscribeNotificationReminderDue = () => this.client.on("notification.reminder_due", () => null).unsubscribe;
|
|
12770
|
+
// todo: what should be performed on this event?
|
|
12771
|
+
this.subscribePaginatorStateUpdated = () => this.paginator.state.subscribeWithSelector(
|
|
12772
|
+
({ items }) => [items],
|
|
12773
|
+
([items]) => {
|
|
12774
|
+
if (!items) return;
|
|
12775
|
+
for (const reminder of items) {
|
|
12776
|
+
this.upsertToState({ data: reminder });
|
|
12777
|
+
}
|
|
12778
|
+
}
|
|
12779
|
+
);
|
|
12780
|
+
this.subscribeConfigStateUpdated = () => this.configState.subscribeWithSelector(
|
|
12781
|
+
({ stopTimerRefreshBoundaryMs }) => ({ stopTimerRefreshBoundaryMs }),
|
|
12782
|
+
({ stopTimerRefreshBoundaryMs }, previousValue) => {
|
|
12783
|
+
if (typeof stopTimerRefreshBoundaryMs === "number" && stopTimerRefreshBoundaryMs !== previousValue?.stopTimerRefreshBoundaryMs) {
|
|
12784
|
+
this.reminders.forEach((reminder) => {
|
|
12785
|
+
if (reminder.timer) {
|
|
12786
|
+
reminder.timer.stopRefreshBoundaryMs = stopTimerRefreshBoundaryMs;
|
|
12787
|
+
}
|
|
12788
|
+
});
|
|
12789
|
+
}
|
|
12790
|
+
}
|
|
12791
|
+
);
|
|
12792
|
+
// WS event handling END //
|
|
12793
|
+
// API calls START //
|
|
12794
|
+
this.upsertReminder = async (options) => {
|
|
12795
|
+
const { messageId } = options;
|
|
12796
|
+
if (this.getFromState(messageId)) {
|
|
12797
|
+
try {
|
|
12798
|
+
return await this.updateReminder(options);
|
|
12799
|
+
} catch (error) {
|
|
12800
|
+
if (isReminderDoesNotExistError(error)) {
|
|
12801
|
+
return await this.createReminder(options);
|
|
12802
|
+
}
|
|
12803
|
+
throw error;
|
|
12804
|
+
}
|
|
12805
|
+
} else {
|
|
12806
|
+
try {
|
|
12807
|
+
return await this.createReminder(options);
|
|
12808
|
+
} catch (error) {
|
|
12809
|
+
if (isReminderExistsError(error)) {
|
|
12810
|
+
return await this.updateReminder(options);
|
|
12811
|
+
}
|
|
12812
|
+
throw error;
|
|
12813
|
+
}
|
|
12814
|
+
}
|
|
12815
|
+
};
|
|
12816
|
+
this.createReminder = async (options) => {
|
|
12817
|
+
const { reminder } = await this.client.createReminder(options);
|
|
12818
|
+
return this.upsertToState({ data: reminder, overwrite: false });
|
|
12819
|
+
};
|
|
12820
|
+
this.updateReminder = async (options) => {
|
|
12821
|
+
const { reminder } = await this.client.updateReminder(options);
|
|
12822
|
+
return this.upsertToState({ data: reminder });
|
|
12823
|
+
};
|
|
12824
|
+
this.deleteReminder = async (messageId) => {
|
|
12825
|
+
await this.client.deleteReminder(messageId);
|
|
12826
|
+
this.removeFromState(messageId);
|
|
12827
|
+
};
|
|
12828
|
+
this.queryNextReminders = async () => {
|
|
12829
|
+
await this.paginator.next();
|
|
12830
|
+
};
|
|
12831
|
+
this.queryPreviousReminders = async () => {
|
|
12832
|
+
await this.paginator.prev();
|
|
12833
|
+
};
|
|
12834
|
+
this.client = client;
|
|
12835
|
+
this.configState = new StateStore({
|
|
12836
|
+
scheduledOffsetsMs: config?.scheduledOffsetsMs ?? DEFAULT_REMINDER_MANAGER_CONFIG.scheduledOffsetsMs
|
|
12837
|
+
});
|
|
12838
|
+
this.state = new StateStore({ reminders: /* @__PURE__ */ new Map() });
|
|
12839
|
+
this.paginator = new ReminderPaginator(client);
|
|
12840
|
+
}
|
|
12841
|
+
// Config API START //
|
|
12842
|
+
updateConfig(config) {
|
|
12843
|
+
this.configState.partialNext(config);
|
|
12844
|
+
}
|
|
12845
|
+
get stopTimerRefreshBoundaryMs() {
|
|
12846
|
+
return this.configState.getLatestValue().stopTimerRefreshBoundaryMs;
|
|
12847
|
+
}
|
|
12848
|
+
get scheduledOffsetsMs() {
|
|
12849
|
+
return this.configState.getLatestValue().scheduledOffsetsMs;
|
|
12850
|
+
}
|
|
12851
|
+
// Config API END //
|
|
12852
|
+
// State API START //
|
|
12853
|
+
get reminders() {
|
|
12854
|
+
return this.state.getLatestValue().reminders;
|
|
12855
|
+
}
|
|
12856
|
+
getFromState(messageId) {
|
|
12857
|
+
return this.reminders.get(messageId);
|
|
12858
|
+
}
|
|
12859
|
+
// API calls END //
|
|
12860
|
+
};
|
|
12861
|
+
// Timers API END //
|
|
12862
|
+
// WS event handling START //
|
|
12863
|
+
_ReminderManager.isReminderWsEventPayload = (event) => !!event.reminder && (event.type.startsWith("reminder.") || event.type === "notification.reminder_due");
|
|
12864
|
+
var ReminderManager = _ReminderManager;
|
|
12865
|
+
|
|
12395
12866
|
// src/client.ts
|
|
12396
12867
|
function isString3(x) {
|
|
12397
12868
|
return typeof x === "string" || x instanceof String;
|
|
@@ -12407,6 +12878,9 @@ var StreamChat = class _StreamChat {
|
|
|
12407
12878
|
});
|
|
12408
12879
|
this._getConnectionID = () => this.wsConnection?.connectionID || this.wsFallback?.connectionID;
|
|
12409
12880
|
this._hasConnectionID = () => Boolean(this._getConnectionID());
|
|
12881
|
+
this.setMessageComposerSetupFunction = (setupFunction) => {
|
|
12882
|
+
this._messageComposerSetupState.partialNext({ setupFunction });
|
|
12883
|
+
};
|
|
12410
12884
|
/**
|
|
12411
12885
|
* connectUser - Set the current user and open a WebSocket connection
|
|
12412
12886
|
*
|
|
@@ -12975,9 +13449,6 @@ var StreamChat = class _StreamChat {
|
|
|
12975
13449
|
device: this.options.device,
|
|
12976
13450
|
client_request_id
|
|
12977
13451
|
});
|
|
12978
|
-
this.setMessageComposerSetupFunction = (setupFunction) => {
|
|
12979
|
-
this._messageComposerSetupState.partialNext({ setupFunction });
|
|
12980
|
-
};
|
|
12981
13452
|
this.key = key;
|
|
12982
13453
|
this.listeners = {};
|
|
12983
13454
|
this.state = new ClientState({ client: this });
|
|
@@ -13032,6 +13503,7 @@ var StreamChat = class _StreamChat {
|
|
|
13032
13503
|
this.recoverStateOnReconnect = this.options.recoverStateOnReconnect;
|
|
13033
13504
|
this.threads = new ThreadManager({ client: this });
|
|
13034
13505
|
this.polls = new PollManager({ client: this });
|
|
13506
|
+
this.reminders = new ReminderManager({ client: this });
|
|
13035
13507
|
}
|
|
13036
13508
|
static getInstance(key, secretOrOptions, options) {
|
|
13037
13509
|
if (!_StreamChat._instance) {
|
|
@@ -13167,15 +13639,15 @@ var StreamChat = class _StreamChat {
|
|
|
13167
13639
|
* @param {string} userID User ID. If user has no devices, it will error
|
|
13168
13640
|
* @param {TestPushDataInput} [data] Overrides for push templates/message used
|
|
13169
13641
|
* IE: {
|
|
13170
|
-
|
|
13171
|
-
|
|
13172
|
-
|
|
13173
|
-
|
|
13174
|
-
|
|
13175
|
-
|
|
13176
|
-
|
|
13177
|
-
|
|
13178
|
-
|
|
13642
|
+
messageID: 'id-of-message', // will error if message does not exist
|
|
13643
|
+
apnTemplate: '{}', // if app doesn't have apn configured it will error
|
|
13644
|
+
firebaseTemplate: '{}', // if app doesn't have firebase configured it will error
|
|
13645
|
+
firebaseDataTemplate: '{}', // if app doesn't have firebase configured it will error
|
|
13646
|
+
skipDevices: true, // skip config/device checks and sending to real devices
|
|
13647
|
+
pushProviderName: 'staging' // one of your configured push providers
|
|
13648
|
+
pushProviderType: 'apn' // one of supported provider types
|
|
13649
|
+
}
|
|
13650
|
+
*/
|
|
13179
13651
|
async testPushSettings(userID, data = {}) {
|
|
13180
13652
|
return await this.post(this.baseURL + "/check_push", {
|
|
13181
13653
|
user_id: userID,
|
|
@@ -13193,10 +13665,10 @@ var StreamChat = class _StreamChat {
|
|
|
13193
13665
|
*
|
|
13194
13666
|
* @param {TestSQSDataInput} [data] Overrides SQS settings for testing if needed
|
|
13195
13667
|
* IE: {
|
|
13196
|
-
|
|
13197
|
-
|
|
13198
|
-
|
|
13199
|
-
|
|
13668
|
+
sqs_key: 'auth_key',
|
|
13669
|
+
sqs_secret: 'auth_secret',
|
|
13670
|
+
sqs_url: 'url_to_queue',
|
|
13671
|
+
}
|
|
13200
13672
|
*/
|
|
13201
13673
|
async testSQSSettings(data = {}) {
|
|
13202
13674
|
return await this.post(this.baseURL + "/check_sqs", data);
|
|
@@ -13206,10 +13678,10 @@ var StreamChat = class _StreamChat {
|
|
|
13206
13678
|
*
|
|
13207
13679
|
* @param {TestSNSDataInput} [data] Overrides SNS settings for testing if needed
|
|
13208
13680
|
* IE: {
|
|
13209
|
-
|
|
13210
|
-
|
|
13211
|
-
|
|
13212
|
-
|
|
13681
|
+
sns_key: 'auth_key',
|
|
13682
|
+
sns_secret: 'auth_secret',
|
|
13683
|
+
sns_topic_arn: 'topic_to_publish_to',
|
|
13684
|
+
}
|
|
13213
13685
|
*/
|
|
13214
13686
|
async testSNSSettings(data = {}) {
|
|
13215
13687
|
return await this.post(this.baseURL + "/check_sns", data);
|
|
@@ -13690,6 +14162,7 @@ var StreamChat = class _StreamChat {
|
|
|
13690
14162
|
})
|
|
13691
14163
|
};
|
|
13692
14164
|
this.polls.hydratePollCache(channelState.messages, true);
|
|
14165
|
+
this.reminders.hydrateState(channelState.messages);
|
|
13693
14166
|
}
|
|
13694
14167
|
if (channelState.draft) {
|
|
13695
14168
|
c.messageComposer.initState({ composition: channelState.draft });
|
|
@@ -14267,7 +14740,7 @@ var StreamChat = class _StreamChat {
|
|
|
14267
14740
|
data
|
|
14268
14741
|
);
|
|
14269
14742
|
}
|
|
14270
|
-
|
|
14743
|
+
deleteChannelType(channelType) {
|
|
14271
14744
|
return this.delete(
|
|
14272
14745
|
this.baseURL + `/channeltypes/${encodeURIComponent(channelType)}`
|
|
14273
14746
|
);
|
|
@@ -14610,7 +15083,7 @@ var StreamChat = class _StreamChat {
|
|
|
14610
15083
|
if (this.userAgent) {
|
|
14611
15084
|
return this.userAgent;
|
|
14612
15085
|
}
|
|
14613
|
-
const version = "9.
|
|
15086
|
+
const version = "9.5.1";
|
|
14614
15087
|
const clientBundle = "browser-cjs";
|
|
14615
15088
|
let userAgentString = "";
|
|
14616
15089
|
if (this.sdkIdentifier) {
|
|
@@ -15649,6 +16122,56 @@ var StreamChat = class _StreamChat {
|
|
|
15649
16122
|
};
|
|
15650
16123
|
return await this.post(this.baseURL + "/drafts/query", payload);
|
|
15651
16124
|
}
|
|
16125
|
+
/**
|
|
16126
|
+
* createReminder - Creates a reminder for a message
|
|
16127
|
+
*
|
|
16128
|
+
* @param {CreateReminderOptions} options The options for creating the reminder
|
|
16129
|
+
* @returns {Promise<ReminderAPIResponse>}
|
|
16130
|
+
*/
|
|
16131
|
+
async createReminder({ messageId, ...options }) {
|
|
16132
|
+
return await this.post(
|
|
16133
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
16134
|
+
options
|
|
16135
|
+
);
|
|
16136
|
+
}
|
|
16137
|
+
/**
|
|
16138
|
+
* updateReminder - Updates an existing reminder for a message
|
|
16139
|
+
*
|
|
16140
|
+
* @param {UpdateReminderOptions} options The options for updating the reminder
|
|
16141
|
+
* @returns {Promise<ReminderAPIResponse>}
|
|
16142
|
+
*/
|
|
16143
|
+
async updateReminder({ messageId, ...options }) {
|
|
16144
|
+
return await this.patch(
|
|
16145
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
16146
|
+
options
|
|
16147
|
+
);
|
|
16148
|
+
}
|
|
16149
|
+
/**
|
|
16150
|
+
* deleteReminder - Deletes a reminder for a message
|
|
16151
|
+
*
|
|
16152
|
+
* @param {string} messageId The ID of the message whose reminder to delete
|
|
16153
|
+
* @param {string} [userId] Optional user ID, required for server-side operations
|
|
16154
|
+
* @returns {Promise<APIResponse>}
|
|
16155
|
+
*/
|
|
16156
|
+
async deleteReminder(messageId, userId) {
|
|
16157
|
+
return await this.delete(
|
|
16158
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
16159
|
+
userId ? { user_id: userId } : {}
|
|
16160
|
+
);
|
|
16161
|
+
}
|
|
16162
|
+
/**
|
|
16163
|
+
* queryReminders - Queries reminders based on given filters
|
|
16164
|
+
*
|
|
16165
|
+
* @param {QueryRemindersOptions} options The options for querying reminders
|
|
16166
|
+
* @returns {Promise<QueryRemindersResponse>}
|
|
16167
|
+
*/
|
|
16168
|
+
async queryReminders({ filter: filter2, sort, ...rest } = {}) {
|
|
16169
|
+
return await this.post(`${this.baseURL}/reminders/query`, {
|
|
16170
|
+
filter_conditions: filter2,
|
|
16171
|
+
sort: sort && normalizeQuerySort(sort),
|
|
16172
|
+
...rest
|
|
16173
|
+
});
|
|
16174
|
+
}
|
|
15652
16175
|
};
|
|
15653
16176
|
|
|
15654
16177
|
// src/events.ts
|
|
@@ -15715,7 +16238,12 @@ var EVENT_MAP = {
|
|
|
15715
16238
|
"connection.changed": true,
|
|
15716
16239
|
"connection.recovered": true,
|
|
15717
16240
|
"transport.changed": true,
|
|
15718
|
-
"capabilities.changed": true
|
|
16241
|
+
"capabilities.changed": true,
|
|
16242
|
+
// Reminder events
|
|
16243
|
+
"reminder.created": true,
|
|
16244
|
+
"reminder.updated": true,
|
|
16245
|
+
"reminder.deleted": true,
|
|
16246
|
+
"notification.reminder_due": true
|
|
15719
16247
|
};
|
|
15720
16248
|
|
|
15721
16249
|
// src/permissions.ts
|