@stream-io/feeds-client 0.2.2 → 0.2.4

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/@react-bindings/contexts/StreamSearchContext.d.ts +1 -1
  3. package/dist/@react-bindings/contexts/StreamSearchResultsContext.d.ts +1 -1
  4. package/dist/@react-bindings/hooks/search-state-hooks/useSearchQuery.d.ts +1 -1
  5. package/dist/@react-bindings/hooks/search-state-hooks/useSearchResult.d.ts +1 -1
  6. package/dist/@react-bindings/hooks/search-state-hooks/useSearchSources.d.ts +2 -2
  7. package/dist/@react-bindings/wrappers/StreamSearch.d.ts +1 -1
  8. package/dist/@react-bindings/wrappers/StreamSearchResults.d.ts +1 -1
  9. package/dist/index-react-bindings.browser.cjs +29 -9
  10. package/dist/index-react-bindings.browser.cjs.map +1 -1
  11. package/dist/index-react-bindings.browser.js +29 -9
  12. package/dist/index-react-bindings.browser.js.map +1 -1
  13. package/dist/index-react-bindings.node.cjs +29 -9
  14. package/dist/index-react-bindings.node.cjs.map +1 -1
  15. package/dist/index-react-bindings.node.js +29 -9
  16. package/dist/index-react-bindings.node.js.map +1 -1
  17. package/dist/index.browser.cjs +243 -171
  18. package/dist/index.browser.cjs.map +1 -1
  19. package/dist/index.browser.js +243 -172
  20. package/dist/index.browser.js.map +1 -1
  21. package/dist/index.d.ts +1 -5
  22. package/dist/index.node.cjs +243 -171
  23. package/dist/index.node.cjs.map +1 -1
  24. package/dist/index.node.js +243 -172
  25. package/dist/index.node.js.map +1 -1
  26. package/dist/src/common/{ActivitySearchSource.d.ts → search/ActivitySearchSource.d.ts} +3 -3
  27. package/dist/src/common/{BaseSearchSource.d.ts → search/BaseSearchSource.d.ts} +41 -35
  28. package/dist/src/common/{FeedSearchSource.d.ts → search/FeedSearchSource.d.ts} +5 -5
  29. package/dist/src/common/{SearchController.d.ts → search/SearchController.d.ts} +1 -3
  30. package/dist/src/common/{UserSearchSource.d.ts → search/UserSearchSource.d.ts} +4 -4
  31. package/dist/src/common/search/index.d.ts +6 -0
  32. package/dist/src/common/search/types.d.ts +22 -0
  33. package/dist/src/common/types.d.ts +1 -0
  34. package/dist/src/feed/event-handlers/activity/handle-activity-deleted.d.ts +5 -12
  35. package/dist/src/gen/models/index.d.ts +68 -26
  36. package/dist/tsconfig.tsbuildinfo +1 -1
  37. package/index.ts +1 -5
  38. package/package.json +1 -1
  39. package/src/common/{ActivitySearchSource.ts → search/ActivitySearchSource.ts} +3 -3
  40. package/src/common/{BaseSearchSource.ts → search/BaseSearchSource.ts} +137 -69
  41. package/src/common/{FeedSearchSource.ts → search/FeedSearchSource.ts} +6 -5
  42. package/src/common/{SearchController.ts → search/SearchController.ts} +2 -7
  43. package/src/common/{UserSearchSource.ts → search/UserSearchSource.ts} +3 -3
  44. package/src/common/search/index.ts +6 -0
  45. package/src/common/search/types.ts +21 -0
  46. package/src/common/types.ts +2 -0
  47. package/src/feed/event-handlers/activity/activity-utils.test.ts +2 -2
  48. package/src/feed/event-handlers/activity/handle-activity-added.test.ts +86 -0
  49. package/src/feed/event-handlers/activity/handle-activity-deleted.test.ts +117 -0
  50. package/src/feed/event-handlers/activity/handle-activity-deleted.ts +8 -4
  51. package/src/feed/event-handlers/feed-member/handle-feed-member-added.test.ts +75 -0
  52. package/src/feed/event-handlers/feed-member/handle-feed-member-removed.test.ts +82 -0
  53. package/src/feed/event-handlers/feed-member/handle-feed-member-removed.ts +19 -9
  54. package/src/feed/event-handlers/feed-member/handle-feed-member-updated.test.ts +84 -0
  55. package/src/gen/feeds/FeedsApi.ts +6 -0
  56. package/src/gen/model-decoders/decoders.ts +13 -1
  57. package/src/gen/models/index.ts +108 -34
  58. package/src/test-utils/response-generators.ts +107 -0
  59. package/dist/src/test-utils/index.d.ts +0 -1
  60. package/dist/src/test-utils/response-generators.d.ts +0 -74
