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
package/dist/cjs/index.node.cjs
CHANGED
|
@@ -10670,6 +10670,7 @@ __export(index_exports, {
|
|
|
10670
10670
|
AnyResource: () => AnyResource,
|
|
10671
10671
|
AnyRole: () => AnyRole,
|
|
10672
10672
|
AttachmentManager: () => AttachmentManager,
|
|
10673
|
+
BasePaginator: () => BasePaginator,
|
|
10673
10674
|
BaseSearchSource: () => BaseSearchSource,
|
|
10674
10675
|
BuiltinPermissions: () => BuiltinPermissions,
|
|
10675
10676
|
BuiltinRoles: () => BuiltinRoles,
|
|
@@ -10687,6 +10688,9 @@ __export(index_exports, {
|
|
|
10687
10688
|
DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS: () => DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS,
|
|
10688
10689
|
DEFAULT_COMPOSER_CONFIG: () => DEFAULT_COMPOSER_CONFIG,
|
|
10689
10690
|
DEFAULT_LINK_PREVIEW_MANAGER_CONFIG: () => DEFAULT_LINK_PREVIEW_MANAGER_CONFIG,
|
|
10691
|
+
DEFAULT_PAGINATION_OPTIONS: () => DEFAULT_PAGINATION_OPTIONS,
|
|
10692
|
+
DEFAULT_REMINDER_MANAGER_CONFIG: () => DEFAULT_REMINDER_MANAGER_CONFIG,
|
|
10693
|
+
DEFAULT_STOP_REFRESH_BOUNDARY_MS: () => DEFAULT_STOP_REFRESH_BOUNDARY_MS,
|
|
10690
10694
|
DEFAULT_TEXT_COMPOSER_CONFIG: () => DEFAULT_TEXT_COMPOSER_CONFIG,
|
|
10691
10695
|
Deny: () => Deny,
|
|
10692
10696
|
DenyAll: () => DenyAll,
|
|
@@ -10719,6 +10723,10 @@ __export(index_exports, {
|
|
|
10719
10723
|
PollComposerCompositionMiddlewareExecutor: () => PollComposerCompositionMiddlewareExecutor,
|
|
10720
10724
|
PollComposerStateMiddlewareExecutor: () => PollComposerStateMiddlewareExecutor,
|
|
10721
10725
|
PollManager: () => PollManager,
|
|
10726
|
+
Reminder: () => Reminder,
|
|
10727
|
+
ReminderManager: () => ReminderManager,
|
|
10728
|
+
ReminderPaginator: () => ReminderPaginator,
|
|
10729
|
+
ReminderTimer: () => ReminderTimer,
|
|
10722
10730
|
SearchController: () => SearchController,
|
|
10723
10731
|
Segment: () => Segment,
|
|
10724
10732
|
StableWSConnection: () => StableWSConnection,
|
|
@@ -10806,7 +10814,8 @@ __export(index_exports, {
|
|
|
10806
10814
|
readFileAsArrayBuffer: () => readFileAsArrayBuffer,
|
|
10807
10815
|
removeDiacritics: () => removeDiacritics,
|
|
10808
10816
|
replaceWordWithEntity: () => replaceWordWithEntity,
|
|
10809
|
-
textIsEmpty: () => textIsEmpty
|
|
10817
|
+
textIsEmpty: () => textIsEmpty,
|
|
10818
|
+
timeLeftMs: () => timeLeftMs
|
|
10810
10819
|
});
|
|
10811
10820
|
module.exports = __toCommonJS(index_exports);
|
|
10812
10821
|
|
|
@@ -16774,15 +16783,14 @@ var pollStateChangeValidators = {
|
|
|
16774
16783
|
return { max_votes_allowed: "Type a number from 2 to 10" };
|
|
16775
16784
|
return { max_votes_allowed: void 0 };
|
|
16776
16785
|
},
|
|
16777
|
-
options: ({ value }) => {
|
|
16786
|
+
options: ({ value: options }) => {
|
|
16778
16787
|
const errors = {};
|
|
16779
16788
|
const seenOptions = /* @__PURE__ */ new Set();
|
|
16780
|
-
|
|
16781
|
-
|
|
16782
|
-
if (seenOptions.has(trimmedText)) {
|
|
16789
|
+
options.forEach((option) => {
|
|
16790
|
+
if (seenOptions.has(option.text) && option.text.length) {
|
|
16783
16791
|
errors[option.id] = "Option already exists";
|
|
16784
16792
|
} else {
|
|
16785
|
-
seenOptions.add(
|
|
16793
|
+
seenOptions.add(option.text);
|
|
16786
16794
|
}
|
|
16787
16795
|
});
|
|
16788
16796
|
return Object.keys(errors).length > 0 ? { options: errors } : { options: void 0 };
|
|
@@ -17135,13 +17143,13 @@ var PollComposer = class {
|
|
|
17135
17143
|
}
|
|
17136
17144
|
get canCreatePoll() {
|
|
17137
17145
|
const { data, errors } = this.state.getLatestValue();
|
|
17138
|
-
const
|
|
17146
|
+
const hasAtLeastOneNonEmptyOption = data.options.filter((o) => !!o.text.trim()).length > 0;
|
|
17139
17147
|
const hasName = !!data.name;
|
|
17140
17148
|
const maxVotesAllowedNumber = parseInt(
|
|
17141
17149
|
data.max_votes_allowed?.match(VALID_MAX_VOTES_VALUE_REGEX)?.[0] || ""
|
|
17142
17150
|
);
|
|
17143
17151
|
const validMaxVotesAllowed = data.max_votes_allowed === "" || !!maxVotesAllowedNumber && (2 <= maxVotesAllowedNumber || maxVotesAllowedNumber <= 10);
|
|
17144
|
-
return
|
|
17152
|
+
return hasAtLeastOneNonEmptyOption && hasName && validMaxVotesAllowed && Object.values(errors).filter((errorText) => !!errorText).length === 0;
|
|
17145
17153
|
}
|
|
17146
17154
|
};
|
|
17147
17155
|
|
|
@@ -17584,7 +17592,7 @@ var MessageDraftComposerMiddlewareExecutor = class extends MiddlewareExecutor {
|
|
|
17584
17592
|
}
|
|
17585
17593
|
};
|
|
17586
17594
|
|
|
17587
|
-
// src/
|
|
17595
|
+
// src/search/BaseSearchSource.ts
|
|
17588
17596
|
var DEFAULT_SEARCH_SOURCE_OPTIONS = {
|
|
17589
17597
|
debounceMs: 300,
|
|
17590
17598
|
pageSize: 10
|
|
@@ -17710,6 +17718,112 @@ var BaseSearchSource = class {
|
|
|
17710
17718
|
this.activate();
|
|
17711
17719
|
}
|
|
17712
17720
|
};
|
|
17721
|
+
|
|
17722
|
+
// src/search/SearchController.ts
|
|
17723
|
+
var SearchController = class {
|
|
17724
|
+
constructor({ config, sources } = {}) {
|
|
17725
|
+
this.addSource = (source) => {
|
|
17726
|
+
this.state.partialNext({
|
|
17727
|
+
sources: [...this.sources, source]
|
|
17728
|
+
});
|
|
17729
|
+
};
|
|
17730
|
+
this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
|
|
17731
|
+
this.removeSource = (sourceType) => {
|
|
17732
|
+
const newSources = this.sources.filter((s) => s.type !== sourceType);
|
|
17733
|
+
if (newSources.length === this.sources.length) return;
|
|
17734
|
+
this.state.partialNext({ sources: newSources });
|
|
17735
|
+
};
|
|
17736
|
+
this.activateSource = (sourceType) => {
|
|
17737
|
+
const source = this.getSource(sourceType);
|
|
17738
|
+
if (!source || source.isActive) return;
|
|
17739
|
+
if (this.config.keepSingleActiveSource) {
|
|
17740
|
+
this.sources.forEach((s) => {
|
|
17741
|
+
if (s.type !== sourceType) {
|
|
17742
|
+
s.deactivate();
|
|
17743
|
+
}
|
|
17744
|
+
});
|
|
17745
|
+
}
|
|
17746
|
+
source.activate();
|
|
17747
|
+
this.state.partialNext({ sources: [...this.sources] });
|
|
17748
|
+
};
|
|
17749
|
+
this.deactivateSource = (sourceType) => {
|
|
17750
|
+
const source = this.getSource(sourceType);
|
|
17751
|
+
if (!source?.isActive) return;
|
|
17752
|
+
if (this.activeSources.length === 1) return;
|
|
17753
|
+
source.deactivate();
|
|
17754
|
+
this.state.partialNext({ sources: [...this.sources] });
|
|
17755
|
+
};
|
|
17756
|
+
this.activate = () => {
|
|
17757
|
+
if (!this.activeSources.length) {
|
|
17758
|
+
const sourcesToActivate = this.config.keepSingleActiveSource ? this.sources.slice(0, 1) : this.sources;
|
|
17759
|
+
sourcesToActivate.forEach((s) => s.activate());
|
|
17760
|
+
}
|
|
17761
|
+
if (this.isActive) return;
|
|
17762
|
+
this.state.partialNext({ isActive: true });
|
|
17763
|
+
};
|
|
17764
|
+
this.search = async (searchQuery) => {
|
|
17765
|
+
const searchedSources = this.activeSources;
|
|
17766
|
+
this.state.partialNext({
|
|
17767
|
+
searchQuery
|
|
17768
|
+
});
|
|
17769
|
+
await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
|
|
17770
|
+
};
|
|
17771
|
+
this.cancelSearchQueries = () => {
|
|
17772
|
+
this.activeSources.forEach((s) => s.cancelScheduledQuery());
|
|
17773
|
+
};
|
|
17774
|
+
this.clear = () => {
|
|
17775
|
+
this.cancelSearchQueries();
|
|
17776
|
+
this.sources.forEach(
|
|
17777
|
+
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
17778
|
+
);
|
|
17779
|
+
this.state.next((current) => ({
|
|
17780
|
+
...current,
|
|
17781
|
+
isActive: true,
|
|
17782
|
+
queriesInProgress: [],
|
|
17783
|
+
searchQuery: ""
|
|
17784
|
+
}));
|
|
17785
|
+
};
|
|
17786
|
+
this.exit = () => {
|
|
17787
|
+
this.cancelSearchQueries();
|
|
17788
|
+
this.sources.forEach(
|
|
17789
|
+
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
17790
|
+
);
|
|
17791
|
+
this.state.next((current) => ({
|
|
17792
|
+
...current,
|
|
17793
|
+
isActive: false,
|
|
17794
|
+
queriesInProgress: [],
|
|
17795
|
+
searchQuery: ""
|
|
17796
|
+
}));
|
|
17797
|
+
};
|
|
17798
|
+
this.state = new StateStore({
|
|
17799
|
+
isActive: false,
|
|
17800
|
+
searchQuery: "",
|
|
17801
|
+
sources: sources ?? []
|
|
17802
|
+
});
|
|
17803
|
+
this._internalState = new StateStore({});
|
|
17804
|
+
this.config = { keepSingleActiveSource: true, ...config };
|
|
17805
|
+
}
|
|
17806
|
+
get hasNext() {
|
|
17807
|
+
return this.sources.some((source) => source.hasNext);
|
|
17808
|
+
}
|
|
17809
|
+
get sources() {
|
|
17810
|
+
return this.state.getLatestValue().sources;
|
|
17811
|
+
}
|
|
17812
|
+
get activeSources() {
|
|
17813
|
+
return this.state.getLatestValue().sources.filter((s) => s.isActive);
|
|
17814
|
+
}
|
|
17815
|
+
get isActive() {
|
|
17816
|
+
return this.state.getLatestValue().isActive;
|
|
17817
|
+
}
|
|
17818
|
+
get searchQuery() {
|
|
17819
|
+
return this.state.getLatestValue().searchQuery;
|
|
17820
|
+
}
|
|
17821
|
+
get searchSourceTypes() {
|
|
17822
|
+
return this.sources.map((s) => s.type);
|
|
17823
|
+
}
|
|
17824
|
+
};
|
|
17825
|
+
|
|
17826
|
+
// src/search/UserSearchSource.ts
|
|
17713
17827
|
var UserSearchSource = class extends BaseSearchSource {
|
|
17714
17828
|
constructor(client, options) {
|
|
17715
17829
|
super(options);
|
|
@@ -17733,6 +17847,8 @@ var UserSearchSource = class extends BaseSearchSource {
|
|
|
17733
17847
|
return items.filter((u) => u.id !== this.client.user?.id);
|
|
17734
17848
|
}
|
|
17735
17849
|
};
|
|
17850
|
+
|
|
17851
|
+
// src/search/ChannelSearchSource.ts
|
|
17736
17852
|
var ChannelSearchSource = class extends BaseSearchSource {
|
|
17737
17853
|
constructor(client, options) {
|
|
17738
17854
|
super(options);
|
|
@@ -17754,6 +17870,8 @@ var ChannelSearchSource = class extends BaseSearchSource {
|
|
|
17754
17870
|
return items;
|
|
17755
17871
|
}
|
|
17756
17872
|
};
|
|
17873
|
+
|
|
17874
|
+
// src/search/MessageSearchSource.ts
|
|
17757
17875
|
var MessageSearchSource = class extends BaseSearchSource {
|
|
17758
17876
|
constructor(client, options) {
|
|
17759
17877
|
super(options);
|
|
@@ -17814,108 +17932,6 @@ var MessageSearchSource = class extends BaseSearchSource {
|
|
|
17814
17932
|
return items;
|
|
17815
17933
|
}
|
|
17816
17934
|
};
|
|
17817
|
-
var SearchController = class {
|
|
17818
|
-
constructor({ config, sources } = {}) {
|
|
17819
|
-
this.addSource = (source) => {
|
|
17820
|
-
this.state.partialNext({
|
|
17821
|
-
sources: [...this.sources, source]
|
|
17822
|
-
});
|
|
17823
|
-
};
|
|
17824
|
-
this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
|
|
17825
|
-
this.removeSource = (sourceType) => {
|
|
17826
|
-
const newSources = this.sources.filter((s) => s.type !== sourceType);
|
|
17827
|
-
if (newSources.length === this.sources.length) return;
|
|
17828
|
-
this.state.partialNext({ sources: newSources });
|
|
17829
|
-
};
|
|
17830
|
-
this.activateSource = (sourceType) => {
|
|
17831
|
-
const source = this.getSource(sourceType);
|
|
17832
|
-
if (!source || source.isActive) return;
|
|
17833
|
-
if (this.config.keepSingleActiveSource) {
|
|
17834
|
-
this.sources.forEach((s) => {
|
|
17835
|
-
if (s.type !== sourceType) {
|
|
17836
|
-
s.deactivate();
|
|
17837
|
-
}
|
|
17838
|
-
});
|
|
17839
|
-
}
|
|
17840
|
-
source.activate();
|
|
17841
|
-
this.state.partialNext({ sources: [...this.sources] });
|
|
17842
|
-
};
|
|
17843
|
-
this.deactivateSource = (sourceType) => {
|
|
17844
|
-
const source = this.getSource(sourceType);
|
|
17845
|
-
if (!source?.isActive) return;
|
|
17846
|
-
if (this.activeSources.length === 1) return;
|
|
17847
|
-
source.deactivate();
|
|
17848
|
-
this.state.partialNext({ sources: [...this.sources] });
|
|
17849
|
-
};
|
|
17850
|
-
this.activate = () => {
|
|
17851
|
-
if (!this.activeSources.length) {
|
|
17852
|
-
const sourcesToActivate = this.config.keepSingleActiveSource ? this.sources.slice(0, 1) : this.sources;
|
|
17853
|
-
sourcesToActivate.forEach((s) => s.activate());
|
|
17854
|
-
}
|
|
17855
|
-
if (this.isActive) return;
|
|
17856
|
-
this.state.partialNext({ isActive: true });
|
|
17857
|
-
};
|
|
17858
|
-
this.search = async (searchQuery) => {
|
|
17859
|
-
const searchedSources = this.activeSources;
|
|
17860
|
-
this.state.partialNext({
|
|
17861
|
-
searchQuery
|
|
17862
|
-
});
|
|
17863
|
-
await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
|
|
17864
|
-
};
|
|
17865
|
-
this.cancelSearchQueries = () => {
|
|
17866
|
-
this.activeSources.forEach((s) => s.cancelScheduledQuery());
|
|
17867
|
-
};
|
|
17868
|
-
this.clear = () => {
|
|
17869
|
-
this.cancelSearchQueries();
|
|
17870
|
-
this.sources.forEach(
|
|
17871
|
-
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
17872
|
-
);
|
|
17873
|
-
this.state.next((current) => ({
|
|
17874
|
-
...current,
|
|
17875
|
-
isActive: true,
|
|
17876
|
-
queriesInProgress: [],
|
|
17877
|
-
searchQuery: ""
|
|
17878
|
-
}));
|
|
17879
|
-
};
|
|
17880
|
-
this.exit = () => {
|
|
17881
|
-
this.cancelSearchQueries();
|
|
17882
|
-
this.sources.forEach(
|
|
17883
|
-
(source) => source.state.next({ ...source.initialState, isActive: source.isActive })
|
|
17884
|
-
);
|
|
17885
|
-
this.state.next((current) => ({
|
|
17886
|
-
...current,
|
|
17887
|
-
isActive: false,
|
|
17888
|
-
queriesInProgress: [],
|
|
17889
|
-
searchQuery: ""
|
|
17890
|
-
}));
|
|
17891
|
-
};
|
|
17892
|
-
this.state = new StateStore({
|
|
17893
|
-
isActive: false,
|
|
17894
|
-
searchQuery: "",
|
|
17895
|
-
sources: sources ?? []
|
|
17896
|
-
});
|
|
17897
|
-
this._internalState = new StateStore({});
|
|
17898
|
-
this.config = { keepSingleActiveSource: true, ...config };
|
|
17899
|
-
}
|
|
17900
|
-
get hasNext() {
|
|
17901
|
-
return this.sources.some((source) => source.hasNext);
|
|
17902
|
-
}
|
|
17903
|
-
get sources() {
|
|
17904
|
-
return this.state.getLatestValue().sources;
|
|
17905
|
-
}
|
|
17906
|
-
get activeSources() {
|
|
17907
|
-
return this.state.getLatestValue().sources.filter((s) => s.isActive);
|
|
17908
|
-
}
|
|
17909
|
-
get isActive() {
|
|
17910
|
-
return this.state.getLatestValue().isActive;
|
|
17911
|
-
}
|
|
17912
|
-
get searchQuery() {
|
|
17913
|
-
return this.state.getLatestValue().searchQuery;
|
|
17914
|
-
}
|
|
17915
|
-
get searchSourceTypes() {
|
|
17916
|
-
return this.sources.map((s) => s.type);
|
|
17917
|
-
}
|
|
17918
|
-
};
|
|
17919
17935
|
|
|
17920
17936
|
// src/messageComposer/middleware/textComposer/textMiddlewareUtils.ts
|
|
17921
17937
|
var getTriggerCharWithToken = ({
|
|
@@ -20694,6 +20710,7 @@ var Channel = class {
|
|
|
20694
20710
|
})
|
|
20695
20711
|
};
|
|
20696
20712
|
this.getClient().polls.hydratePollCache(state.messages, true);
|
|
20713
|
+
this.getClient().reminders.hydrateState(state.messages);
|
|
20697
20714
|
if (state.draft) {
|
|
20698
20715
|
this.messageComposer.initState({ composition: state.draft });
|
|
20699
20716
|
}
|
|
@@ -21973,7 +21990,9 @@ var TokenManager = class {
|
|
|
21973
21990
|
try {
|
|
21974
21991
|
this.token = await this.tokenProvider();
|
|
21975
21992
|
} catch (e) {
|
|
21976
|
-
return reject(
|
|
21993
|
+
return reject(
|
|
21994
|
+
new Error(`Call to tokenProvider failed with message: ${e}`, { cause: e })
|
|
21995
|
+
);
|
|
21977
21996
|
}
|
|
21978
21997
|
resolve(this.token);
|
|
21979
21998
|
}
|
|
@@ -23723,6 +23742,458 @@ var NotificationManager = class {
|
|
|
23723
23742
|
}
|
|
23724
23743
|
};
|
|
23725
23744
|
|
|
23745
|
+
// src/reminders/ReminderTimer.ts
|
|
23746
|
+
var oneMinute = 60 * 1e3;
|
|
23747
|
+
var oneHour = 60 * oneMinute;
|
|
23748
|
+
var oneDay = 24 * oneHour;
|
|
23749
|
+
var oneWeek = 7 * oneDay;
|
|
23750
|
+
var GROUP_BOUNDS = {
|
|
23751
|
+
minute: { lower: oneMinute, upper: oneHour },
|
|
23752
|
+
hour: { lower: oneHour, upper: oneDay },
|
|
23753
|
+
day: { lower: oneDay, upper: oneWeek }
|
|
23754
|
+
};
|
|
23755
|
+
var DEFAULT_STOP_REFRESH_BOUNDARY_MS = 2 * oneWeek;
|
|
23756
|
+
var ReminderTimer = class {
|
|
23757
|
+
constructor({
|
|
23758
|
+
reminder,
|
|
23759
|
+
config
|
|
23760
|
+
}) {
|
|
23761
|
+
this.timeout = null;
|
|
23762
|
+
this.stopRefreshBoundaryMs = DEFAULT_STOP_REFRESH_BOUNDARY_MS;
|
|
23763
|
+
this.getRefreshIntervalLength = () => {
|
|
23764
|
+
if (!this.reminder.remindAt) return null;
|
|
23765
|
+
const distanceFromDeadlineMs = Math.abs(timeLeftMs(this.reminder.remindAt.getTime()));
|
|
23766
|
+
let refreshInterval;
|
|
23767
|
+
if (distanceFromDeadlineMs === 0) {
|
|
23768
|
+
refreshInterval = oneMinute;
|
|
23769
|
+
} else if (distanceFromDeadlineMs < GROUP_BOUNDS.minute.lower) {
|
|
23770
|
+
refreshInterval = distanceFromDeadlineMs;
|
|
23771
|
+
} else if (distanceFromDeadlineMs <= GROUP_BOUNDS.minute.upper) {
|
|
23772
|
+
refreshInterval = oneMinute;
|
|
23773
|
+
} else if (distanceFromDeadlineMs <= GROUP_BOUNDS.hour.upper) {
|
|
23774
|
+
refreshInterval = oneHour;
|
|
23775
|
+
} else {
|
|
23776
|
+
refreshInterval = oneDay;
|
|
23777
|
+
}
|
|
23778
|
+
return refreshInterval;
|
|
23779
|
+
};
|
|
23780
|
+
this.init = () => {
|
|
23781
|
+
if (!this.reminder.remindAt) return null;
|
|
23782
|
+
const timeoutLength = this.getRefreshIntervalLength();
|
|
23783
|
+
if (timeoutLength === null) return null;
|
|
23784
|
+
const boundaryTimestamp = this.reminder.remindAt?.getTime() + this.stopRefreshBoundaryMs;
|
|
23785
|
+
const timeLeftToBoundary = boundaryTimestamp - Date.now();
|
|
23786
|
+
if (timeLeftToBoundary <= 0) {
|
|
23787
|
+
this.timeout = null;
|
|
23788
|
+
return;
|
|
23789
|
+
}
|
|
23790
|
+
if (this.timeout) clearTimeout(this.timeout);
|
|
23791
|
+
this.timeout = setTimeout(() => {
|
|
23792
|
+
this.reminder.refreshTimeLeft();
|
|
23793
|
+
this.init();
|
|
23794
|
+
}, timeoutLength);
|
|
23795
|
+
};
|
|
23796
|
+
this.clear = () => {
|
|
23797
|
+
if (this.timeout) {
|
|
23798
|
+
clearInterval(this.timeout);
|
|
23799
|
+
this.timeout = null;
|
|
23800
|
+
}
|
|
23801
|
+
};
|
|
23802
|
+
this.reminder = reminder;
|
|
23803
|
+
if (typeof config?.stopRefreshBoundaryMs === "number") {
|
|
23804
|
+
this.stopRefreshBoundaryMs = config.stopRefreshBoundaryMs;
|
|
23805
|
+
}
|
|
23806
|
+
}
|
|
23807
|
+
};
|
|
23808
|
+
|
|
23809
|
+
// src/reminders/Reminder.ts
|
|
23810
|
+
var timeLeftMs = (remindAt) => remindAt - (/* @__PURE__ */ new Date()).getTime();
|
|
23811
|
+
var _Reminder = class _Reminder {
|
|
23812
|
+
constructor({ data, config }) {
|
|
23813
|
+
this.setState = (data) => {
|
|
23814
|
+
this.state.next((current) => {
|
|
23815
|
+
const newState = { ...current, ..._Reminder.toStateValue(data) };
|
|
23816
|
+
if (newState.remind_at) {
|
|
23817
|
+
newState.timeLeftMs = timeLeftMs(newState.remind_at.getTime());
|
|
23818
|
+
}
|
|
23819
|
+
return newState;
|
|
23820
|
+
});
|
|
23821
|
+
if (data.remind_at) {
|
|
23822
|
+
this.initTimer();
|
|
23823
|
+
} else if (!data.remind_at) {
|
|
23824
|
+
this.clearTimer();
|
|
23825
|
+
}
|
|
23826
|
+
};
|
|
23827
|
+
this.refreshTimeLeft = () => {
|
|
23828
|
+
if (!this.remindAt) return;
|
|
23829
|
+
this.state.partialNext({ timeLeftMs: timeLeftMs(this.remindAt.getTime()) });
|
|
23830
|
+
};
|
|
23831
|
+
this.initTimer = () => {
|
|
23832
|
+
this.timer.init();
|
|
23833
|
+
};
|
|
23834
|
+
this.clearTimer = () => {
|
|
23835
|
+
this.timer.clear();
|
|
23836
|
+
};
|
|
23837
|
+
this.state = new StateStore(_Reminder.toStateValue(data));
|
|
23838
|
+
this.timer = new ReminderTimer({ reminder: this, config });
|
|
23839
|
+
this.initTimer();
|
|
23840
|
+
}
|
|
23841
|
+
get id() {
|
|
23842
|
+
return this.state.getLatestValue().message_id;
|
|
23843
|
+
}
|
|
23844
|
+
get remindAt() {
|
|
23845
|
+
return this.state.getLatestValue().remind_at;
|
|
23846
|
+
}
|
|
23847
|
+
get timeLeftMs() {
|
|
23848
|
+
return this.state.getLatestValue().timeLeftMs;
|
|
23849
|
+
}
|
|
23850
|
+
};
|
|
23851
|
+
_Reminder.toStateValue = (data) => ({
|
|
23852
|
+
...data,
|
|
23853
|
+
created_at: new Date(data.created_at),
|
|
23854
|
+
message: data.message || null,
|
|
23855
|
+
remind_at: data.remind_at ? new Date(data.remind_at) : null,
|
|
23856
|
+
timeLeftMs: data.remind_at ? timeLeftMs(new Date(data.remind_at).getTime()) : null,
|
|
23857
|
+
updated_at: new Date(data.updated_at),
|
|
23858
|
+
user: data.user || null
|
|
23859
|
+
});
|
|
23860
|
+
var Reminder = _Reminder;
|
|
23861
|
+
|
|
23862
|
+
// src/pagination/BasePaginator.ts
|
|
23863
|
+
var DEFAULT_PAGINATION_OPTIONS = {
|
|
23864
|
+
debounceMs: 300,
|
|
23865
|
+
pageSize: 10
|
|
23866
|
+
};
|
|
23867
|
+
var BasePaginator = class {
|
|
23868
|
+
constructor(options) {
|
|
23869
|
+
this._isCursorPagination = false;
|
|
23870
|
+
this.setDebounceOptions = ({ debounceMs }) => {
|
|
23871
|
+
this._executeQueryDebounced = debounce(this.executeQuery.bind(this), debounceMs);
|
|
23872
|
+
};
|
|
23873
|
+
this.canExecuteQuery = (direction) => !this.isLoading && direction === "next" && this.hasNext || direction === "prev" && this.hasPrev;
|
|
23874
|
+
this.next = () => this.executeQuery({ direction: "next" });
|
|
23875
|
+
this.prev = () => this.executeQuery({ direction: "prev" });
|
|
23876
|
+
this.nextDebounced = () => {
|
|
23877
|
+
this._executeQueryDebounced({ direction: "next" });
|
|
23878
|
+
};
|
|
23879
|
+
this.prevDebounced = () => {
|
|
23880
|
+
this._executeQueryDebounced({ direction: "prev" });
|
|
23881
|
+
};
|
|
23882
|
+
const { debounceMs, pageSize } = { ...DEFAULT_PAGINATION_OPTIONS, ...options };
|
|
23883
|
+
this.pageSize = pageSize;
|
|
23884
|
+
this.state = new StateStore(this.initialState);
|
|
23885
|
+
this.setDebounceOptions({ debounceMs });
|
|
23886
|
+
}
|
|
23887
|
+
get lastQueryError() {
|
|
23888
|
+
return this.state.getLatestValue().lastQueryError;
|
|
23889
|
+
}
|
|
23890
|
+
get hasNext() {
|
|
23891
|
+
return this.state.getLatestValue().hasNext;
|
|
23892
|
+
}
|
|
23893
|
+
get hasPrev() {
|
|
23894
|
+
return this.state.getLatestValue().hasPrev;
|
|
23895
|
+
}
|
|
23896
|
+
get hasResults() {
|
|
23897
|
+
return Array.isArray(this.state.getLatestValue().items);
|
|
23898
|
+
}
|
|
23899
|
+
get isLoading() {
|
|
23900
|
+
return this.state.getLatestValue().isLoading;
|
|
23901
|
+
}
|
|
23902
|
+
get initialState() {
|
|
23903
|
+
return {
|
|
23904
|
+
hasNext: true,
|
|
23905
|
+
hasPrev: true,
|
|
23906
|
+
//todo: check if optimistic value does not cause problems in UI
|
|
23907
|
+
isLoading: false,
|
|
23908
|
+
items: void 0,
|
|
23909
|
+
lastQueryError: void 0,
|
|
23910
|
+
cursor: void 0,
|
|
23911
|
+
offset: 0
|
|
23912
|
+
};
|
|
23913
|
+
}
|
|
23914
|
+
get items() {
|
|
23915
|
+
return this.state.getLatestValue().items;
|
|
23916
|
+
}
|
|
23917
|
+
get cursor() {
|
|
23918
|
+
return this.state.getLatestValue().cursor;
|
|
23919
|
+
}
|
|
23920
|
+
get offset() {
|
|
23921
|
+
return this.state.getLatestValue().offset;
|
|
23922
|
+
}
|
|
23923
|
+
getStateBeforeFirstQuery() {
|
|
23924
|
+
return {
|
|
23925
|
+
...this.initialState,
|
|
23926
|
+
isLoading: true
|
|
23927
|
+
};
|
|
23928
|
+
}
|
|
23929
|
+
getStateAfterQuery(stateUpdate, isFirstPage) {
|
|
23930
|
+
const current = this.state.getLatestValue();
|
|
23931
|
+
return {
|
|
23932
|
+
...current,
|
|
23933
|
+
lastQueryError: void 0,
|
|
23934
|
+
// reset lastQueryError that can be overridden by the stateUpdate
|
|
23935
|
+
...stateUpdate,
|
|
23936
|
+
isLoading: false,
|
|
23937
|
+
items: isFirstPage ? stateUpdate.items : [...this.items ?? [], ...stateUpdate.items || []]
|
|
23938
|
+
};
|
|
23939
|
+
}
|
|
23940
|
+
async executeQuery({ direction }) {
|
|
23941
|
+
if (!this.canExecuteQuery(direction)) return;
|
|
23942
|
+
const isFirstPage = typeof this.items === "undefined";
|
|
23943
|
+
if (isFirstPage) {
|
|
23944
|
+
this.state.next(this.getStateBeforeFirstQuery());
|
|
23945
|
+
} else {
|
|
23946
|
+
this.state.partialNext({ isLoading: true });
|
|
23947
|
+
}
|
|
23948
|
+
const stateUpdate = {};
|
|
23949
|
+
try {
|
|
23950
|
+
const results = await this.query({ direction });
|
|
23951
|
+
if (!results) return;
|
|
23952
|
+
const { items, next, prev } = results;
|
|
23953
|
+
if (isFirstPage && (next || prev)) {
|
|
23954
|
+
this._isCursorPagination = true;
|
|
23955
|
+
}
|
|
23956
|
+
if (this._isCursorPagination) {
|
|
23957
|
+
stateUpdate.cursor = { next: next || null, prev: prev || null };
|
|
23958
|
+
stateUpdate.hasNext = !!next;
|
|
23959
|
+
stateUpdate.hasPrev = !!prev;
|
|
23960
|
+
} else {
|
|
23961
|
+
stateUpdate.offset = (this.offset ?? 0) + items.length;
|
|
23962
|
+
stateUpdate.hasNext = items.length === this.pageSize;
|
|
23963
|
+
}
|
|
23964
|
+
stateUpdate.items = await this.filterQueryResults(items);
|
|
23965
|
+
} catch (e) {
|
|
23966
|
+
stateUpdate.lastQueryError = e;
|
|
23967
|
+
} finally {
|
|
23968
|
+
this.state.next(this.getStateAfterQuery(stateUpdate, isFirstPage));
|
|
23969
|
+
}
|
|
23970
|
+
}
|
|
23971
|
+
cancelScheduledQuery() {
|
|
23972
|
+
this._executeQueryDebounced.cancel();
|
|
23973
|
+
}
|
|
23974
|
+
resetState() {
|
|
23975
|
+
this.state.next(this.initialState);
|
|
23976
|
+
}
|
|
23977
|
+
};
|
|
23978
|
+
|
|
23979
|
+
// src/pagination/ReminderPaginator.ts
|
|
23980
|
+
var ReminderPaginator = class extends BasePaginator {
|
|
23981
|
+
constructor(client, options) {
|
|
23982
|
+
super(options);
|
|
23983
|
+
this.query = async ({
|
|
23984
|
+
direction
|
|
23985
|
+
}) => {
|
|
23986
|
+
const cursor = this.cursor?.[direction];
|
|
23987
|
+
const {
|
|
23988
|
+
reminders: items,
|
|
23989
|
+
next,
|
|
23990
|
+
prev
|
|
23991
|
+
} = await this.client.queryReminders({
|
|
23992
|
+
filter: this.filters,
|
|
23993
|
+
sort: this.sort,
|
|
23994
|
+
limit: this.pageSize,
|
|
23995
|
+
[direction]: cursor
|
|
23996
|
+
});
|
|
23997
|
+
return { items, next, prev };
|
|
23998
|
+
};
|
|
23999
|
+
this.filterQueryResults = (items) => items;
|
|
24000
|
+
this.client = client;
|
|
24001
|
+
}
|
|
24002
|
+
};
|
|
24003
|
+
|
|
24004
|
+
// src/reminders/ReminderManager.ts
|
|
24005
|
+
var oneMinute2 = 60 * 1e3;
|
|
24006
|
+
var oneHour2 = 60 * oneMinute2;
|
|
24007
|
+
var oneDay2 = 24 * oneHour2;
|
|
24008
|
+
var DEFAULT_REMINDER_MANAGER_CONFIG = {
|
|
24009
|
+
scheduledOffsetsMs: [
|
|
24010
|
+
2 * oneMinute2,
|
|
24011
|
+
30 * oneMinute2,
|
|
24012
|
+
oneHour2,
|
|
24013
|
+
2 * oneHour2,
|
|
24014
|
+
8 * oneHour2,
|
|
24015
|
+
oneDay2
|
|
24016
|
+
]
|
|
24017
|
+
};
|
|
24018
|
+
var isReminderExistsError = (error) => error.message.match("already has reminder created for this message_id");
|
|
24019
|
+
var isReminderDoesNotExistError = (error) => error.message.match("reminder does not exist");
|
|
24020
|
+
var _ReminderManager = class _ReminderManager extends WithSubscriptions {
|
|
24021
|
+
constructor({ client, config }) {
|
|
24022
|
+
super();
|
|
24023
|
+
this.upsertToState = ({
|
|
24024
|
+
data,
|
|
24025
|
+
overwrite = true
|
|
24026
|
+
}) => {
|
|
24027
|
+
if (!this.client._cacheEnabled()) {
|
|
24028
|
+
return;
|
|
24029
|
+
}
|
|
24030
|
+
const cachedReminder = this.getFromState(data.message_id);
|
|
24031
|
+
if (!cachedReminder) {
|
|
24032
|
+
const reminder = new Reminder({
|
|
24033
|
+
data,
|
|
24034
|
+
config: { stopRefreshBoundaryMs: this.stopTimerRefreshBoundaryMs }
|
|
24035
|
+
});
|
|
24036
|
+
this.state.partialNext({
|
|
24037
|
+
reminders: new Map(this.reminders.set(data.message_id, reminder))
|
|
24038
|
+
});
|
|
24039
|
+
} else if (overwrite) {
|
|
24040
|
+
cachedReminder.setState(data);
|
|
24041
|
+
}
|
|
24042
|
+
return cachedReminder;
|
|
24043
|
+
};
|
|
24044
|
+
this.removeFromState = (messageId) => {
|
|
24045
|
+
const cachedReminder = this.getFromState(messageId);
|
|
24046
|
+
if (!cachedReminder) return;
|
|
24047
|
+
cachedReminder.clearTimer();
|
|
24048
|
+
const reminders = this.reminders;
|
|
24049
|
+
reminders.delete(messageId);
|
|
24050
|
+
this.state.partialNext({ reminders: new Map(reminders) });
|
|
24051
|
+
};
|
|
24052
|
+
this.hydrateState = (messages) => {
|
|
24053
|
+
messages.forEach(({ reminder }) => {
|
|
24054
|
+
if (reminder) {
|
|
24055
|
+
this.upsertToState({ data: reminder });
|
|
24056
|
+
}
|
|
24057
|
+
});
|
|
24058
|
+
};
|
|
24059
|
+
// State API END //
|
|
24060
|
+
// Timers API START //
|
|
24061
|
+
this.initTimers = () => {
|
|
24062
|
+
this.reminders.forEach((reminder) => reminder.initTimer());
|
|
24063
|
+
};
|
|
24064
|
+
this.clearTimers = () => {
|
|
24065
|
+
this.reminders.forEach((reminder) => reminder.clearTimer());
|
|
24066
|
+
};
|
|
24067
|
+
this.registerSubscriptions = () => {
|
|
24068
|
+
if (this.hasSubscriptions) return;
|
|
24069
|
+
this.addUnsubscribeFunction(this.subscribeReminderCreated());
|
|
24070
|
+
this.addUnsubscribeFunction(this.subscribeReminderUpdated());
|
|
24071
|
+
this.addUnsubscribeFunction(this.subscribeReminderDeleted());
|
|
24072
|
+
this.addUnsubscribeFunction(this.subscribeNotificationReminderDue());
|
|
24073
|
+
this.addUnsubscribeFunction(this.subscribeMessageDeleted());
|
|
24074
|
+
this.addUnsubscribeFunction(this.subscribeMessageUndeleted());
|
|
24075
|
+
this.addUnsubscribeFunction(this.subscribePaginatorStateUpdated());
|
|
24076
|
+
this.addUnsubscribeFunction(this.subscribeConfigStateUpdated());
|
|
24077
|
+
};
|
|
24078
|
+
this.subscribeReminderCreated = () => this.client.on("reminder.created", (event) => {
|
|
24079
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
24080
|
+
const { reminder } = event;
|
|
24081
|
+
this.upsertToState({ data: reminder });
|
|
24082
|
+
}).unsubscribe;
|
|
24083
|
+
this.subscribeReminderUpdated = () => this.client.on("reminder.updated", (event) => {
|
|
24084
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
24085
|
+
const { reminder } = event;
|
|
24086
|
+
this.upsertToState({ data: reminder });
|
|
24087
|
+
}).unsubscribe;
|
|
24088
|
+
this.subscribeReminderDeleted = () => this.client.on("reminder.deleted", (event) => {
|
|
24089
|
+
if (!_ReminderManager.isReminderWsEventPayload(event)) return;
|
|
24090
|
+
this.removeFromState(event.message_id);
|
|
24091
|
+
}).unsubscribe;
|
|
24092
|
+
this.subscribeMessageDeleted = () => this.client.on("message.deleted", (event) => {
|
|
24093
|
+
if (!event.message?.id) return;
|
|
24094
|
+
this.removeFromState(event.message.id);
|
|
24095
|
+
}).unsubscribe;
|
|
24096
|
+
this.subscribeMessageUndeleted = () => this.client.on("message.undeleted", (event) => {
|
|
24097
|
+
if (!event.message?.reminder) return;
|
|
24098
|
+
this.upsertToState({ data: event.message.reminder });
|
|
24099
|
+
}).unsubscribe;
|
|
24100
|
+
this.subscribeNotificationReminderDue = () => this.client.on("notification.reminder_due", () => null).unsubscribe;
|
|
24101
|
+
// todo: what should be performed on this event?
|
|
24102
|
+
this.subscribePaginatorStateUpdated = () => this.paginator.state.subscribeWithSelector(
|
|
24103
|
+
({ items }) => [items],
|
|
24104
|
+
([items]) => {
|
|
24105
|
+
if (!items) return;
|
|
24106
|
+
for (const reminder of items) {
|
|
24107
|
+
this.upsertToState({ data: reminder });
|
|
24108
|
+
}
|
|
24109
|
+
}
|
|
24110
|
+
);
|
|
24111
|
+
this.subscribeConfigStateUpdated = () => this.configState.subscribeWithSelector(
|
|
24112
|
+
({ stopTimerRefreshBoundaryMs }) => ({ stopTimerRefreshBoundaryMs }),
|
|
24113
|
+
({ stopTimerRefreshBoundaryMs }, previousValue) => {
|
|
24114
|
+
if (typeof stopTimerRefreshBoundaryMs === "number" && stopTimerRefreshBoundaryMs !== previousValue?.stopTimerRefreshBoundaryMs) {
|
|
24115
|
+
this.reminders.forEach((reminder) => {
|
|
24116
|
+
if (reminder.timer) {
|
|
24117
|
+
reminder.timer.stopRefreshBoundaryMs = stopTimerRefreshBoundaryMs;
|
|
24118
|
+
}
|
|
24119
|
+
});
|
|
24120
|
+
}
|
|
24121
|
+
}
|
|
24122
|
+
);
|
|
24123
|
+
// WS event handling END //
|
|
24124
|
+
// API calls START //
|
|
24125
|
+
this.upsertReminder = async (options) => {
|
|
24126
|
+
const { messageId } = options;
|
|
24127
|
+
if (this.getFromState(messageId)) {
|
|
24128
|
+
try {
|
|
24129
|
+
return await this.updateReminder(options);
|
|
24130
|
+
} catch (error) {
|
|
24131
|
+
if (isReminderDoesNotExistError(error)) {
|
|
24132
|
+
return await this.createReminder(options);
|
|
24133
|
+
}
|
|
24134
|
+
throw error;
|
|
24135
|
+
}
|
|
24136
|
+
} else {
|
|
24137
|
+
try {
|
|
24138
|
+
return await this.createReminder(options);
|
|
24139
|
+
} catch (error) {
|
|
24140
|
+
if (isReminderExistsError(error)) {
|
|
24141
|
+
return await this.updateReminder(options);
|
|
24142
|
+
}
|
|
24143
|
+
throw error;
|
|
24144
|
+
}
|
|
24145
|
+
}
|
|
24146
|
+
};
|
|
24147
|
+
this.createReminder = async (options) => {
|
|
24148
|
+
const { reminder } = await this.client.createReminder(options);
|
|
24149
|
+
return this.upsertToState({ data: reminder, overwrite: false });
|
|
24150
|
+
};
|
|
24151
|
+
this.updateReminder = async (options) => {
|
|
24152
|
+
const { reminder } = await this.client.updateReminder(options);
|
|
24153
|
+
return this.upsertToState({ data: reminder });
|
|
24154
|
+
};
|
|
24155
|
+
this.deleteReminder = async (messageId) => {
|
|
24156
|
+
await this.client.deleteReminder(messageId);
|
|
24157
|
+
this.removeFromState(messageId);
|
|
24158
|
+
};
|
|
24159
|
+
this.queryNextReminders = async () => {
|
|
24160
|
+
await this.paginator.next();
|
|
24161
|
+
};
|
|
24162
|
+
this.queryPreviousReminders = async () => {
|
|
24163
|
+
await this.paginator.prev();
|
|
24164
|
+
};
|
|
24165
|
+
this.client = client;
|
|
24166
|
+
this.configState = new StateStore({
|
|
24167
|
+
scheduledOffsetsMs: config?.scheduledOffsetsMs ?? DEFAULT_REMINDER_MANAGER_CONFIG.scheduledOffsetsMs
|
|
24168
|
+
});
|
|
24169
|
+
this.state = new StateStore({ reminders: /* @__PURE__ */ new Map() });
|
|
24170
|
+
this.paginator = new ReminderPaginator(client);
|
|
24171
|
+
}
|
|
24172
|
+
// Config API START //
|
|
24173
|
+
updateConfig(config) {
|
|
24174
|
+
this.configState.partialNext(config);
|
|
24175
|
+
}
|
|
24176
|
+
get stopTimerRefreshBoundaryMs() {
|
|
24177
|
+
return this.configState.getLatestValue().stopTimerRefreshBoundaryMs;
|
|
24178
|
+
}
|
|
24179
|
+
get scheduledOffsetsMs() {
|
|
24180
|
+
return this.configState.getLatestValue().scheduledOffsetsMs;
|
|
24181
|
+
}
|
|
24182
|
+
// Config API END //
|
|
24183
|
+
// State API START //
|
|
24184
|
+
get reminders() {
|
|
24185
|
+
return this.state.getLatestValue().reminders;
|
|
24186
|
+
}
|
|
24187
|
+
getFromState(messageId) {
|
|
24188
|
+
return this.reminders.get(messageId);
|
|
24189
|
+
}
|
|
24190
|
+
// API calls END //
|
|
24191
|
+
};
|
|
24192
|
+
// Timers API END //
|
|
24193
|
+
// WS event handling START //
|
|
24194
|
+
_ReminderManager.isReminderWsEventPayload = (event) => !!event.reminder && (event.type.startsWith("reminder.") || event.type === "notification.reminder_due");
|
|
24195
|
+
var ReminderManager = _ReminderManager;
|
|
24196
|
+
|
|
23726
24197
|
// src/client.ts
|
|
23727
24198
|
function isString3(x) {
|
|
23728
24199
|
return typeof x === "string" || x instanceof String;
|
|
@@ -23738,6 +24209,9 @@ var StreamChat = class _StreamChat {
|
|
|
23738
24209
|
});
|
|
23739
24210
|
this._getConnectionID = () => this.wsConnection?.connectionID || this.wsFallback?.connectionID;
|
|
23740
24211
|
this._hasConnectionID = () => Boolean(this._getConnectionID());
|
|
24212
|
+
this.setMessageComposerSetupFunction = (setupFunction) => {
|
|
24213
|
+
this._messageComposerSetupState.partialNext({ setupFunction });
|
|
24214
|
+
};
|
|
23741
24215
|
/**
|
|
23742
24216
|
* connectUser - Set the current user and open a WebSocket connection
|
|
23743
24217
|
*
|
|
@@ -24306,9 +24780,6 @@ var StreamChat = class _StreamChat {
|
|
|
24306
24780
|
device: this.options.device,
|
|
24307
24781
|
client_request_id
|
|
24308
24782
|
});
|
|
24309
|
-
this.setMessageComposerSetupFunction = (setupFunction) => {
|
|
24310
|
-
this._messageComposerSetupState.partialNext({ setupFunction });
|
|
24311
|
-
};
|
|
24312
24783
|
this.key = key;
|
|
24313
24784
|
this.listeners = {};
|
|
24314
24785
|
this.state = new ClientState({ client: this });
|
|
@@ -24363,6 +24834,7 @@ var StreamChat = class _StreamChat {
|
|
|
24363
24834
|
this.recoverStateOnReconnect = this.options.recoverStateOnReconnect;
|
|
24364
24835
|
this.threads = new ThreadManager({ client: this });
|
|
24365
24836
|
this.polls = new PollManager({ client: this });
|
|
24837
|
+
this.reminders = new ReminderManager({ client: this });
|
|
24366
24838
|
}
|
|
24367
24839
|
static getInstance(key, secretOrOptions, options) {
|
|
24368
24840
|
if (!_StreamChat._instance) {
|
|
@@ -24498,15 +24970,15 @@ var StreamChat = class _StreamChat {
|
|
|
24498
24970
|
* @param {string} userID User ID. If user has no devices, it will error
|
|
24499
24971
|
* @param {TestPushDataInput} [data] Overrides for push templates/message used
|
|
24500
24972
|
* IE: {
|
|
24501
|
-
|
|
24502
|
-
|
|
24503
|
-
|
|
24504
|
-
|
|
24505
|
-
|
|
24506
|
-
|
|
24507
|
-
|
|
24508
|
-
|
|
24509
|
-
|
|
24973
|
+
messageID: 'id-of-message', // will error if message does not exist
|
|
24974
|
+
apnTemplate: '{}', // if app doesn't have apn configured it will error
|
|
24975
|
+
firebaseTemplate: '{}', // if app doesn't have firebase configured it will error
|
|
24976
|
+
firebaseDataTemplate: '{}', // if app doesn't have firebase configured it will error
|
|
24977
|
+
skipDevices: true, // skip config/device checks and sending to real devices
|
|
24978
|
+
pushProviderName: 'staging' // one of your configured push providers
|
|
24979
|
+
pushProviderType: 'apn' // one of supported provider types
|
|
24980
|
+
}
|
|
24981
|
+
*/
|
|
24510
24982
|
async testPushSettings(userID, data = {}) {
|
|
24511
24983
|
return await this.post(this.baseURL + "/check_push", {
|
|
24512
24984
|
user_id: userID,
|
|
@@ -24524,10 +24996,10 @@ var StreamChat = class _StreamChat {
|
|
|
24524
24996
|
*
|
|
24525
24997
|
* @param {TestSQSDataInput} [data] Overrides SQS settings for testing if needed
|
|
24526
24998
|
* IE: {
|
|
24527
|
-
|
|
24528
|
-
|
|
24529
|
-
|
|
24530
|
-
|
|
24999
|
+
sqs_key: 'auth_key',
|
|
25000
|
+
sqs_secret: 'auth_secret',
|
|
25001
|
+
sqs_url: 'url_to_queue',
|
|
25002
|
+
}
|
|
24531
25003
|
*/
|
|
24532
25004
|
async testSQSSettings(data = {}) {
|
|
24533
25005
|
return await this.post(this.baseURL + "/check_sqs", data);
|
|
@@ -24537,10 +25009,10 @@ var StreamChat = class _StreamChat {
|
|
|
24537
25009
|
*
|
|
24538
25010
|
* @param {TestSNSDataInput} [data] Overrides SNS settings for testing if needed
|
|
24539
25011
|
* IE: {
|
|
24540
|
-
|
|
24541
|
-
|
|
24542
|
-
|
|
24543
|
-
|
|
25012
|
+
sns_key: 'auth_key',
|
|
25013
|
+
sns_secret: 'auth_secret',
|
|
25014
|
+
sns_topic_arn: 'topic_to_publish_to',
|
|
25015
|
+
}
|
|
24544
25016
|
*/
|
|
24545
25017
|
async testSNSSettings(data = {}) {
|
|
24546
25018
|
return await this.post(this.baseURL + "/check_sns", data);
|
|
@@ -25021,6 +25493,7 @@ var StreamChat = class _StreamChat {
|
|
|
25021
25493
|
})
|
|
25022
25494
|
};
|
|
25023
25495
|
this.polls.hydratePollCache(channelState.messages, true);
|
|
25496
|
+
this.reminders.hydrateState(channelState.messages);
|
|
25024
25497
|
}
|
|
25025
25498
|
if (channelState.draft) {
|
|
25026
25499
|
c.messageComposer.initState({ composition: channelState.draft });
|
|
@@ -25598,7 +26071,7 @@ var StreamChat = class _StreamChat {
|
|
|
25598
26071
|
data
|
|
25599
26072
|
);
|
|
25600
26073
|
}
|
|
25601
|
-
|
|
26074
|
+
deleteChannelType(channelType) {
|
|
25602
26075
|
return this.delete(
|
|
25603
26076
|
this.baseURL + `/channeltypes/${encodeURIComponent(channelType)}`
|
|
25604
26077
|
);
|
|
@@ -25941,7 +26414,7 @@ var StreamChat = class _StreamChat {
|
|
|
25941
26414
|
if (this.userAgent) {
|
|
25942
26415
|
return this.userAgent;
|
|
25943
26416
|
}
|
|
25944
|
-
const version = "9.
|
|
26417
|
+
const version = "9.5.1";
|
|
25945
26418
|
const clientBundle = "node-cjs";
|
|
25946
26419
|
let userAgentString = "";
|
|
25947
26420
|
if (this.sdkIdentifier) {
|
|
@@ -26980,6 +27453,56 @@ var StreamChat = class _StreamChat {
|
|
|
26980
27453
|
};
|
|
26981
27454
|
return await this.post(this.baseURL + "/drafts/query", payload);
|
|
26982
27455
|
}
|
|
27456
|
+
/**
|
|
27457
|
+
* createReminder - Creates a reminder for a message
|
|
27458
|
+
*
|
|
27459
|
+
* @param {CreateReminderOptions} options The options for creating the reminder
|
|
27460
|
+
* @returns {Promise<ReminderAPIResponse>}
|
|
27461
|
+
*/
|
|
27462
|
+
async createReminder({ messageId, ...options }) {
|
|
27463
|
+
return await this.post(
|
|
27464
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
27465
|
+
options
|
|
27466
|
+
);
|
|
27467
|
+
}
|
|
27468
|
+
/**
|
|
27469
|
+
* updateReminder - Updates an existing reminder for a message
|
|
27470
|
+
*
|
|
27471
|
+
* @param {UpdateReminderOptions} options The options for updating the reminder
|
|
27472
|
+
* @returns {Promise<ReminderAPIResponse>}
|
|
27473
|
+
*/
|
|
27474
|
+
async updateReminder({ messageId, ...options }) {
|
|
27475
|
+
return await this.patch(
|
|
27476
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
27477
|
+
options
|
|
27478
|
+
);
|
|
27479
|
+
}
|
|
27480
|
+
/**
|
|
27481
|
+
* deleteReminder - Deletes a reminder for a message
|
|
27482
|
+
*
|
|
27483
|
+
* @param {string} messageId The ID of the message whose reminder to delete
|
|
27484
|
+
* @param {string} [userId] Optional user ID, required for server-side operations
|
|
27485
|
+
* @returns {Promise<APIResponse>}
|
|
27486
|
+
*/
|
|
27487
|
+
async deleteReminder(messageId, userId) {
|
|
27488
|
+
return await this.delete(
|
|
27489
|
+
`${this.baseURL}/messages/${messageId}/reminders`,
|
|
27490
|
+
userId ? { user_id: userId } : {}
|
|
27491
|
+
);
|
|
27492
|
+
}
|
|
27493
|
+
/**
|
|
27494
|
+
* queryReminders - Queries reminders based on given filters
|
|
27495
|
+
*
|
|
27496
|
+
* @param {QueryRemindersOptions} options The options for querying reminders
|
|
27497
|
+
* @returns {Promise<QueryRemindersResponse>}
|
|
27498
|
+
*/
|
|
27499
|
+
async queryReminders({ filter: filter2, sort, ...rest } = {}) {
|
|
27500
|
+
return await this.post(`${this.baseURL}/reminders/query`, {
|
|
27501
|
+
filter_conditions: filter2,
|
|
27502
|
+
sort: sort && normalizeQuerySort(sort),
|
|
27503
|
+
...rest
|
|
27504
|
+
});
|
|
27505
|
+
}
|
|
26983
27506
|
};
|
|
26984
27507
|
|
|
26985
27508
|
// src/events.ts
|
|
@@ -27046,7 +27569,12 @@ var EVENT_MAP = {
|
|
|
27046
27569
|
"connection.changed": true,
|
|
27047
27570
|
"connection.recovered": true,
|
|
27048
27571
|
"transport.changed": true,
|
|
27049
|
-
"capabilities.changed": true
|
|
27572
|
+
"capabilities.changed": true,
|
|
27573
|
+
// Reminder events
|
|
27574
|
+
"reminder.created": true,
|
|
27575
|
+
"reminder.updated": true,
|
|
27576
|
+
"reminder.deleted": true,
|
|
27577
|
+
"notification.reminder_due": true
|
|
27050
27578
|
};
|
|
27051
27579
|
|
|
27052
27580
|
// src/permissions.ts
|
|
@@ -27919,6 +28447,7 @@ var FixedSizeQueueCache = class {
|
|
|
27919
28447
|
AnyResource,
|
|
27920
28448
|
AnyRole,
|
|
27921
28449
|
AttachmentManager,
|
|
28450
|
+
BasePaginator,
|
|
27922
28451
|
BaseSearchSource,
|
|
27923
28452
|
BuiltinPermissions,
|
|
27924
28453
|
BuiltinRoles,
|
|
@@ -27936,6 +28465,9 @@ var FixedSizeQueueCache = class {
|
|
|
27936
28465
|
DEFAULT_CHANNEL_MANAGER_PAGINATION_OPTIONS,
|
|
27937
28466
|
DEFAULT_COMPOSER_CONFIG,
|
|
27938
28467
|
DEFAULT_LINK_PREVIEW_MANAGER_CONFIG,
|
|
28468
|
+
DEFAULT_PAGINATION_OPTIONS,
|
|
28469
|
+
DEFAULT_REMINDER_MANAGER_CONFIG,
|
|
28470
|
+
DEFAULT_STOP_REFRESH_BOUNDARY_MS,
|
|
27939
28471
|
DEFAULT_TEXT_COMPOSER_CONFIG,
|
|
27940
28472
|
Deny,
|
|
27941
28473
|
DenyAll,
|
|
@@ -27968,6 +28500,10 @@ var FixedSizeQueueCache = class {
|
|
|
27968
28500
|
PollComposerCompositionMiddlewareExecutor,
|
|
27969
28501
|
PollComposerStateMiddlewareExecutor,
|
|
27970
28502
|
PollManager,
|
|
28503
|
+
Reminder,
|
|
28504
|
+
ReminderManager,
|
|
28505
|
+
ReminderPaginator,
|
|
28506
|
+
ReminderTimer,
|
|
27971
28507
|
SearchController,
|
|
27972
28508
|
Segment,
|
|
27973
28509
|
StableWSConnection,
|
|
@@ -28055,7 +28591,8 @@ var FixedSizeQueueCache = class {
|
|
|
28055
28591
|
readFileAsArrayBuffer,
|
|
28056
28592
|
removeDiacritics,
|
|
28057
28593
|
replaceWordWithEntity,
|
|
28058
|
-
textIsEmpty
|
|
28594
|
+
textIsEmpty,
|
|
28595
|
+
timeLeftMs
|
|
28059
28596
|
});
|
|
28060
28597
|
/*! Bundled license information:
|
|
28061
28598
|
|