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
package/dist/esm/index.js
CHANGED
|
@@ -3900,26 +3900,14 @@ var ensureIsLocalAttachment = (attachment) => {
|
|
|
3900
3900
|
|
|
3901
3901
|
// src/store.ts
|
|
3902
3902
|
var isPatch = (value) => typeof value === "function";
|
|
3903
|
+
var noop2 = () => {
|
|
3904
|
+
};
|
|
3903
3905
|
var StateStore = class {
|
|
3904
3906
|
constructor(value) {
|
|
3905
3907
|
this.value = value;
|
|
3906
|
-
this.
|
|
3907
|
-
this.
|
|
3908
|
-
const newValue = isPatch(newValueOrPatch) ? newValueOrPatch(this.value) : newValueOrPatch;
|
|
3909
|
-
if (newValue === this.value) return;
|
|
3910
|
-
const oldValue = this.value;
|
|
3911
|
-
this.value = newValue;
|
|
3912
|
-
this.handlerSet.forEach((handler) => handler(this.value, oldValue));
|
|
3913
|
-
};
|
|
3908
|
+
this.handlers = /* @__PURE__ */ new Set();
|
|
3909
|
+
this.preprocessors = /* @__PURE__ */ new Set();
|
|
3914
3910
|
this.partialNext = (partial) => this.next((current) => ({ ...current, ...partial }));
|
|
3915
|
-
this.getLatestValue = () => this.value;
|
|
3916
|
-
this.subscribe = (handler) => {
|
|
3917
|
-
handler(this.value, void 0);
|
|
3918
|
-
this.handlerSet.add(handler);
|
|
3919
|
-
return () => {
|
|
3920
|
-
this.handlerSet.delete(handler);
|
|
3921
|
-
};
|
|
3922
|
-
};
|
|
3923
3911
|
this.subscribeWithSelector = (selector, handler) => {
|
|
3924
3912
|
let previouslySelectedValues;
|
|
3925
3913
|
const wrappedHandler = (nextValue) => {
|
|
@@ -3938,6 +3926,183 @@ var StateStore = class {
|
|
|
3938
3926
|
return this.subscribe(wrappedHandler);
|
|
3939
3927
|
};
|
|
3940
3928
|
}
|
|
3929
|
+
/**
|
|
3930
|
+
* Allows merging two stores only if their keys differ otherwise there's no way to ensure the data type stability.
|
|
3931
|
+
* @experimental
|
|
3932
|
+
* This method is experimental and may change in future versions.
|
|
3933
|
+
*/
|
|
3934
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3935
|
+
merge(stateStore) {
|
|
3936
|
+
return new MergedStateStore({
|
|
3937
|
+
original: this,
|
|
3938
|
+
merged: stateStore
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
3941
|
+
next(newValueOrPatch) {
|
|
3942
|
+
const newValue = isPatch(newValueOrPatch) ? newValueOrPatch(this.value) : newValueOrPatch;
|
|
3943
|
+
if (newValue === this.value) return;
|
|
3944
|
+
this.preprocessors.forEach((preprocessor) => preprocessor(newValue, this.value));
|
|
3945
|
+
const oldValue = this.value;
|
|
3946
|
+
this.value = newValue;
|
|
3947
|
+
this.handlers.forEach((handler) => handler(this.value, oldValue));
|
|
3948
|
+
}
|
|
3949
|
+
getLatestValue() {
|
|
3950
|
+
return this.value;
|
|
3951
|
+
}
|
|
3952
|
+
subscribe(handler) {
|
|
3953
|
+
handler(this.value, void 0);
|
|
3954
|
+
this.handlers.add(handler);
|
|
3955
|
+
return () => {
|
|
3956
|
+
this.handlers.delete(handler);
|
|
3957
|
+
};
|
|
3958
|
+
}
|
|
3959
|
+
/**
|
|
3960
|
+
* Registers a preprocessor function that will be called before the state is updated.
|
|
3961
|
+
*
|
|
3962
|
+
* Preprocessors are invoked with the new and previous values whenever `next` or `partialNext` methods
|
|
3963
|
+
* are called, allowing you to mutate or react to the new value before it is set. Preprocessors run in the
|
|
3964
|
+
* order they were registered.
|
|
3965
|
+
*
|
|
3966
|
+
* @example
|
|
3967
|
+
* ```ts
|
|
3968
|
+
* const store = new StateStore<{ count: number; isMaxValue: bool; }>({ count: 0, isMaxValue: false });
|
|
3969
|
+
*
|
|
3970
|
+
* store.addPreprocessor((nextValue, prevValue) => {
|
|
3971
|
+
* if (nextValue.count > 10) {
|
|
3972
|
+
* nextValue.count = 10; // Clamp the value to a maximum of 10
|
|
3973
|
+
* }
|
|
3974
|
+
*
|
|
3975
|
+
* if (nextValue.count === 10) {
|
|
3976
|
+
* nextValue.isMaxValue = true; // Set isMaxValue to true if count is 10
|
|
3977
|
+
* } else {
|
|
3978
|
+
* nextValue.isMaxValue = false; // Reset isMaxValue otherwise
|
|
3979
|
+
* }
|
|
3980
|
+
* });
|
|
3981
|
+
*
|
|
3982
|
+
* store.partialNext({ count: 15 });
|
|
3983
|
+
*
|
|
3984
|
+
* store.getLatestValue(); // { count: 10, isMaxValue: true }
|
|
3985
|
+
*
|
|
3986
|
+
* store.partialNext({ count: 5 });
|
|
3987
|
+
*
|
|
3988
|
+
* store.getLatestValue(); // { count: 5, isMaxValue: false }
|
|
3989
|
+
* ```
|
|
3990
|
+
*
|
|
3991
|
+
* @param preprocessor - The function to be called with the next and previous values before the state is updated.
|
|
3992
|
+
* @returns A `RemovePreprocessor` function that removes the preprocessor when called.
|
|
3993
|
+
*/
|
|
3994
|
+
addPreprocessor(preprocessor) {
|
|
3995
|
+
this.preprocessors.add(preprocessor);
|
|
3996
|
+
return () => {
|
|
3997
|
+
this.preprocessors.delete(preprocessor);
|
|
3998
|
+
};
|
|
3999
|
+
}
|
|
4000
|
+
};
|
|
4001
|
+
var MergedStateStore = class _MergedStateStore extends StateStore {
|
|
4002
|
+
constructor({ original, merged }) {
|
|
4003
|
+
const originalValue = original.getLatestValue();
|
|
4004
|
+
const mergedValue = merged.getLatestValue();
|
|
4005
|
+
super({
|
|
4006
|
+
...originalValue,
|
|
4007
|
+
...mergedValue
|
|
4008
|
+
});
|
|
4009
|
+
// override original methods and "disable" them
|
|
4010
|
+
this.next = () => {
|
|
4011
|
+
console.warn(
|
|
4012
|
+
`${_MergedStateStore.name}.next is disabled, call original.next or merged.next instead`
|
|
4013
|
+
);
|
|
4014
|
+
};
|
|
4015
|
+
this.partialNext = () => {
|
|
4016
|
+
console.warn(
|
|
4017
|
+
`${_MergedStateStore.name}.partialNext is disabled, call original.partialNext or merged.partialNext instead`
|
|
4018
|
+
);
|
|
4019
|
+
};
|
|
4020
|
+
this.cachedOriginalValue = originalValue;
|
|
4021
|
+
this.cachedMergedValue = mergedValue;
|
|
4022
|
+
this.original = original;
|
|
4023
|
+
this.merged = merged;
|
|
4024
|
+
}
|
|
4025
|
+
/**
|
|
4026
|
+
* Subscribes to changes in the merged state store.
|
|
4027
|
+
*
|
|
4028
|
+
* This method extends the base subscribe functionality to handle the merged nature of this store:
|
|
4029
|
+
* 1. The first subscriber triggers registration of helper subscribers that listen to both source stores
|
|
4030
|
+
* 2. Changes from either source store are propagated to this merged store
|
|
4031
|
+
* 3. Source store values are cached to prevent unnecessary updates
|
|
4032
|
+
*
|
|
4033
|
+
* When the first subscriber is added, the method sets up listeners on both original and merged stores.
|
|
4034
|
+
* These listeners update the combined store value whenever either source store changes.
|
|
4035
|
+
* All subscriptions (helpers and the actual handler) are tracked so they can be properly cleaned up.
|
|
4036
|
+
*
|
|
4037
|
+
* @param handler - The callback function that will be executed when the state changes
|
|
4038
|
+
* @returns An unsubscribe function that, when called, removes the subscription and any helper subscriptions
|
|
4039
|
+
*/
|
|
4040
|
+
subscribe(handler) {
|
|
4041
|
+
const unsubscribeFunctions = [];
|
|
4042
|
+
if (!this.handlers.size) {
|
|
4043
|
+
const base = (nextValue) => {
|
|
4044
|
+
super.next((currentValue) => ({
|
|
4045
|
+
...currentValue,
|
|
4046
|
+
...nextValue
|
|
4047
|
+
}));
|
|
4048
|
+
};
|
|
4049
|
+
unsubscribeFunctions.push(
|
|
4050
|
+
this.original.subscribe((nextValue) => {
|
|
4051
|
+
if (nextValue === this.cachedOriginalValue) return;
|
|
4052
|
+
this.cachedOriginalValue = nextValue;
|
|
4053
|
+
base(nextValue);
|
|
4054
|
+
}),
|
|
4055
|
+
this.merged.subscribe((nextValue) => {
|
|
4056
|
+
if (nextValue === this.cachedMergedValue) return;
|
|
4057
|
+
this.cachedMergedValue = nextValue;
|
|
4058
|
+
base(nextValue);
|
|
4059
|
+
})
|
|
4060
|
+
);
|
|
4061
|
+
}
|
|
4062
|
+
unsubscribeFunctions.push(super.subscribe(handler));
|
|
4063
|
+
return () => {
|
|
4064
|
+
unsubscribeFunctions.forEach((unsubscribe) => unsubscribe());
|
|
4065
|
+
};
|
|
4066
|
+
}
|
|
4067
|
+
/**
|
|
4068
|
+
* Retrieves the latest combined state from both original and merged stores.
|
|
4069
|
+
*
|
|
4070
|
+
* This method extends the base getLatestValue functionality to ensure the merged store
|
|
4071
|
+
* remains in sync with its source stores even when there are no active subscribers.
|
|
4072
|
+
*
|
|
4073
|
+
* When there are no handlers registered, the method:
|
|
4074
|
+
* 1. Fetches the latest values from both source stores
|
|
4075
|
+
* 2. Compares them with the cached values to detect changes
|
|
4076
|
+
* 3. If changes are detected, updates the internal value and caches
|
|
4077
|
+
* the new source values to maintain consistency
|
|
4078
|
+
*
|
|
4079
|
+
* This approach ensures that calling getLatestValue() always returns the most
|
|
4080
|
+
* up-to-date combined state, even if the merged store hasn't been actively
|
|
4081
|
+
* receiving updates through subscriptions.
|
|
4082
|
+
*
|
|
4083
|
+
* @returns The latest combined state from both original and merged stores
|
|
4084
|
+
*/
|
|
4085
|
+
getLatestValue() {
|
|
4086
|
+
if (!this.handlers.size) {
|
|
4087
|
+
const originalValue = this.original.getLatestValue();
|
|
4088
|
+
const mergedValue = this.merged.getLatestValue();
|
|
4089
|
+
if (originalValue !== this.cachedOriginalValue || mergedValue !== this.cachedMergedValue) {
|
|
4090
|
+
this.value = {
|
|
4091
|
+
...originalValue,
|
|
4092
|
+
...mergedValue
|
|
4093
|
+
};
|
|
4094
|
+
this.cachedMergedValue = mergedValue;
|
|
4095
|
+
this.cachedOriginalValue = originalValue;
|
|
4096
|
+
}
|
|
4097
|
+
}
|
|
4098
|
+
return super.getLatestValue();
|
|
4099
|
+
}
|
|
4100
|
+
addPreprocessor() {
|
|
4101
|
+
console.warn(
|
|
4102
|
+
`${_MergedStateStore.name}.addPreprocessor is disabled, call original.addPreprocessor or merged.addPreprocessor instead`
|
|
4103
|
+
);
|
|
4104
|
+
return noop2;
|
|
4105
|
+
}
|
|
3941
4106
|
};
|
|
3942
4107
|
|
|
3943
4108
|
// src/utils/mergeWith/mergeWithCore.ts
|
|
@@ -5289,8 +5454,8 @@ function decodeTlds(encoded) {
|
|
|
5289
5454
|
var defaults2 = {
|
|
5290
5455
|
defaultProtocol: "http",
|
|
5291
5456
|
events: null,
|
|
5292
|
-
format:
|
|
5293
|
-
formatHref:
|
|
5457
|
+
format: noop3,
|
|
5458
|
+
formatHref: noop3,
|
|
5294
5459
|
nl2br: false,
|
|
5295
5460
|
tagName: "a",
|
|
5296
5461
|
target: null,
|
|
@@ -5395,7 +5560,7 @@ Options.prototype = {
|
|
|
5395
5560
|
return renderFn(ir, token.t, token);
|
|
5396
5561
|
}
|
|
5397
5562
|
};
|
|
5398
|
-
function
|
|
5563
|
+
function noop3(val) {
|
|
5399
5564
|
return val;
|
|
5400
5565
|
}
|
|
5401
5566
|
function MultiToken(value, tokens) {
|
|
@@ -6486,7 +6651,9 @@ var ErrorFromResponse = class extends Error {
|
|
|
6486
6651
|
return {
|
|
6487
6652
|
message: `(${joinable.join(", ")}) - ${this.message}`,
|
|
6488
6653
|
stack: this.stack,
|
|
6489
|
-
name: this.name
|
|
6654
|
+
name: this.name,
|
|
6655
|
+
code: this.code,
|
|
6656
|
+
status: this.status
|
|
6490
6657
|
};
|
|
6491
6658
|
}
|
|
6492
6659
|
};
|
|
@@ -7054,7 +7221,7 @@ var MessageDraftComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
|
7054
7221
|
}
|
|
7055
7222
|
};
|
|
7056
7223
|
|
|
7057
|
-
// src/
|
|
7224
|
+
// src/search/BaseSearchSource.ts
|
|
7058
7225
|
var DEFAULT_SEARCH_SOURCE_OPTIONS = {
|
|
7059
7226
|
debounceMs: 300,
|
|
7060
7227
|
pageSize: 10
|
|
@@ -7180,6 +7347,112 @@ var BaseSearchSource = class {
|
|
|
7180
7347
|
this.activate();
|
|
7181
7348
|
}
|
|
7182
7349
|
};
|
|
7350
|
+
|
|
7351
|
+
// src/search/SearchController.ts
|
|
7352
|
+
var SearchController = class {
|
|
7353
|
+
constructor({ config, sources } = {}) {
|
|
7354
|
+
this.addSource = (source) => {
|
|
7355
|
+
this.state.partialNext({
|
|
7356
|
+
sources: [...this.sources, source]
|
|
7357
|
+
});
|
|
7358
|
+
};
|
|
7359
|
+
this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
|
|
7360
|
+
this.removeSource = (sourceType) => {
|
|
7361
|
+
const newSources = this.sources.filter((s) => s.type !== sourceType);
|
|
7362
|
+
if (newSources.length === this.sources.length) return;
|
|
7363
|
+
this.state.partialNext({ sources: newSources });
|
|
7364
|
+
};
|
|
7365
|
+
this.activateSource = (sourceType) => {
|
|
7366
|
+
const source = this.getSource(sourceType);
|
|
7367
|
+
if (!source || source.isActive) return;
|
|
7368
|
+
if (this.config.keepSingleActiveSource) {
|
|
7369
|
+
this.sources.forEach((s) => {
|
|
7370
|
+
if (s.type !== sourceType) {
|
|
7371
|
+
s.deactivate();
|
|
7372
|
+
}
|
|
7373
|
+
});
|
|
7374
|
+
}
|
|
7375
|
+
source.activate();
|
|
7376
|
+
this.state.partialNext({ sources: [...this.sources] });
|
|
7377
|
+
};
|
|
7378
|
+
this.deactivateSource = (sourceType) => {
|
|
7379
|
+
const source = this.getSource(sourceType);
|
|
7380
|
+
if (!source?.isActive) return;
|
|
7381
|
+
if (this.activeSources.length === 1) return;
|
|
7382
|
+
source.deactivate();
|
|
7383
|
+
this.state.partialNext({ sources: [...this.sources] });
|
|
7384
|
+
};
|
|
7385
|
+
this.activate = () => {
|
|
7386
|
+
if (!this.activeSources.length) {
|
|
7387
|
+
const sourcesToActivate = this.config.keepSingleActiveSource ? this.sources.slice(0, 1) : this.sources;
|
|
7388
|
+
sourcesToActivate.forEach((s) => s.activate());
|
|
7389
|
+
}
|
|
7390
|
+
if (this.isActive) return;
|
|
7391
|
+
this.state.partialNext({ isActive: true });
|
|
7392
|
+
};
|
|
7393
|
+
this.search = async (searchQuery) => {
|
|
7394
|
+
const searchedSources = this.activeSources;
|
|
7395
|
+
this.state.partialNext({
|
|
7396
|
+
searchQuery
|
|
7397
|
+
});
|
|
7398
|
+
await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
|
|
7399
|
+
};
|
|
7400
|
+
this.cancelSearchQueries = () => {
|
|
7401
|
+
this.activeSources.forEach((s) => s.cancelScheduledQuery());
|
|
7402
|
+
};
|
|
7403
|
+
this.clear = () => {
|
|
7404
|
+
this.cancelSearchQueries();
|
|
7405
|
+
this.sources.forEach(
|
|
7406
|
+
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
7407
|
+
);
|
|
7408
|
+
this.state.next((current) => ({
|
|
7409
|
+
...current,
|
|
7410
|
+
isActive: true,
|
|
7411
|
+
queriesInProgress: [],
|
|
7412
|
+
searchQuery: ""
|
|
7413
|
+
}));
|
|
7414
|
+
};
|
|
7415
|
+
this.exit = () => {
|
|
7416
|
+
this.cancelSearchQueries();
|
|
7417
|
+
this.sources.forEach(
|
|
7418
|
+
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
7419
|
+
);
|
|
7420
|
+
this.state.next((current) => ({
|
|
7421
|
+
...current,
|
|
7422
|
+
isActive: false,
|
|
7423
|
+
queriesInProgress: [],
|
|
7424
|
+
searchQuery: ""
|
|
7425
|
+
}));
|
|
7426
|
+
};
|
|
7427
|
+
this.state = new StateStore({
|
|
7428
|
+
isActive: false,
|
|
7429
|
+
searchQuery: "",
|
|
7430
|
+
sources: sources ?? []
|
|
7431
|
+
});
|
|
7432
|
+
this._internalState = new StateStore({});
|
|
7433
|
+
this.config = { keepSingleActiveSource: true, ...config };
|
|
7434
|
+
}
|
|
7435
|
+
get hasNext() {
|
|
7436
|
+
return this.sources.some((source) => source.hasNext);
|
|
7437
|
+
}
|
|
7438
|
+
get sources() {
|
|
7439
|
+
return this.state.getLatestValue().sources;
|
|
7440
|
+
}
|
|
7441
|
+
get activeSources() {
|
|
7442
|
+
return this.state.getLatestValue().sources.filter((s) => s.isActive);
|
|
7443
|
+
}
|
|
7444
|
+
get isActive() {
|
|
7445
|
+
return this.state.getLatestValue().isActive;
|
|
7446
|
+
}
|
|
7447
|
+
get searchQuery() {
|
|
7448
|
+
return this.state.getLatestValue().searchQuery;
|
|
7449
|
+
}
|
|
7450
|
+
get searchSourceTypes() {
|
|
7451
|
+
return this.sources.map((s) => s.type);
|
|
7452
|
+
}
|
|
7453
|
+
};
|
|
7454
|
+
|
|
7455
|
+
// src/search/UserSearchSource.ts
|
|
7183
7456
|
var UserSearchSource = class extends BaseSearchSource {
|
|
7184
7457
|
constructor(client, options) {
|
|
7185
7458
|
super(options);
|
|
@@ -7203,6 +7476,8 @@ var UserSearchSource = class extends BaseSearchSource {
|
|
|
7203
7476
|
return items.filter((u) => u.id !== this.client.user?.id);
|
|
7204
7477
|
}
|
|
7205
7478
|
};
|
|
7479
|
+
|
|
7480
|
+
// src/search/ChannelSearchSource.ts
|
|
7206
7481
|
var ChannelSearchSource = class extends BaseSearchSource {
|
|
7207
7482
|
constructor(client, options) {
|
|
7208
7483
|
super(options);
|
|
@@ -7224,6 +7499,8 @@ var ChannelSearchSource = class extends BaseSearchSource {
|
|
|
7224
7499
|
return items;
|
|
7225
7500
|
}
|
|
7226
7501
|
};
|
|
7502
|
+
|
|
7503
|
+
// src/search/MessageSearchSource.ts
|
|
7227
7504
|
var MessageSearchSource = class extends BaseSearchSource {
|
|
7228
7505
|
constructor(client, options) {
|
|
7229
7506
|
super(options);
|
|
@@ -7284,108 +7561,6 @@ var MessageSearchSource = class extends BaseSearchSource {
|
|
|
7284
7561
|
return items;
|
|
7285
7562
|
}
|
|
7286
7563
|
};
|
|
7287
|
-
var SearchController = class {
|
|
7288
|
-
constructor({ config, sources } = {}) {
|
|
7289
|
-
this.addSource = (source) => {
|
|
7290
|
-
this.state.partialNext({
|
|
7291
|
-
sources: [...this.sources, source]
|
|
7292
|
-
});
|
|
7293
|
-
};
|
|
7294
|
-
this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
|
|
7295
|
-
this.removeSource = (sourceType) => {
|
|
7296
|
-
const newSources = this.sources.filter((s) => s.type !== sourceType);
|
|
7297
|
-
if (newSources.length === this.sources.length) return;
|
|
7298
|
-
this.state.partialNext({ sources: newSources });
|
|
7299
|
-
};
|
|
7300
|
-
this.activateSource = (sourceType) => {
|
|
7301
|
-
const source = this.getSource(sourceType);
|
|
7302
|
-
if (!source || source.isActive) return;
|
|
7303
|
-
if (this.config.keepSingleActiveSource) {
|
|
7304
|
-
this.sources.forEach((s) => {
|
|
7305
|
-
if (s.type !== sourceType) {
|
|
7306
|
-
s.deactivate();
|
|
7307
|
-
}
|
|
7308
|
-
});
|
|
7309
|
-
}
|
|
7310
|
-
source.activate();
|
|
7311
|
-
this.state.partialNext({ sources: [...this.sources] });
|
|
7312
|
-
};
|
|
7313
|
-
this.deactivateSource = (sourceType) => {
|
|
7314
|
-
const source = this.getSource(sourceType);
|
|
7315
|
-
if (!source?.isActive) return;
|
|
7316
|
-
if (this.activeSources.length === 1) return;
|
|
7317
|
-
source.deactivate();
|
|
7318
|
-
this.state.partialNext({ sources: [...this.sources] });
|
|
7319
|
-
};
|
|
7320
|
-
this.activate = () => {
|
|
7321
|
-
if (!this.activeSources.length) {
|
|
7322
|
-
const sourcesToActivate = this.config.keepSingleActiveSource ? this.sources.slice(0, 1) : this.sources;
|
|
7323
|
-
sourcesToActivate.forEach((s) => s.activate());
|
|
7324
|
-
}
|
|
7325
|
-
if (this.isActive) return;
|
|
7326
|
-
this.state.partialNext({ isActive: true });
|
|
7327
|
-
};
|
|
7328
|
-
this.search = async (searchQuery) => {
|
|
7329
|
-
const searchedSources = this.activeSources;
|
|
7330
|
-
this.state.partialNext({
|
|
7331
|
-
searchQuery
|
|
7332
|
-
});
|
|
7333
|
-
await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
|
|
7334
|
-
};
|
|
7335
|
-
this.cancelSearchQueries = () => {
|
|
7336
|
-
this.activeSources.forEach((s) => s.cancelScheduledQuery());
|
|
7337
|
-
};
|
|
7338
|
-
this.clear = () => {
|
|
7339
|
-
this.cancelSearchQueries();
|
|
7340
|
-
this.sources.forEach(
|
|
7341
|
-
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
7342
|
-
);
|
|
7343
|
-
this.state.next((current) => ({
|
|
7344
|
-
...current,
|
|
7345
|
-
isActive: true,
|
|
7346
|
-
queriesInProgress: [],
|
|
7347
|
-
searchQuery: ""
|
|
7348
|
-
}));
|
|
7349
|
-
};
|
|
7350
|
-
this.exit = () => {
|
|
7351
|
-
this.cancelSearchQueries();
|
|
7352
|
-
this.sources.forEach(
|
|
7353
|
-
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
7354
|
-
);
|
|
7355
|
-
this.state.next((current) => ({
|
|
7356
|
-
...current,
|
|
7357
|
-
isActive: false,
|
|
7358
|
-
queriesInProgress: [],
|
|
7359
|
-
searchQuery: ""
|
|
7360
|
-
}));
|
|
7361
|
-
};
|
|
7362
|
-
this.state = new StateStore({
|
|
7363
|
-
isActive: false,
|
|
7364
|
-
searchQuery: "",
|
|
7365
|
-
sources: sources ?? []
|
|
7366
|
-
});
|
|
7367
|
-
this._internalState = new StateStore({});
|
|
7368
|
-
this.config = { keepSingleActiveSource: true, ...config };
|
|
7369
|
-
}
|
|
7370
|
-
get hasNext() {
|
|
7371
|
-
return this.sources.some((source) => source.hasNext);
|
|
7372
|
-
}
|
|
7373
|
-
get sources() {
|
|
7374
|
-
return this.state.getLatestValue().sources;
|
|
7375
|
-
}
|
|
7376
|
-
get activeSources() {
|
|
7377
|
-
return this.state.getLatestValue().sources.filter((s) => s.isActive);
|
|
7378
|
-
}
|
|
7379
|
-
get isActive() {
|
|
7380
|
-
return this.state.getLatestValue().isActive;
|
|
7381
|
-
}
|
|
7382
|
-
get searchQuery() {
|
|
7383
|
-
return this.state.getLatestValue().searchQuery;
|
|
7384
|
-
}
|
|
7385
|
-
get searchSourceTypes() {
|
|
7386
|
-
return this.sources.map((s) => s.type);
|
|
7387
|
-
}
|
|
7388
|
-
};
|
|
7389
7564
|
|
|
7390
7565
|
// src/messageComposer/middleware/textComposer/textMiddlewareUtils.ts
|
|
7391
7566
|
var getTriggerCharWithToken = ({
|
|
@@ -8619,7 +8794,7 @@ var initState5 = (composition) => {
|
|
|
8619
8794
|
pollId: message.poll_id ?? null
|
|
8620
8795
|
};
|
|
8621
8796
|
};
|
|
8622
|
-
var
|
|
8797
|
+
var noop4 = () => void 0;
|
|
8623
8798
|
var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
8624
8799
|
// todo: mediaRecorder: MediaRecorderController;
|
|
8625
8800
|
constructor({
|
|
@@ -8647,7 +8822,7 @@ var _MessageComposer = class _MessageComposer extends WithSubscriptions {
|
|
|
8647
8822
|
this.initEditingAuditState = (composition) => initEditingAuditState(composition);
|
|
8648
8823
|
this.registerSubscriptions = () => {
|
|
8649
8824
|
if (this.hasSubscriptions) {
|
|
8650
|
-
return
|
|
8825
|
+
return noop4;
|
|
8651
8826
|
}
|
|
8652
8827
|
this.addUnsubscribeFunction(this.subscribeMessageComposerSetupStateChange());
|
|
8653
8828
|
this.addUnsubscribeFunction(this.subscribeMessageUpdated());
|
|
@@ -10164,6 +10339,7 @@ var Channel = class {
|
|
|
10164
10339
|
})
|
|
10165
10340
|
};
|
|
10166
10341
|
this.getClient().polls.hydratePollCache(state.messages, true);
|
|
10342
|
+
this.getClient().reminders.hydrateState(state.messages);
|
|
10167
10343
|
if (state.draft) {
|
|
10168
10344
|
this.messageComposer.initState({ composition: state.draft });
|
|
10169
10345
|
}
|
|
@@ -11455,7 +11631,9 @@ var TokenManager = class {
|
|
|
11455
11631
|
try {
|
|
11456
11632
|
this.token = await this.tokenProvider();
|
|
11457
11633
|
} catch (e) {
|
|
11458
|
-
return reject(
|
|
11634
|
+
return reject(
|
|
11635
|
+
new Error(`Call to tokenProvider failed with message: ${e}`, { cause: e })
|
|
11636
|
+
);
|
|
11459
11637
|
}
|
|
11460
11638
|
resolve(this.token);
|
|
11461
11639
|
}
|
|
@@ -13205,6 +13383,458 @@ var NotificationManager = class {
|
|
|
13205
13383
|
}
|
|
13206
13384
|
};
|
|
13207
13385
|
|
|
13386
|
+
// src/reminders/ReminderTimer.ts
|
|
13387
|
+
var oneMinute = 60 * 1e3;
|
|
13388
|
+
var oneHour = 60 * oneMinute;
|
|
13389
|
+
var oneDay = 24 * oneHour;
|
|
13390
|
+
var oneWeek = 7 * oneDay;
|
|
13391
|
+
var GROUP_BOUNDS = {
|
|
13392
|
+
minute: { lower: oneMinute, upper: oneHour },
|
|
13393
|
+
hour: { lower: oneHour, upper: oneDay },
|
|
13394
|
+
day: { lower: oneDay, upper: oneWeek }
|
|
13395
|
+
};
|
|
13396
|
+
var DEFAULT_STOP_REFRESH_BOUNDARY_MS = 2 * oneWeek;
|
|
13397
|
+
var ReminderTimer = class {
|
|
13398
|
+
constructor({
|
|
13399
|
+
reminder,
|
|
13400
|
+
config
|
|
13401
|
+
}) {
|
|
13402
|
+
this.timeout = null;
|
|
13403
|
+
this.stopRefreshBoundaryMs = DEFAULT_STOP_REFRESH_BOUNDARY_MS;
|
|
13404
|
+
this.getRefreshIntervalLength = () => {
|
|
13405
|
+
if (!this.reminder.remindAt) return null;
|
|
13406
|
+
const distanceFromDeadlineMs = Math.abs(timeLeftMs(this.reminder.remindAt.getTime()));
|
|
13407
|
+
let refreshInterval;
|
|
13408
|
+
if (distanceFromDeadlineMs === 0) {
|
|
13409
|
+
refreshInterval = oneMinute;
|
|
13410
|
+
} else if (distanceFromDeadlineMs < GROUP_BOUNDS.minute.lower) {
|
|
13411
|
+
refreshInterval = distanceFromDeadlineMs;
|
|
13412
|
+
} else if (distanceFromDeadlineMs <= GROUP_BOUNDS.minute.upper) {
|
|
13413
|
+
refreshInterval = oneMinute;
|
|
13414
|
+
} else if (distanceFromDeadlineMs <= GROUP_BOUNDS.hour.upper) {
|
|
13415
|
+
refreshInterval = oneHour;
|
|
13416
|
+
} else {
|
|
13417
|
+
refreshInterval = oneDay;
|
|
13418
|
+
}
|
|
13419
|
+
return refreshInterval;
|
|
13420
|
+
};
|
|
13421
|
+
this.init = () => {
|
|
13422
|
+
if (!this.reminder.remindAt) return null;
|
|
13423
|
+
const timeoutLength = this.getRefreshIntervalLength();
|
|
13424
|
+
if (timeoutLength === null) return null;
|
|
13425
|
+
const boundaryTimestamp = this.reminder.remindAt?.getTime() + this.stopRefreshBoundaryMs;
|
|
13426
|
+
const timeLeftToBoundary = boundaryTimestamp - Date.now();
|
|
13427
|
+
if (timeLeftToBoundary <= 0) {
|
|
13428
|
+
this.timeout = null;
|
|
13429
|
+
return;
|
|
13430
|
+
}
|
|
13431
|
+
if (this.timeout) clearTimeout(this.timeout);
|
|
13432
|
+
this.timeout = setTimeout(() => {
|
|
13433
|
+
this.reminder.refreshTimeLeft();
|
|
13434
|
+
this.init();
|
|
13435
|
+
}, timeoutLength);
|
|
13436
|
+
};
|
|
13437
|
+
this.clear = () => {
|
|
13438
|
+
if (this.timeout) {
|
|
13439
|
+
clearInterval(this.timeout);
|
|
13440
|
+
this.timeout = null;
|
|
13441
|
+
}
|
|
13442
|
+
};
|
|
13443
|
+
this.reminder = reminder;
|
|
13444
|
+
if (typeof config?.stopRefreshBoundaryMs === "number") {
|
|
13445
|
+
this.stopRefreshBoundaryMs = config.stopRefreshBoundaryMs;
|
|
13446
|
+
}
|
|
13447
|
+
}
|
|
13448
|
+
};
|
|
13449
|
+
|
|
13450
|
+
// src/reminders/Reminder.ts
|
|
13451
|
+
var timeLeftMs = (remindAt) => remindAt - (/* @__PURE__ */ new Date()).getTime();
|
|
13452
|
+
var _Reminder = class _Reminder {
|
|
13453
|
+
constructor({ data, config }) {
|
|
13454
|
+
this.setState = (data) => {
|
|
13455
|
+
this.state.next((current) => {
|
|
13456
|
+
const newState = { ...current, ..._Reminder.toStateValue(data) };
|
|
13457
|
+
if (newState.remind_at) {
|
|
13458
|
+
newState.timeLeftMs = timeLeftMs(newState.remind_at.getTime());
|
|
13459
|
+
}
|
|
13460
|
+
return newState;
|
|
13461
|
+
});
|
|
13462
|
+
if (data.remind_at) {
|
|
13463
|
+
this.initTimer();
|
|
13464
|
+
} else if (!data.remind_at) {
|
|
13465
|
+
this.clearTimer();
|
|
13466
|
+
}
|
|
13467
|
+
};
|
|
13468
|
+
this.refreshTimeLeft = () => {
|
|
13469
|
+
if (!this.remindAt) return;
|
|
13470
|
+
this.state.partialNext({ timeLeftMs: timeLeftMs(this.remindAt.getTime()) });
|
|
13471
|
+
};
|
|
13472
|
+
this.initTimer = () => {
|
|
13473
|
+
this.timer.init();
|
|
13474
|
+
};
|
|
13475
|
+
this.clearTimer = () => {
|
|
13476
|
+
this.timer.clear();
|
|
13477
|
+
};
|
|
13478
|
+
this.state = new StateStore(_Reminder.toStateValue(data));
|
|
13479
|
+
this.timer = new ReminderTimer({ reminder: this, config });
|
|
13480
|
+
this.initTimer();
|
|
13481
|
+
}
|
|
13482
|
+
get id() {
|
|
13483
|
+
return this.state.getLatestValue().message_id;
|
|
13484
|
+
}
|
|
13485
|
+
get remindAt() {
|
|
13486
|
+
return this.state.getLatestValue().remind_at;
|
|
13487
|
+
}
|
|
13488
|
+
get timeLeftMs() {
|
|
13489
|
+
return this.state.getLatestValue().timeLeftMs;
|
|
13490
|
+
}
|
|
13491
|
+
};
|
|
13492
|
+
_Reminder.toStateValue = (data) => ({
|
|
13493
|
+
...data,
|
|
13494
|
+
created_at: new Date(data.created_at),
|
|
13495
|
+
message: data.message || null,
|
|
13496
|
+
remind_at: data.remind_at ? new Date(data.remind_at) : null,
|
|
13497
|
+
timeLeftMs: data.remind_at ? timeLeftMs(new Date(data.remind_at).getTime()) : null,
|
|
13498
|
+
updated_at: new Date(data.updated_at),
|
|
13499
|
+
user: data.user || null
|
|
13500
|
+
});
|
|
13501
|
+
var Reminder = _Reminder;
|
|
13502
|
+
|
|
13503
|
+
// src/pagination/BasePaginator.ts
|
|
13504
|
+
var DEFAULT_PAGINATION_OPTIONS = {
|
|
13505
|
+
debounceMs: 300,
|
|
13506
|
+
pageSize: 10
|
|
13507
|
+
};
|
|
13508
|
+
var BasePaginator = class {
|
|
13509
|
+
constructor(options) {
|
|
13510
|
+
this._isCursorPagination = false;
|
|
13511
|
+
this.setDebounceOptions = ({ debounceMs }) => {
|
|
13512
|
+
this._executeQueryDebounced = debounce(this.executeQuery.bind(this), debounceMs);
|
|
13513
|
+
};
|
|
13514
|
+
this.canExecuteQuery = (direction) => !this.isLoading && direction === "next" && this.hasNext || direction === "prev" && this.hasPrev;
|
|
13515
|
+
this.next = () => this.executeQuery({ direction: "next" });
|
|
13516
|
+
this.prev = () => this.executeQuery({ direction: "prev" });
|
|
13517
|
+
this.nextDebounced = () => {
|
|
13518
|
+
this._executeQueryDebounced({ direction: "next" });
|
|
13519
|
+
};
|
|
13520
|
+
this.prevDebounced = () => {
|
|
13521
|
+
this._executeQueryDebounced({ direction: "prev" });
|
|
13522
|
+
};
|
|
13523
|
+
const { debounceMs, pageSize } = { ...DEFAULT_PAGINATION_OPTIONS, ...options };
|
|
13524
|
+
this.pageSize = pageSize;
|
|
13525
|
+
this.state = new StateStore(this.initialState);
|
|
13526
|
+
this.setDebounceOptions({ debounceMs });
|
|
13527
|
+
}
|
|
13528
|
+
get lastQueryError() {
|
|
13529
|
+
return this.state.getLatestValue().lastQueryError;
|
|
13530
|
+
}
|
|
13531
|
+
get hasNext() {
|
|
13532
|
+
return this.state.getLatestValue().hasNext;
|
|
13533
|
+
}
|
|
13534
|
+
get hasPrev() {
|
|
13535
|
+
return this.state.getLatestValue().hasPrev;
|
|
13536
|
+
}
|
|
13537
|
+
get hasResults() {
|
|
13538
|
+
return Array.isArray(this.state.getLatestValue().items);
|
|
13539
|
+
}
|
|
13540
|
+
get isLoading() {
|
|
13541
|
+
return this.state.getLatestValue().isLoading;
|
|
13542
|
+
}
|
|
13543
|
+
get initialState() {
|
|
13544
|
+
return {
|
|
13545
|
+
hasNext: true,
|
|
13546
|
+
hasPrev: true,
|
|
13547
|
+
//todo: check if optimistic value does not cause problems in UI
|
|
13548
|
+
isLoading: false,
|
|
13549
|
+
items: void 0,
|
|
13550
|
+
lastQueryError: void 0,
|
|
13551
|
+
cursor: void 0,
|
|
13552
|
+
offset: 0
|
|
13553
|
+
};
|
|
13554
|
+
}
|
|
13555
|
+
get items() {
|
|
13556
|
+
return this.state.getLatestValue().items;
|
|
13557
|
+
}
|
|
13558
|
+
get cursor() {
|
|
13559
|
+
return this.state.getLatestValue().cursor;
|
|
13560
|
+
}
|
|
13561
|
+
get offset() {
|
|
13562
|
+
return this.state.getLatestValue().offset;
|
|
13563
|
+
}
|
|
13564
|
+
getStateBeforeFirstQuery() {
|
|
13565
|
+
return {
|
|
13566
|
+
...this.initialState,
|
|
13567
|
+
isLoading: true
|
|
13568
|
+
};
|
|
13569
|
+
}
|
|
13570
|
+
getStateAfterQuery(stateUpdate, isFirstPage) {
|
|
13571
|
+
const current = this.state.getLatestValue();
|
|
13572
|
+
return {
|
|
13573
|
+
...current,
|
|
13574
|
+
lastQueryError: void 0,
|
|
13575
|
+
// reset lastQueryError that can be overridden by the stateUpdate
|
|
13576
|
+
...stateUpdate,
|
|
13577
|
+
isLoading: false,
|
|
13578
|
+
items: isFirstPage ? stateUpdate.items : [...this.items ?? [], ...stateUpdate.items || []]
|
|
13579
|
+
};
|
|
13580
|
+
}
|
|
13581
|
+
async executeQuery({ direction }) {
|
|
13582
|
+
if (!this.canExecuteQuery(direction)) return;
|
|
13583
|
+
const isFirstPage = typeof this.items === "undefined";
|
|
13584
|
+
if (isFirstPage) {
|
|
13585
|
+
this.state.next(this.getStateBeforeFirstQuery());
|
|
13586
|
+
} else {
|
|
13587
|
+
this.state.partialNext({ isLoading: true });
|
|
13588
|
+
}
|
|
13589
|
+
const stateUpdate = {};
|
|
13590
|
+
try {
|
|
13591
|
+
const results = await this.query({ direction });
|
|
13592
|
+
if (!results) return;
|
|
13593
|
+
const { items, next, prev } = results;
|
|
13594
|
+
if (isFirstPage && (next || prev)) {
|
|
13595
|
+
this._isCursorPagination = true;
|
|
13596
|
+
}
|
|
13597
|
+
if (this._isCursorPagination) {
|
|
13598
|
+
stateUpdate.cursor = { next: next || null, prev: prev || null };
|
|
13599
|
+
stateUpdate.hasNext = !!next;
|
|
13600
|
+
stateUpdate.hasPrev = !!prev;
|
|
13601
|
+
} else {
|
|
13602
|
+
stateUpdate.offset = (this.offset ?? 0) + items.length;
|
|
13603
|
+
stateUpdate.hasNext = items.length === this.pageSize;
|
|
13604
|
+
}
|
|
13605
|
+
stateUpdate.items = await this.filterQueryResults(items);
|
|
13606
|
+
} catch (e) {
|
|
13607
|
+
stateUpdate.lastQueryError = e;
|
|
13608
|
+
} finally {
|
|
13609
|
+
this.state.next(this.getStateAfterQuery(stateUpdate, isFirstPage));
|
|
13610
|
+
}
|
|
13611
|
+
}
|
|
13612
|
+
cancelScheduledQuery() {
|
|
13613
|
+
this._executeQueryDebounced.cancel();
|
|
13614
|
+
}
|
|
13615
|
+
resetState() {
|
|
13616
|
+
this.state.next(this.initialState);
|
|
13617
|
+
}
|
|
13618
|
+
};
|
|
13619
|
+
|
|
13620
|
+
// src/pagination/ReminderPaginator.ts
|
|
13621
|
+
var ReminderPaginator = class extends BasePaginator {
|
|
13622
|
+
constructor(client, options) {
|
|
13623
|
+
super(options);
|
|
13624
|
+
this.query = async ({
|
|
13625
|
+
direction
|
|
13626
|
+
}) => {
|
|
13627
|
+
const cursor = this.cursor?.[direction];
|
|
13628
|
+
const {
|
|
13629
|
+
reminders: items,
|
|
13630
|
+
next,
|
|
13631
|
+
prev
|
|
13632
|
+
} = await this.client.queryReminders({
|
|
13633
|
+
filter: this.filters,
|
|
13634
|
+
sort: this.sort,
|
|
13635
|
+
limit: this.pageSize,
|
|
13636
|
+
[direction]: cursor
|
|
13637
|
+
});
|
|
13638
|
+
return { items, next, prev };
|
|
13639
|
+
};
|
|
13640
|
+
this.filterQueryResults = (items) => items;
|
|
13641
|
+
this.client = client;
|
|
13642
|
+
}
|
|
13643
|
+
};
|
|
13644
|
+
|
|
13645
|
+
// src/reminders/ReminderManager.ts
|
|
13646
|
+
var oneMinute2 = 60 * 1e3;
|
|
13647
|
+
var oneHour2 = 60 * oneMinute2;
|
|
13648
|
+
var oneDay2 = 24 * oneHour2;
|
|
13649
|
+
var DEFAULT_REMINDER_MANAGER_CONFIG = {
|
|
13650
|
+
scheduledOffsetsMs: [
|
|
13651
|
+
2 * oneMinute2,
|
|
13652
|
+
30 * oneMinute2,
|
|
13653
|
+
oneHour2,
|
|
13654
|
+
2 * oneHour2,
|
|
13655
|
+
8 * oneHour2,
|
|
13656
|
+
oneDay2
|
|
13657
|
+
]
|
|
13658
|
+
};
|
|
13659
|
+
var isReminderExistsError = (error) => error.message.match("already has reminder created for this message_id");
|
|
13660
|
+
var isReminderDoesNotExistError = (error) => error.message.match("reminder does not exist");
|
|
13661
|
+
var _ReminderManager = class _ReminderManager extends WithSubscriptions {
|
|
13662
|
+
constructor({ client, config }) {
|
|
13663
|
+
super();
|
|
13664
|
+
this.upsertToState = ({
|
|
13665
|
+
data,
|
|
13666
|
+
overwrite = true
|
|
13667
|
+
}) => {
|
|
13668
|
+
if (!this.client._cacheEnabled()) {
|
|
13669
|
+
return;
|
|
13670
|
+
}
|
|
13671
|
+
const cachedReminder = this.getFromState(data.message_id);
|
|
13672
|
+
if (!cachedReminder) {
|
|
13673
|
+
const reminder = new Reminder({
|
|
13674
|
+
data,
|
|
13675
|
+
config: { stopRefreshBoundaryMs: this.stopTimerRefreshBoundaryMs }
|
|
13676
|
+
});
|
|
13677
|
+
this.state.partialNext({
|
|
13678
|
+
reminders: new Map(this.reminders.set(data.message_id, reminder))
|
|
13679
|
+
});
|
|
13680
|
+
} else if (overwrite) {
|
|
13681
|
+
cachedReminder.setState(data);
|
|
13682
|
+
}
|
|
13683
|
+
return cachedReminder;
|
|
13684
|
+
};
|
|
13685
|
+
this.removeFromState = (messageId) => {
|
|
13686
|
+
const cachedReminder = this.getFromState(messageId);
|
|
13687
|
+
if (!cachedReminder) return;
|
|
13688
|
+
cachedReminder.clearTimer();
|
|
13689
|
+
const reminders = this.reminders;
|
|
13690
|
+
reminders.delete(messageId);
|
|
13691
|
+
this.state.partialNext({ reminders: new Map(reminders) });
|
|
13692
|
+
};
|
|
13693
|
+
this.hydrateState = (messages) => {
|
|
13694
|
+
messages.forEach(({ reminder }) => {
|
|
13695
|
+
if (reminder) {
|
|
13696
|
+
this.upsertToState({ data: reminder });
|
|
13697
|
+
}
|
|
13698
|
+
});
|
|
13699
|
+
};
|
|
13700
|
+
// State API END //
|
|
13701
|
+
// Timers API START //
|
|
13702
|
+
this.initTimers = () => {
|
|
13703
|
+
this.reminders.forEach((reminder) => reminder.initTimer());
|
|
13704
|
+
};
|
|
13705
|
+
this.clearTimers = () => {
|
|
13706
|
+
this.reminders.forEach((reminder) => reminder.clearTimer());
|
|
13707
|
+
};
|
|
13708
|
+
this.registerSubscriptions = () => {
|
|
13709
|
+
if (this.hasSubscriptions) return;
|
|
13710
|
+
this.addUnsubscribeFunction(this.subscribeReminderCreated());
|
|
13711
|
+
this.addUnsubscribeFunction(this.subscribeReminderUpdated());
|
|
13712
|
+
this.addUnsubscribeFunction(this.subscribeReminderDeleted());
|
|
13713
|
+
this.addUnsubscribeFunction(this.subscribeNotificationReminderDue());
|
|
13714
|
+
this.addUnsubscribeFunction(this.subscribeMessageDeleted());
|
|
13715
|
+
this.addUnsubscribeFunction(this.subscribeMessageUndeleted());
|
|
13716
|
+
this.addUnsubscribeFunction(this.subscribePaginatorStateUpdated());
|
|
13717
|
+
this.addUnsubscribeFunction(this.subscribeConfigStateUpdated());
|
|
13718
|
+
};
|
|
13719
|
+
this.subscribeReminderCreated = () => this.client.on("reminder.created", (event) => {
|
|
13720
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
13721
|
+
const { reminder } = event;
|
|
13722
|
+
this.upsertToState({ data: reminder });
|
|
13723
|
+
}).unsubscribe;
|
|
13724
|
+
this.subscribeReminderUpdated = () => this.client.on("reminder.updated", (event) => {
|
|
13725
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
13726
|
+
const { reminder } = event;
|
|
13727
|
+
this.upsertToState({ data: reminder });
|
|
13728
|
+
}).unsubscribe;
|
|
13729
|
+
this.subscribeReminderDeleted = () => this.client.on("reminder.deleted", (event) => {
|
|
13730
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
13731
|
+
this.removeFromState(event.message_id);
|
|
13732
|
+
}).unsubscribe;
|
|
13733
|
+
this.subscribeMessageDeleted = () => this.client.on("message.deleted", (event) => {
|
|
13734
|
+
if (!event.message?.id) return;
|
|
13735
|
+
this.removeFromState(event.message.id);
|
|
13736
|
+
}).unsubscribe;
|
|
13737
|
+
this.subscribeMessageUndeleted = () => this.client.on("message.undeleted", (event) => {
|
|
13738
|
+
if (!event.message?.reminder) return;
|
|
13739
|
+
this.upsertToState({ data: event.message.reminder });
|
|
13740
|
+
}).unsubscribe;
|
|
13741
|
+
this.subscribeNotificationReminderDue = () => this.client.on("notification.reminder_due", () => null).unsubscribe;
|
|
13742
|
+
// todo: what should be performed on this event?
|
|
13743
|
+
this.subscribePaginatorStateUpdated = () => this.paginator.state.subscribeWithSelector(
|
|
13744
|
+
({ items }) => [items],
|
|
13745
|
+
([items]) => {
|
|
13746
|
+
if (!items) return;
|
|
13747
|
+
for (const reminder of items) {
|
|
13748
|
+
this.upsertToState({ data: reminder });
|
|
13749
|
+
}
|
|
13750
|
+
}
|
|
13751
|
+
);
|
|
13752
|
+
this.subscribeConfigStateUpdated = () => this.configState.subscribeWithSelector(
|
|
13753
|
+
({ stopTimerRefreshBoundaryMs }) => ({ stopTimerRefreshBoundaryMs }),
|
|
13754
|
+
({ stopTimerRefreshBoundaryMs }, previousValue) => {
|
|
13755
|
+
if (typeof stopTimerRefreshBoundaryMs === "number" && stopTimerRefreshBoundaryMs !== previousValue?.stopTimerRefreshBoundaryMs) {
|
|
13756
|
+
this.reminders.forEach((reminder) => {
|
|
13757
|
+
if (reminder.timer) {
|
|
13758
|
+
reminder.timer.stopRefreshBoundaryMs = stopTimerRefreshBoundaryMs;
|
|
13759
|
+
}
|
|
13760
|
+
});
|
|
13761
|
+
}
|
|
13762
|
+
}
|
|
13763
|
+
);
|
|
13764
|
+
// WS event handling END //
|
|
13765
|
+
// API calls START //
|
|
13766
|
+
this.upsertReminder = async (options) => {
|
|
13767
|
+
const { messageId } = options;
|
|
13768
|
+
if (this.getFromState(messageId)) {
|
|
13769
|
+
try {
|
|
13770
|
+
return await this.updateReminder(options);
|
|
13771
|
+
} catch (error) {
|
|
13772
|
+
if (isReminderDoesNotExistError(error)) {
|
|
13773
|
+
return await this.createReminder(options);
|
|
13774
|
+
}
|
|
13775
|
+
throw error;
|
|
13776
|
+
}
|
|
13777
|
+
} else {
|
|
13778
|
+
try {
|
|
13779
|
+
return await this.createReminder(options);
|
|
13780
|
+
} catch (error) {
|
|
13781
|
+
if (isReminderExistsError(error)) {
|
|
13782
|
+
return await this.updateReminder(options);
|
|
13783
|
+
}
|
|
13784
|
+
throw error;
|
|
13785
|
+
}
|
|
13786
|
+
}
|
|
13787
|
+
};
|
|
13788
|
+
this.createReminder = async (options) => {
|
|
13789
|
+
const { reminder } = await this.client.createReminder(options);
|
|
13790
|
+
return this.upsertToState({ data: reminder, overwrite: false });
|
|
13791
|
+
};
|
|
13792
|
+
this.updateReminder = async (options) => {
|
|
13793
|
+
const { reminder } = await this.client.updateReminder(options);
|
|
13794
|
+
return this.upsertToState({ data: reminder });
|
|
13795
|
+
};
|
|
13796
|
+
this.deleteReminder = async (messageId) => {
|
|
13797
|
+
await this.client.deleteReminder(messageId);
|
|
13798
|
+
this.removeFromState(messageId);
|
|
13799
|
+
};
|
|
13800
|
+
this.queryNextReminders = async () => {
|
|
13801
|
+
await this.paginator.next();
|
|
13802
|
+
};
|
|
13803
|
+
this.queryPreviousReminders = async () => {
|
|
13804
|
+
await this.paginator.prev();
|
|
13805
|
+
};
|
|
13806
|
+
this.client = client;
|
|
13807
|
+
this.configState = new StateStore({
|
|
13808
|
+
scheduledOffsetsMs: config?.scheduledOffsetsMs ?? DEFAULT_REMINDER_MANAGER_CONFIG.scheduledOffsetsMs
|
|
13809
|
+
});
|
|
13810
|
+
this.state = new StateStore({ reminders: /* @__PURE__ */ new Map() });
|
|
13811
|
+
this.paginator = new ReminderPaginator(client);
|
|
13812
|
+
}
|
|
13813
|
+
// Config API START //
|
|
13814
|
+
updateConfig(config) {
|
|
13815
|
+
this.configState.partialNext(config);
|
|
13816
|
+
}
|
|
13817
|
+
get stopTimerRefreshBoundaryMs() {
|
|
13818
|
+
return this.configState.getLatestValue().stopTimerRefreshBoundaryMs;
|
|
13819
|
+
}
|
|
13820
|
+
get scheduledOffsetsMs() {
|
|
13821
|
+
return this.configState.getLatestValue().scheduledOffsetsMs;
|
|
13822
|
+
}
|
|
13823
|
+
// Config API END //
|
|
13824
|
+
// State API START //
|
|
13825
|
+
get reminders() {
|
|
13826
|
+
return this.state.getLatestValue().reminders;
|
|
13827
|
+
}
|
|
13828
|
+
getFromState(messageId) {
|
|
13829
|
+
return this.reminders.get(messageId);
|
|
13830
|
+
}
|
|
13831
|
+
// API calls END //
|
|
13832
|
+
};
|
|
13833
|
+
// Timers API END //
|
|
13834
|
+
// WS event handling START //
|
|
13835
|
+
_ReminderManager.isReminderWsEventPayload = (event) => !!event.reminder && (event.type.startsWith("reminder.") || event.type === "notification.reminder_due");
|
|
13836
|
+
var ReminderManager = _ReminderManager;
|
|
13837
|
+
|
|
13208
13838
|
// src/client.ts
|
|
13209
13839
|
function isString3(x) {
|
|
13210
13840
|
return typeof x === "string" || x instanceof String;
|
|
@@ -13220,6 +13850,9 @@ var StreamChat = class _StreamChat {
|
|
|
13220
13850
|
});
|
|
13221
13851
|
this._getConnectionID = () => this.wsConnection?.connectionID || this.wsFallback?.connectionID;
|
|
13222
13852
|
this._hasConnectionID = () => Boolean(this._getConnectionID());
|
|
13853
|
+
this.setMessageComposerSetupFunction = (setupFunction) => {
|
|
13854
|
+
this._messageComposerSetupState.partialNext({ setupFunction });
|
|
13855
|
+
};
|
|
13223
13856
|
/**
|
|
13224
13857
|
* connectUser - Set the current user and open a WebSocket connection
|
|
13225
13858
|
*
|
|
@@ -13788,9 +14421,6 @@ var StreamChat = class _StreamChat {
|
|
|
13788
14421
|
device: this.options.device,
|
|
13789
14422
|
client_request_id
|
|
13790
14423
|
});
|
|
13791
|
-
this.setMessageComposerSetupFunction = (setupFunction) => {
|
|
13792
|
-
this._messageComposerSetupState.partialNext({ setupFunction });
|
|
13793
|
-
};
|
|
13794
14424
|
this.key = key;
|
|
13795
14425
|
this.listeners = {};
|
|
13796
14426
|
this.state = new ClientState({ client: this });
|
|
@@ -13845,6 +14475,7 @@ var StreamChat = class _StreamChat {
|
|
|
13845
14475
|
this.recoverStateOnReconnect = this.options.recoverStateOnReconnect;
|
|
13846
14476
|
this.threads = new ThreadManager({ client: this });
|
|
13847
14477
|
this.polls = new PollManager({ client: this });
|
|
14478
|
+
this.reminders = new ReminderManager({ client: this });
|
|
13848
14479
|
}
|
|
13849
14480
|
static getInstance(key, secretOrOptions, options) {
|
|
13850
14481
|
if (!_StreamChat._instance) {
|
|
@@ -13980,15 +14611,15 @@ var StreamChat = class _StreamChat {
|
|
|
13980
14611
|
* @param {string} userID User ID. If user has no devices, it will error
|
|
13981
14612
|
* @param {TestPushDataInput} [data] Overrides for push templates/message used
|
|
13982
14613
|
* IE: {
|
|
13983
|
-
|
|
13984
|
-
|
|
13985
|
-
|
|
13986
|
-
|
|
13987
|
-
|
|
13988
|
-
|
|
13989
|
-
|
|
13990
|
-
|
|
13991
|
-
|
|
14614
|
+
messageID: 'id-of-message', // will error if message does not exist
|
|
14615
|
+
apnTemplate: '{}', // if app doesn't have apn configured it will error
|
|
14616
|
+
firebaseTemplate: '{}', // if app doesn't have firebase configured it will error
|
|
14617
|
+
firebaseDataTemplate: '{}', // if app doesn't have firebase configured it will error
|
|
14618
|
+
skipDevices: true, // skip config/device checks and sending to real devices
|
|
14619
|
+
pushProviderName: 'staging' // one of your configured push providers
|
|
14620
|
+
pushProviderType: 'apn' // one of supported provider types
|
|
14621
|
+
}
|
|
14622
|
+
*/
|
|
13992
14623
|
async testPushSettings(userID, data = {}) {
|
|
13993
14624
|
return await this.post(this.baseURL + "/check_push", {
|
|
13994
14625
|
user_id: userID,
|
|
@@ -14006,10 +14637,10 @@ var StreamChat = class _StreamChat {
|
|
|
14006
14637
|
*
|
|
14007
14638
|
* @param {TestSQSDataInput} [data] Overrides SQS settings for testing if needed
|
|
14008
14639
|
* IE: {
|
|
14009
|
-
|
|
14010
|
-
|
|
14011
|
-
|
|
14012
|
-
|
|
14640
|
+
sqs_key: 'auth_key',
|
|
14641
|
+
sqs_secret: 'auth_secret',
|
|
14642
|
+
sqs_url: 'url_to_queue',
|
|
14643
|
+
}
|
|
14013
14644
|
*/
|
|
14014
14645
|
async testSQSSettings(data = {}) {
|
|
14015
14646
|
return await this.post(this.baseURL + "/check_sqs", data);
|
|
@@ -14019,10 +14650,10 @@ var StreamChat = class _StreamChat {
|
|
|
14019
14650
|
*
|
|
14020
14651
|
* @param {TestSNSDataInput} [data] Overrides SNS settings for testing if needed
|
|
14021
14652
|
* IE: {
|
|
14022
|
-
|
|
14023
|
-
|
|
14024
|
-
|
|
14025
|
-
|
|
14653
|
+
sns_key: 'auth_key',
|
|
14654
|
+
sns_secret: 'auth_secret',
|
|
14655
|
+
sns_topic_arn: 'topic_to_publish_to',
|
|
14656
|
+
}
|
|
14026
14657
|
*/
|
|
14027
14658
|
async testSNSSettings(data = {}) {
|
|
14028
14659
|
return await this.post(this.baseURL + "/check_sns", data);
|
|
@@ -14503,6 +15134,7 @@ var StreamChat = class _StreamChat {
|
|
|
14503
15134
|
})
|
|
14504
15135
|
};
|
|
14505
15136
|
this.polls.hydratePollCache(channelState.messages, true);
|
|
15137
|
+
this.reminders.hydrateState(channelState.messages);
|
|
14506
15138
|
}
|
|
14507
15139
|
if (channelState.draft) {
|
|
14508
15140
|
c.messageComposer.initState({ composition: channelState.draft });
|
|
@@ -15423,7 +16055,7 @@ var StreamChat = class _StreamChat {
|
|
|
15423
16055
|
if (this.userAgent) {
|
|
15424
16056
|
return this.userAgent;
|
|
15425
16057
|
}
|
|
15426
|
-
const version = "9.
|
|
16058
|
+
const version = "9.5.0";
|
|
15427
16059
|
const clientBundle = "browser-esm";
|
|
15428
16060
|
let userAgentString = "";
|
|
15429
16061
|
if (this.sdkIdentifier) {
|
|
@@ -16462,6 +17094,56 @@ var StreamChat = class _StreamChat {
|
|
|
16462
17094
|
};
|
|
16463
17095
|
return await this.post(this.baseURL + "/drafts/query", payload);
|
|
16464
17096
|
}
|
|
17097
|
+
/**
|
|
17098
|
+
* createReminder - Creates a reminder for a message
|
|
17099
|
+
*
|
|
17100
|
+
* @param {CreateReminderOptions} options The options for creating the reminder
|
|
17101
|
+
* @returns {Promise<ReminderAPIResponse>}
|
|
17102
|
+
*/
|
|
17103
|
+
async createReminder({ messageId, ...options }) {
|
|
17104
|
+
return await this.post(
|
|
17105
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
17106
|
+
options
|
|
17107
|
+
);
|
|
17108
|
+
}
|
|
17109
|
+
/**
|
|
17110
|
+
* updateReminder - Updates an existing reminder for a message
|
|
17111
|
+
*
|
|
17112
|
+
* @param {UpdateReminderOptions} options The options for updating the reminder
|
|
17113
|
+
* @returns {Promise<ReminderAPIResponse>}
|
|
17114
|
+
*/
|
|
17115
|
+
async updateReminder({ messageId, ...options }) {
|
|
17116
|
+
return await this.patch(
|
|
17117
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
17118
|
+
options
|
|
17119
|
+
);
|
|
17120
|
+
}
|
|
17121
|
+
/**
|
|
17122
|
+
* deleteReminder - Deletes a reminder for a message
|
|
17123
|
+
*
|
|
17124
|
+
* @param {string} messageId The ID of the message whose reminder to delete
|
|
17125
|
+
* @param {string} [userId] Optional user ID, required for server-side operations
|
|
17126
|
+
* @returns {Promise<APIResponse>}
|
|
17127
|
+
*/
|
|
17128
|
+
async deleteReminder(messageId, userId) {
|
|
17129
|
+
return await this.delete(
|
|
17130
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
17131
|
+
userId ? { user_id: userId } : {}
|
|
17132
|
+
);
|
|
17133
|
+
}
|
|
17134
|
+
/**
|
|
17135
|
+
* queryReminders - Queries reminders based on given filters
|
|
17136
|
+
*
|
|
17137
|
+
* @param {QueryRemindersOptions} options The options for querying reminders
|
|
17138
|
+
* @returns {Promise<QueryRemindersResponse>}
|
|
17139
|
+
*/
|
|
17140
|
+
async queryReminders({ filter: filter2, sort, ...rest } = {}) {
|
|
17141
|
+
return await this.post(`${this.baseURL}/reminders/query`, {
|
|
17142
|
+
filter_conditions: filter2,
|
|
17143
|
+
sort: sort && normalizeQuerySort(sort),
|
|
17144
|
+
...rest
|
|
17145
|
+
});
|
|
17146
|
+
}
|
|
16465
17147
|
};
|
|
16466
17148
|
|
|
16467
17149
|
// src/events.ts
|
|
@@ -16528,7 +17210,12 @@ var EVENT_MAP = {
|
|
|
16528
17210
|
"connection.changed": true,
|
|
16529
17211
|
"connection.recovered": true,
|
|
16530
17212
|
"transport.changed": true,
|
|
16531
|
-
"capabilities.changed": true
|
|
17213
|
+
"capabilities.changed": true,
|
|
17214
|
+
// Reminder events
|
|
17215
|
+
"reminder.created": true,
|
|
17216
|
+
"reminder.updated": true,
|
|
17217
|
+
"reminder.deleted": true,
|
|
17218
|
+
"notification.reminder_due": true
|
|
16532
17219
|
};
|
|
16533
17220
|
|
|
16534
17221
|
// src/permissions.ts
|
|
@@ -17400,6 +18087,7 @@ export {
|
|
|
17400
18087
|
AnyResource,
|
|
17401
18088
|
AnyRole,
|
|
17402
18089
|
AttachmentManager,
|
|
18090
|
+
BasePaginator,
|
|
17403
18091
|
BaseSearchSource,
|
|
17404
18092
|
BuiltinPermissions,
|
|
17405
18093
|
BuiltinRoles,
|
|
@@ -17417,6 +18105,9 @@ export {
|
|
|
17417
18105
|
DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS,
|
|
17418
18106
|
DEFAULT_COMPOSER_CONFIG,
|
|
17419
18107
|
DEFAULT_LINK_PREVIEW_MANAGER_CONFIG,
|
|
18108
|
+
DEFAULT_PAGINATION_OPTIONS,
|
|
18109
|
+
DEFAULT_REMINDER_MANAGER_CONFIG,
|
|
18110
|
+
DEFAULT_STOP_REFRESH_BOUNDARY_MS,
|
|
17420
18111
|
DEFAULT_TEXT_COMPOSER_CONFIG,
|
|
17421
18112
|
Deny,
|
|
17422
18113
|
DenyAll,
|
|
@@ -17433,6 +18124,7 @@ export {
|
|
|
17433
18124
|
MODERATION_ENTITY_TYPES,
|
|
17434
18125
|
MaxPriority,
|
|
17435
18126
|
MentionsSearchSource,
|
|
18127
|
+
MergedStateStore,
|
|
17436
18128
|
MessageComposer,
|
|
17437
18129
|
MessageComposerMiddlewareExecutor,
|
|
17438
18130
|
MessageDraftComposerMiddlewareExecutor,
|
|
@@ -17448,6 +18140,10 @@ export {
|
|
|
17448
18140
|
PollComposerCompositionMiddlewareExecutor,
|
|
17449
18141
|
PollComposerStateMiddlewareExecutor,
|
|
17450
18142
|
PollManager,
|
|
18143
|
+
Reminder,
|
|
18144
|
+
ReminderManager,
|
|
18145
|
+
ReminderPaginator,
|
|
18146
|
+
ReminderTimer,
|
|
17451
18147
|
SearchController,
|
|
17452
18148
|
Segment,
|
|
17453
18149
|
StableWSConnection,
|
|
@@ -17535,6 +18231,7 @@ export {
|
|
|
17535
18231
|
readFileAsArrayBuffer,
|
|
17536
18232
|
removeDiacritics,
|
|
17537
18233
|
replaceWordWithEntity,
|
|
17538
|
-
textIsEmpty
|
|
18234
|
+
textIsEmpty,
|
|
18235
|
+
timeLeftMs
|
|
17539
18236
|
};
|
|
17540
18237
|
//# sourceMappingURL=index.js.map
|