package/dist/index.d.ts CHANGED
@@ -4,10 +4,6 @@ export * from './src/gen/models';
4
4
  export * from './src/types';
5
5
  export * from './src/common/types';
6
6
  export * from './src/common/StateStore';
7
- export * from './src/common/BaseSearchSource';
8
- export * from './src/common/SearchController';
9
- export * from './src/common/ActivitySearchSource';
10
- export * from './src/common/UserSearchSource';
11
- export * from './src/common/FeedSearchSource';
7
+ export * from './src/common/search';
12
8
  export * from './src/common/Poll';
13
9
  export * from './src/utils';
@@ -4,7 +4,7 @@ var axios = require('axios');
4
4
 
5
5
  const decoders = {};
6
6
  const decodeDatetimeType = (input) => typeof input === 'number'
7
- ? new Date(Math.floor(input / 1e6))
7
+ ? new Date(Math.floor(input / 1000000))
8
8
  : new Date(input);
9
9
  decoders.DatetimeType = decodeDatetimeType;
10
10
  const decode = (typeMappings, input) => {
@@ -415,6 +415,7 @@ decoders.Command = (input) => {
415
415
  decoders.CommentAddedEvent = (input) => {
416
416
  const typeMappings = {
417
417
  created_at: { type: 'DatetimeType', isSingle: true },
418
+ activity: { type: 'ActivityResponse', isSingle: true },
418
419
  comment: { type: 'CommentResponse', isSingle: true },
419
420
  received_at: { type: 'DatetimeType', isSingle: true },
420
421
  };
@@ -431,6 +432,7 @@ decoders.CommentDeletedEvent = (input) => {
431
432
  decoders.CommentReactionAddedEvent = (input) => {
432
433
  const typeMappings = {
433
434
  created_at: { type: 'DatetimeType', isSingle: true },
435
+ activity: { type: 'ActivityResponse', isSingle: true },
434
436
  comment: { type: 'CommentResponse', isSingle: true },
435
437
  reaction: { type: 'FeedsReactionResponse', isSingle: true },
436
438
  received_at: { type: 'DatetimeType', isSingle: true },
@@ -449,6 +451,7 @@ decoders.CommentReactionDeletedEvent = (input) => {
449
451
  decoders.CommentReactionUpdatedEvent = (input) => {
450
452
  const typeMappings = {
451
453
  created_at: { type: 'DatetimeType', isSingle: true },
454
+ activity: { type: 'ActivityResponse', isSingle: true },
452
455
  comment: { type: 'CommentResponse', isSingle: true },
453
456
  reaction: { type: 'FeedsReactionResponse', isSingle: true },
454
457
  received_at: { type: 'DatetimeType', isSingle: true },
@@ -811,6 +814,7 @@ decoders.Message = (input) => {
811
814
  pin_expires: { type: 'DatetimeType', isSingle: true },
812
815
  pinned_at: { type: 'DatetimeType', isSingle: true },
813
816
  thread_participants: { type: 'User', isSingle: false },
817
+ member: { type: 'ChannelMember', isSingle: true },
814
818
  pinned_by: { type: 'User', isSingle: true },
815
819
  poll: { type: 'Poll', isSingle: true },
816
820
  quoted_message: { type: 'Message', isSingle: true },
@@ -864,6 +868,8 @@ decoders.ModerationCustomActionEvent = (input) => {
864
868
  };
865
869
  decoders.ModerationFlagResponse = (input) => {
866
870
  const typeMappings = {
871
+ created_at: { type: 'DatetimeType', isSingle: true },
872
+ updated_at: { type: 'DatetimeType', isSingle: true },
867
873
  review_queue_item: { type: 'ReviewQueueItemResponse', isSingle: true },
868
874
  user: { type: 'UserResponse', isSingle: true },
869
875
  };
@@ -1630,6 +1636,7 @@ class FeedsApi {
1630
1636
  const body = {
1631
1637
  type: request?.type,
1632
1638
  create_notification_activity: request?.create_notification_activity,
1639
+ skip_push: request?.skip_push,
1633
1640
  custom: request?.custom,
1634
1641
  };
1635
1642
  const response = await this.apiClient.sendRequest('POST', '/api/v2/feeds/activities/{activity_id}/reactions', pathParams, undefined, body, 'application/json');
@@ -1776,6 +1783,7 @@ class FeedsApi {
1776
1783
  object_type: request?.object_type,
1777
1784
  create_notification_activity: request?.create_notification_activity,
1778
1785
  parent_id: request?.parent_id,
1786
+ skip_push: request?.skip_push,
1779
1787
  attachments: request?.attachments,
1780
1788
  mentioned_user_ids: request?.mentioned_user_ids,
1781
1789
  custom: request?.custom,
@@ -1829,6 +1837,7 @@ class FeedsApi {
1829
1837
  };
1830
1838
  const body = {
1831
1839
  comment: request?.comment,
1840
+ skip_push: request?.skip_push,
1832
1841
  custom: request?.custom,
1833
1842
  };
1834
1843
  const response = await this.apiClient.sendRequest('PATCH', '/api/v2/feeds/comments/{id}', pathParams, undefined, body, 'application/json');
@@ -1842,6 +1851,7 @@ class FeedsApi {
1842
1851
  const body = {
1843
1852
  type: request?.type,
1844
1853
  create_notification_activity: request?.create_notification_activity,
1854
+ skip_push: request?.skip_push,
1845
1855
  custom: request?.custom,
1846
1856
  };
1847
1857
  const response = await this.apiClient.sendRequest('POST', '/api/v2/feeds/comments/{id}/reactions', pathParams, undefined, body, 'application/json');
@@ -2082,6 +2092,7 @@ class FeedsApi {
2082
2092
  create_notification_activity: request?.create_notification_activity,
2083
2093
  follower_role: request?.follower_role,
2084
2094
  push_preference: request?.push_preference,
2095
+ skip_push: request?.skip_push,
2085
2096
  custom: request?.custom,
2086
2097
  };
2087
2098
  const response = await this.apiClient.sendRequest('PATCH', '/api/v2/feeds/follows', undefined, undefined, body, 'application/json');
@@ -2094,6 +2105,7 @@ class FeedsApi {
2094
2105
  target: request?.target,
2095
2106
  create_notification_activity: request?.create_notification_activity,
2096
2107
  push_preference: request?.push_preference,
2108
+ skip_push: request?.skip_push,
2097
2109
  custom: request?.custom,
2098
2110
  };
2099
2111
  const response = await this.apiClient.sendRequest('POST', '/api/v2/feeds/follows', undefined, undefined, body, 'application/json');
@@ -4663,14 +4675,20 @@ function handleFeedMemberUpdated(event) {
4663
4675
  function handleFeedMemberRemoved(event) {
4664
4676
  const { connected_user: connectedUser } = this.client.state.getLatestValue();
4665
4677
  this.state.next((currentState) => {
4666
- const newState = {
4667
- ...currentState,
4668
- members: currentState.members?.filter((member) => member.user.id !== event.user?.id),
4669
- };
4670
- if (connectedUser?.id === event.member_id) {
4678
+ let newState;
4679
+ if (typeof currentState.members !== 'undefined') {
4680
+ const filtered = currentState.members.filter((member) => member.user.id !== event.member_id);
4681
+ if (filtered.length !== currentState.members.length) {
4682
+ newState ?? (newState = { ...currentState });
4683
+ newState.members = filtered;
4684
+ }
4685
+ }
4686
+ if (connectedUser?.id === event.member_id &&
4687
+ typeof currentState.own_membership !== 'undefined') {
4688
+ newState ?? (newState = { ...currentState });
4671
4689
  delete newState.own_membership;
4672
4690
  }
4673
- return newState;
4691
+ return newState ?? currentState;
4674
4692
  });
4675
4693
  }
4676
4694
 
@@ -4907,7 +4925,7 @@ const removePinnedActivityFromState = (activityResponse, pinnedActivities) => {
4907
4925
  if (index !== -1) {
4908
4926
  const newActivities = [...pinnedActivities];
4909
4927
  newActivities.splice(index, 1);
4910
- return { changed: true, activities: newActivities };
4928
+ return { changed: true, pinned_activities: newActivities };
4911
4929
  }
4912
4930
  else {
4913
4931
  return { changed: false, pinned_activities: pinnedActivities };
@@ -6111,16 +6129,120 @@ const FeedOwnCapability = {
6111
6129
  UPDATE_FEED_MEMBERS: 'update-feed-members',
6112
6130
  };
6113
6131
 
6132
+ class SearchController {
6133
+ constructor({ config, sources } = {}) {
6134
+ this.addSource = (source) => {
6135
+ this.state.partialNext({
6136
+ sources: [...this.sources, source],
6137
+ });
6138
+ };
6139
+ this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
6140
+ this.removeSource = (sourceType) => {
6141
+ const newSources = this.sources.filter((s) => s.type !== sourceType);
6142
+ if (newSources.length === this.sources.length)
6143
+ return;
6144
+ this.state.partialNext({ sources: newSources });
6145
+ };
6146
+ this.activateSource = (sourceType) => {
6147
+ const source = this.getSource(sourceType);
6148
+ if (!source || source.isActive)
6149
+ return;
6150
+ if (this.config.keepSingleActiveSource) {
6151
+ this.sources.forEach((s) => {
6152
+ if (s.type !== sourceType) {
6153
+ s.deactivate();
6154
+ }
6155
+ });
6156
+ }
6157
+ source.activate();
6158
+ this.state.partialNext({ sources: [...this.sources] });
6159
+ };
6160
+ this.deactivateSource = (sourceType) => {
6161
+ const source = this.getSource(sourceType);
6162
+ if (!source?.isActive)
6163
+ return;
6164
+ if (this.activeSources.length === 1)
6165
+ return;
6166
+ source.deactivate();
6167
+ this.state.partialNext({ sources: [...this.sources] });
6168
+ };
6169
+ this.activate = () => {
6170
+ if (!this.activeSources.length) {
6171
+ const sourcesToActivate = this.config.keepSingleActiveSource
6172
+ ? this.sources.slice(0, 1)
6173
+ : this.sources;
6174
+ sourcesToActivate.forEach((s) => s.activate());
6175
+ }
6176
+ if (this.isActive)
6177
+ return;
6178
+ this.state.partialNext({ isActive: true });
6179
+ };
6180
+ this.search = async (searchQuery) => {
6181
+ const searchedSources = this.activeSources;
6182
+ this.state.partialNext({
6183
+ searchQuery,
6184
+ });
6185
+ await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
6186
+ };
6187
+ this.cancelSearchQueries = () => {
6188
+ this.activeSources.forEach((s) => s.cancelScheduledQuery());
6189
+ };
6190
+ this.clear = () => {
6191
+ this.cancelSearchQueries();
6192
+ this.sources.forEach((source) => source.state.next({ ...source.initialState, isActive: source.isActive }));
6193
+ this.state.next((current) => ({
6194
+ ...current,
6195
+ isActive: true,
6196
+ queriesInProgress: [],
6197
+ searchQuery: '',
6198
+ }));
6199
+ };
6200
+ this.exit = () => {
6201
+ this.cancelSearchQueries();
6202
+ this.sources.forEach((source) => source.state.next({ ...source.initialState, isActive: source.isActive }));
6203
+ this.state.next((current) => ({
6204
+ ...current,
6205
+ isActive: false,
6206
+ queriesInProgress: [],
6207
+ searchQuery: '',
6208
+ }));
6209
+ };
6210
+ this.state = new StateStore({
6211
+ isActive: false,
6212
+ searchQuery: '',
6213
+ sources: sources ?? [],
6214
+ });
6215
+ this._internalState = new StateStore({});
6216
+ this.config = { keepSingleActiveSource: true, ...config };
6217
+ }
6218
+ get hasNext() {
6219
+ return this.sources.some((source) => source.hasNext);
6220
+ }
6221
+ get sources() {
6222
+ return this.state.getLatestValue().sources;
6223
+ }
6224
+ get activeSources() {
6225
+ return this.state.getLatestValue().sources.filter((s) => s.isActive);
6226
+ }
6227
+ get isActive() {
6228
+ return this.state.getLatestValue().isActive;
6229
+ }
6230
+ get searchQuery() {
6231
+ return this.state.getLatestValue().searchQuery;
6232
+ }
6233
+ get searchSourceTypes() {
6234
+ return this.sources.map((s) => s.type);
6235
+ }
6236
+ }
6237
+
6114
6238
  const DEFAULT_SEARCH_SOURCE_OPTIONS = {
6115
6239
  debounceMs: 300,
6116
6240
  pageSize: 10,
6117
6241
  allowEmptySearchString: false,
6242
+ resetOnNewSearchQuery: true,
6118
6243
  };
6119
- class BaseSearchSource {
6244
+ class BaseSearchSourceBase {
6120
6245
  constructor(options) {
6121
- this.setDebounceOptions = ({ debounceMs }) => {
6122
- this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
6123
- };
6124
6246
  this.activate = () => {
6125
6247
  if (this.isActive)
6126
6248
  return;
@@ -6139,15 +6261,11 @@ class BaseSearchSource {
6139
6261
  (this.hasNext || hasNewSearchQuery) &&
6140
6262
  (this.allowEmptySearchString || searchString));
6141
6263
  };
6142
- this.search = (searchQuery) => this.searchDebounced(searchQuery);
6143
- const { debounceMs, pageSize, allowEmptySearchString } = {
6144
- ...DEFAULT_SEARCH_SOURCE_OPTIONS,
6145
- ...options,
6146
- };
6264
+ const { pageSize, allowEmptySearchString, resetOnNewSearchQuery } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
6147
6265
  this.pageSize = pageSize;
6148
6266
  this.allowEmptySearchString = allowEmptySearchString;
6267
+ this.resetOnNewSearchQuery = resetOnNewSearchQuery;
6149
6268
  this.state = new StateStore(this.initialState);
6150
- this.setDebounceOptions({ debounceMs });
6151
6269
  }
6152
6270
  get lastQueryError() {
6153
6271
  return this.state.getLatestValue().lastQueryError;
@@ -6189,10 +6307,14 @@ class BaseSearchSource {
6189
6307
  return this.state.getLatestValue().searchQuery;
6190
6308
  }
6191
6309
  getStateBeforeFirstQuery(newSearchString) {
6310
+ const initialState = this.initialState;
6311
+ const oldItems = this.items;
6312
+ const items = this.resetOnNewSearchQuery ? initialState.items : oldItems;
6192
6313
  return {
6193
6314
  ...this.initialState,
6315
+ items,
6194
6316
  isActive: this.isActive,
6195
- isLoading: true,
6317
+ isLoading: this.resetOnNewSearchQuery ? true : !oldItems,
6196
6318
  searchQuery: newSearchString,
6197
6319
  };
6198
6320
  }
@@ -6205,12 +6327,10 @@ class BaseSearchSource {
6205
6327
  isLoading: false,
6206
6328
  items: isFirstPage
6207
6329
  ? stateUpdate.items
6208
- : [...(this.items ?? []), ...(stateUpdate.items ?? [])],
6330
+ : [...(this.items ?? []), ...(stateUpdate.items || [])],
6209
6331
  };
6210
6332
  }
6211
- async executeQuery(newSearchString) {
6212
- if (!this.canExecuteQuery(newSearchString))
6213
- return;
6333
+ prepareStateForQuery(newSearchString) {
6214
6334
  const hasNewSearchQuery = typeof newSearchString !== 'undefined';
6215
6335
  const searchString = newSearchString ?? this.searchQuery;
6216
6336
  if (hasNewSearchQuery) {
@@ -6219,20 +6339,50 @@ class BaseSearchSource {
6219
6339
  else {
6220
6340
  this.state.partialNext({ isLoading: true });
6221
6341
  }
6342
+ return { searchString, hasNewSearchQuery };
6343
+ }
6344
+ updatePaginationStateFromQuery(result) {
6345
+ const { items, next } = result;
6222
6346
  const stateUpdate = {};
6347
+ if (Object.prototype.hasOwnProperty.call(result, 'next')) {
6348
+ stateUpdate.next = next;
6349
+ stateUpdate.hasNext = !!next;
6350
+ }
6351
+ else {
6352
+ stateUpdate.offset = (this.offset ?? 0) + items.length;
6353
+ stateUpdate.hasNext = items.length === this.pageSize;
6354
+ }
6355
+ return stateUpdate;
6356
+ }
6357
+ resetState() {
6358
+ this.state.next(this.initialState);
6359
+ }
6360
+ resetStateAndActivate() {
6361
+ this.resetState();
6362
+ this.activate();
6363
+ }
6364
+ }
6365
+ class BaseSearchSource extends BaseSearchSourceBase {
6366
+ constructor(options) {
6367
+ const { debounceMs } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
6368
+ super(options);
6369
+ this.setDebounceOptions = ({ debounceMs }) => {
6370
+ this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
6371
+ };
6372
+ this.search = (searchQuery) => this.searchDebounced(searchQuery);
6373
+ this.setDebounceOptions({ debounceMs });
6374
+ }
6375
+ async executeQuery(newSearchString) {
6376
+ if (!this.canExecuteQuery(newSearchString))
6377
+ return;
6378
+ const { hasNewSearchQuery, searchString } = this.prepareStateForQuery(newSearchString);
6379
+ let stateUpdate = {};
6223
6380
  try {
6224
6381
  const results = await this.query(searchString);
6225
6382
  if (!results)
6226
6383
  return;
6227
- const { items, next } = results;
6228
- if (typeof next === 'string' || next === null) {
6229
- stateUpdate.next = next;
6230
- stateUpdate.hasNext = !!next;
6231
- }
6232
- else {
6233
- stateUpdate.offset = (this.offset ?? 0) + items.length;
6234
- stateUpdate.hasNext = items.length === this.pageSize;
6235
- }
6384
+ const { items } = results;
6385
+ stateUpdate = this.updatePaginationStateFromQuery(results);
6236
6386
  stateUpdate.items = await this.filterQueryResults(items);
6237
6387
  }
6238
6388
  catch (e) {
@@ -6245,118 +6395,39 @@ class BaseSearchSource {
6245
6395
  cancelScheduledQuery() {
6246
6396
  this.searchDebounced.cancel();
6247
6397
  }
6248
- resetState() {
6249
- this.state.next(this.initialState);
6250
- }
6251
- resetStateAndActivate() {
6252
- this.resetState();
6253
- this.activate();
6254
- }
6255
6398
  }
6256
-
6257
- class SearchController {
6258
- constructor({ config, sources } = {}) {
6259
- this.addSource = (source) => {
6260
- this.state.partialNext({
6261
- sources: [...this.sources, source],
6262
- });
6263
- };
6264
- this.getSource = (sourceType) => this.sources.find((s) => s.type === sourceType);
6265
- this.removeSource = (sourceType) => {
6266
- const newSources = this.sources.filter((s) => s.type !== sourceType);
6267
- if (newSources.length === this.sources.length)
6268
- return;
6269
- this.state.partialNext({ sources: newSources });
6270
- };
6271
- this.activateSource = (sourceType) => {
6272
- const source = this.getSource(sourceType);
6273
- if (!source || source.isActive)
6274
- return;
6275
- if (this.config.keepSingleActiveSource) {
6276
- this.sources.forEach((s) => {
6277
- if (s.type !== sourceType) {
6278
- s.deactivate();
6279
- }
6280
- });
6281
- }
6282
- source.activate();
6283
- this.state.partialNext({ sources: [...this.sources] });
6284
- };
6285
- this.deactivateSource = (sourceType) => {
6286
- const source = this.getSource(sourceType);
6287
- if (!source?.isActive)
6288
- return;
6289
- if (this.activeSources.length === 1)
6290
- return;
6291
- source.deactivate();
6292
- this.state.partialNext({ sources: [...this.sources] });
6293
- };
6294
- this.activate = () => {
6295
- if (!this.activeSources.length) {
6296
- const sourcesToActivate = this.config.keepSingleActiveSource
6297
- ? this.sources.slice(0, 1)
6298
- : this.sources;
6299
- sourcesToActivate.forEach((s) => s.activate());
6300
- }
6301
- if (this.isActive)
6302
- return;
6303
- this.state.partialNext({ isActive: true });
6304
- };
6305
- this.search = async (searchQuery) => {
6306
- const searchedSources = this.activeSources;
6307
- this.state.partialNext({
6308
- searchQuery,
6309
- });
6310
- await Promise.all(searchedSources.map((source) => source.search(searchQuery)));
6311
- };
6312
- this.cancelSearchQueries = () => {
6313
- this.activeSources.forEach((s) => s.cancelScheduledQuery());
6314
- };
6315
- this.clear = () => {
6316
- this.cancelSearchQueries();
6317
- this.sources.forEach((source) => source.state.next({ ...source.initialState, isActive: source.isActive }));
6318
- this.state.next((current) => ({
6319
- ...current,
6320
- isActive: true,
6321
- queriesInProgress: [],
6322
- searchQuery: '',
6323
- }));
6324
- };
6325
- this.exit = () => {
6326
- this.cancelSearchQueries();
6327
- this.sources.forEach((source) => source.state.next({ ...source.initialState, isActive: source.isActive }));
6328
- this.state.next((current) => ({
6329
- ...current,
6330
- isActive: false,
6331
- queriesInProgress: [],
6332
- searchQuery: '',
6333
- }));
6399
+ class BaseSearchSourceSync extends BaseSearchSourceBase {
6400
+ constructor(options) {
6401
+ const { debounceMs } = { ...DEFAULT_SEARCH_SOURCE_OPTIONS, ...options };
6402
+ super(options);
6403
+ this.setDebounceOptions = ({ debounceMs }) => {
6404
+ this.searchDebounced = debounce(this.executeQuery.bind(this), debounceMs);
6334
6405
  };
6335
- this.state = new StateStore({
6336
- isActive: false,
6337
- searchQuery: '',
6338
- sources: sources ?? [],
6339
- });
6340
- this._internalState = new StateStore({});
6341
- this.config = { keepSingleActiveSource: true, ...config };
6342
- }
6343
- get hasNext() {
6344
- return this.sources.some((source) => source.hasNext);
6345
- }
6346
- get sources() {
6347
- return this.state.getLatestValue().sources;
6348
- }
6349
- get activeSources() {
6350
- return this.state.getLatestValue().sources.filter((s) => s.isActive);
6351
- }
6352
- get isActive() {
6353
- return this.state.getLatestValue().isActive;
6406
+ this.search = (searchQuery) => this.searchDebounced(searchQuery);
6407
+ this.setDebounceOptions({ debounceMs });
6354
6408
  }
6355
- get searchQuery() {
6356
- return this.state.getLatestValue().searchQuery;
6409
+ executeQuery(newSearchString) {
6410
+ if (!this.canExecuteQuery(newSearchString))
6411
+ return;
6412
+ const { hasNewSearchQuery, searchString } = this.prepareStateForQuery(newSearchString);
6413
+ let stateUpdate = {};
6414
+ try {
6415
+ const results = this.query(searchString);
6416
+ if (!results)
6417
+ return;
6418
+ const { items } = results;
6419
+ stateUpdate = this.updatePaginationStateFromQuery(results);
6420
+ stateUpdate.items = this.filterQueryResults(items);
6421
+ }
6422
+ catch (e) {
6423
+ stateUpdate.lastQueryError = e;
6424
+ }
6425
+ finally {
6426
+ this.state.next(this.getStateAfterQuery(stateUpdate, hasNewSearchQuery));
6427
+ }
6357
6428
  }
6358
- get searchSourceTypes() {
6359
- return this.sources.map((s) => s.type);
6429
+ cancelScheduledQuery() {
6430
+ this.searchDebounced.cancel();
6360
6431
  }
6361
6432
  }
6362
6433
 
@@ -6385,42 +6456,12 @@ class ActivitySearchSource extends BaseSearchSource {
6385
6456
  }
6386
6457
  }
6387
6458
 
6388
- class UserSearchSource extends BaseSearchSource {
6389
- constructor(client, options) {
6390
- super(options);
6391
- this.type = 'user';
6392
- this.client = client;
6393
- }
6394
- async query(searchQuery) {
6395
- const { connected_user: connectedUser } = this.client.state.getLatestValue();
6396
- if (!connectedUser)
6397
- return { items: [] };
6398
- const { users: items } = await this.client.queryUsers({
6399
- payload: {
6400
- filter_conditions: {
6401
- ...(!this.allowEmptySearchString || searchQuery.length > 0
6402
- ? {
6403
- name: {
6404
- $autocomplete: searchQuery,
6405
- },
6406
- }
6407
- : {}),
6408
- },
6409
- },
6410
- });
6411
- return { items, next: undefined };
6412
- }
6413
- filterQueryResults(items) {
6414
- return items;
6415
- }
6416
- }
6417
-
6418
6459
  class FeedSearchSource extends BaseSearchSource {
6419
6460
  constructor(client, options) {
6420
6461
  super(options);
6421
- this.type = 'feed';
6422
6462
  this.client = client;
6423
6463
  this.feedGroupId = options?.groupId;
6464
+ this.type = `${this.feedGroupId}-feed`;
6424
6465
  }
6425
6466
  async query(searchQuery) {
6426
6467
  const { connected_user: connectedUser } = this.client.state.getLatestValue();
@@ -6448,8 +6489,39 @@ class FeedSearchSource extends BaseSearchSource {
6448
6489
  }
6449
6490
  }
6450
6491
 
6492
+ class UserSearchSource extends BaseSearchSource {
6493
+ constructor(client, options) {
6494
+ super(options);
6495
+ this.type = 'user';
6496
+ this.client = client;
6497
+ }
6498
+ async query(searchQuery) {
6499
+ const { connected_user: connectedUser } = this.client.state.getLatestValue();
6500
+ if (!connectedUser)
6501
+ return { items: [] };
6502
+ const { users: items } = await this.client.queryUsers({
6503
+ payload: {
6504
+ filter_conditions: {
6505
+ ...(!this.allowEmptySearchString || searchQuery.length > 0
6506
+ ? {
6507
+ name: {
6508
+ $autocomplete: searchQuery,
6509
+ },
6510
+ }
6511
+ : {}),
6512
+ },
6513
+ },
6514
+ });
6515
+ return { items, next: undefined };
6516
+ }
6517
+ filterQueryResults(items) {
6518
+ return items;
6519
+ }
6520
+ }
6521
+
6451
6522
  exports.ActivitySearchSource = ActivitySearchSource;
6452
6523
  exports.BaseSearchSource = BaseSearchSource;
6524
+ exports.BaseSearchSourceSync = BaseSearchSourceSync;
6453
6525
  exports.ChannelOwnCapability = ChannelOwnCapability;
6454
6526
  exports.Constants = Constants;
6455
6527
  exports.Feed = Feed;