@amityco/ts-sdk 7.6.1-c97e594b.0 → 7.6.1-ce05a481.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.
Files changed (145) hide show
  1. package/dist/@types/core/payload.d.ts +1 -1
  2. package/dist/@types/core/payload.d.ts.map +1 -1
  3. package/dist/@types/domains/channel.d.ts +0 -2
  4. package/dist/@types/domains/channel.d.ts.map +1 -1
  5. package/dist/@types/domains/content.d.ts +8 -2
  6. package/dist/@types/domains/content.d.ts.map +1 -1
  7. package/dist/@types/domains/feed.d.ts +6 -1
  8. package/dist/@types/domains/feed.d.ts.map +1 -1
  9. package/dist/@types/domains/file.d.ts +3 -1
  10. package/dist/@types/domains/file.d.ts.map +1 -1
  11. package/dist/@types/domains/post.d.ts +3 -3
  12. package/dist/@types/domains/post.d.ts.map +1 -1
  13. package/dist/@types/domains/stream.d.ts +0 -4
  14. package/dist/@types/domains/stream.d.ts.map +1 -1
  15. package/dist/channelRepository/api/createChannel.d.ts +1 -3
  16. package/dist/channelRepository/api/createChannel.d.ts.map +1 -1
  17. package/dist/channelRepository/internalApi/getChannel.d.ts.map +1 -1
  18. package/dist/communityRepository/api/getCommunity.d.ts +1 -1
  19. package/dist/communityRepository/api/getCommunity.d.ts.map +1 -1
  20. package/dist/core/model/index.d.ts.map +1 -1
  21. package/dist/feedRepository/api/getCustomRankingGlobalFeed.d.ts +1 -1
  22. package/dist/feedRepository/api/getCustomRankingGlobalFeed.d.ts.map +1 -1
  23. package/dist/feedRepository/api/queryGlobalFeed.d.ts.map +1 -1
  24. package/dist/feedRepository/index.d.ts +1 -1
  25. package/dist/feedRepository/index.d.ts.map +1 -1
  26. package/dist/feedRepository/observers/getCustomRankingGlobalFeed/LiveCollectionController.d.ts +13 -0
  27. package/dist/feedRepository/observers/getCustomRankingGlobalFeed/LiveCollectionController.d.ts.map +1 -0
  28. package/dist/feedRepository/observers/getCustomRankingGlobalFeed/PaginationController.d.ts +5 -0
  29. package/dist/feedRepository/observers/getCustomRankingGlobalFeed/PaginationController.d.ts.map +1 -0
  30. package/dist/feedRepository/observers/getCustomRankingGlobalFeed/QueryStreamController.d.ts +15 -0
  31. package/dist/feedRepository/observers/getCustomRankingGlobalFeed/QueryStreamController.d.ts.map +1 -0
  32. package/dist/feedRepository/observers/getCustomRankingGlobalFeed.d.ts +23 -0
  33. package/dist/feedRepository/observers/getCustomRankingGlobalFeed.d.ts.map +1 -0
  34. package/dist/feedRepository/observers/getGlobalFeed/LiveCollectionController.d.ts +13 -0
  35. package/dist/feedRepository/observers/getGlobalFeed/LiveCollectionController.d.ts.map +1 -0
  36. package/dist/feedRepository/observers/getGlobalFeed/PaginationController.d.ts +5 -0
  37. package/dist/feedRepository/observers/getGlobalFeed/PaginationController.d.ts.map +1 -0
  38. package/dist/feedRepository/observers/getGlobalFeed/QueryStreamController.d.ts +15 -0
  39. package/dist/feedRepository/observers/getGlobalFeed/QueryStreamController.d.ts.map +1 -0
  40. package/dist/feedRepository/observers/getGlobalFeed.d.ts +22 -0
  41. package/dist/feedRepository/observers/getGlobalFeed.d.ts.map +1 -0
  42. package/dist/feedRepository/observers/index.d.ts +3 -0
  43. package/dist/feedRepository/observers/index.d.ts.map +1 -0
  44. package/dist/feedRepository/observers/utils.d.ts +6 -0
  45. package/dist/feedRepository/observers/utils.d.ts.map +1 -0
  46. package/dist/fileRepository/api/index.d.ts +1 -0
  47. package/dist/fileRepository/api/index.d.ts.map +1 -1
  48. package/dist/fileRepository/api/uploadClip.d.ts +17 -0
  49. package/dist/fileRepository/api/uploadClip.d.ts.map +1 -0
  50. package/dist/index.cjs.js +7384 -7173
  51. package/dist/index.esm.js +9384 -9173
  52. package/dist/index.umd.js +3 -3
  53. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts +0 -2
  54. package/dist/messagePreview/utils/getChannelMessagePreviewWithUser.d.ts.map +1 -1
  55. package/dist/messagePreview/utils/getSubChannelMessagePreviewWithUser.d.ts +1 -1
  56. package/dist/messageRepository/api/deleteMessage.d.ts.map +1 -1
  57. package/dist/messageRepository/observers/getMessages/MessageQueryStreamController.d.ts.map +1 -1
  58. package/dist/postRepository/api/createClipPost.d.ts +32 -0
  59. package/dist/postRepository/api/createClipPost.d.ts.map +1 -0
  60. package/dist/postRepository/api/createPost.d.ts.map +1 -1
  61. package/dist/postRepository/api/index.d.ts +1 -0
  62. package/dist/postRepository/api/index.d.ts.map +1 -1
  63. package/dist/postRepository/events/utils.d.ts.map +1 -1
  64. package/dist/postRepository/observers/getGlobalPinnedPosts/GlobalPinnedPostLiveCollectionController.d.ts.map +1 -1
  65. package/dist/postRepository/observers/getPinnedPosts/PinnedPostLiveCollectionController.d.ts.map +1 -1
  66. package/dist/postRepository/observers/getPinnedPosts/PinnedPostQueryStreamController.d.ts +6 -0
  67. package/dist/postRepository/observers/getPinnedPosts/PinnedPostQueryStreamController.d.ts.map +1 -1
  68. package/dist/postRepository/observers/getPosts/PostLiveCollectionController.d.ts.map +1 -1
  69. package/dist/postRepository/observers/utils.d.ts +13 -0
  70. package/dist/postRepository/observers/utils.d.ts.map +1 -0
  71. package/dist/postRepository/utils/payload.d.ts.map +1 -1
  72. package/dist/reactionRepository/api/addReaction.d.ts.map +1 -1
  73. package/dist/reactionRepository/api/removeReaction.d.ts.map +1 -1
  74. package/dist/streamRepository/api/createStream.d.ts +1 -1
  75. package/dist/streamRepository/api/createStream.d.ts.map +1 -1
  76. package/dist/streamRepository/api/index.d.ts +0 -1
  77. package/dist/streamRepository/api/index.d.ts.map +1 -1
  78. package/dist/streamRepository/api/updateStream.d.ts +1 -4
  79. package/dist/streamRepository/api/updateStream.d.ts.map +1 -1
  80. package/dist/streamRepository/internalApi/getStream.d.ts +2 -2
  81. package/dist/streamRepository/internalApi/getStream.d.ts.map +1 -1
  82. package/dist/utils/linkedObject/postLinkedObject.d.ts.map +1 -1
  83. package/dist/utils/linkedObject/streamLinkedObject.d.ts.map +1 -1
  84. package/dist/utils/postTypePredicate.d.ts +4 -5
  85. package/dist/utils/postTypePredicate.d.ts.map +1 -1
  86. package/dist/utils/tests/dummy/comment.d.ts +1 -1
  87. package/package.json +1 -1
  88. package/src/@types/core/payload.ts +1 -1
  89. package/src/@types/domains/channel.ts +0 -3
  90. package/src/@types/domains/content.ts +10 -0
  91. package/src/@types/domains/feed.ts +18 -1
  92. package/src/@types/domains/file.ts +5 -0
  93. package/src/@types/domains/post.ts +4 -4
  94. package/src/@types/domains/stream.ts +0 -4
  95. package/src/channelRepository/api/createChannel.ts +9 -12
  96. package/src/channelRepository/internalApi/getChannel.ts +1 -0
  97. package/src/channelRepository/utils/constructChannelObject.ts +2 -2
  98. package/src/commentRepository/api/deleteComment.ts +6 -6
  99. package/src/communityRepository/api/getCommunity.ts +0 -9
  100. package/src/core/model/index.ts +2 -1
  101. package/src/feedRepository/api/getCustomRankingGlobalFeed.ts +1 -1
  102. package/src/feedRepository/api/queryGlobalFeed.ts +3 -1
  103. package/src/feedRepository/index.ts +1 -1
  104. package/src/feedRepository/observers/getCustomRankingGlobalFeed/LiveCollectionController.ts +95 -0
  105. package/src/feedRepository/observers/getCustomRankingGlobalFeed/PaginationController.ts +25 -0
  106. package/src/feedRepository/observers/getCustomRankingGlobalFeed/QueryStreamController.ts +101 -0
  107. package/src/feedRepository/observers/getCustomRankingGlobalFeed.ts +57 -0
  108. package/src/feedRepository/observers/getGlobalFeed/LiveCollectionController.ts +91 -0
  109. package/src/feedRepository/observers/getGlobalFeed/PaginationController.ts +23 -0
  110. package/src/feedRepository/observers/getGlobalFeed/QueryStreamController.ts +99 -0
  111. package/src/feedRepository/observers/getGlobalFeed.ts +56 -0
  112. package/src/feedRepository/observers/index.ts +2 -0
  113. package/src/feedRepository/observers/utils.ts +85 -0
  114. package/src/fileRepository/api/index.ts +1 -0
  115. package/src/fileRepository/api/uploadClip.ts +71 -0
  116. package/src/messageRepository/api/deleteMessage.ts +0 -16
  117. package/src/messageRepository/observers/getMessages/MessageQueryStreamController.ts +0 -13
  118. package/src/postRepository/api/createClipPost.ts +62 -0
  119. package/src/postRepository/api/createPost.ts +2 -3
  120. package/src/postRepository/api/index.ts +2 -0
  121. package/src/postRepository/api/queryPosts.ts +1 -1
  122. package/src/postRepository/events/utils.ts +35 -1
  123. package/src/postRepository/observers/getGlobalPinnedPosts/GlobalPinnedPostLiveCollectionController.ts +5 -0
  124. package/src/postRepository/observers/getPinnedPosts/PinnedPostLiveCollectionController.ts +7 -1
  125. package/src/postRepository/observers/getPinnedPosts/PinnedPostQueryStreamController.ts +27 -0
  126. package/src/postRepository/observers/getPosts/PostLiveCollectionController.ts +2 -74
  127. package/src/postRepository/observers/getPosts/PostPaginationController.ts +1 -1
  128. package/src/postRepository/observers/utils.ts +97 -0
  129. package/src/postRepository/utils/payload.ts +1 -37
  130. package/src/reactionRepository/api/addReaction.ts +1 -0
  131. package/src/reactionRepository/api/removeReaction.ts +1 -0
  132. package/src/streamRepository/api/createStream.ts +1 -4
  133. package/src/streamRepository/api/index.ts +0 -1
  134. package/src/streamRepository/api/updateStream.ts +1 -8
  135. package/src/streamRepository/internalApi/getStream.ts +3 -3
  136. package/src/streamRepository/observers/getStreams/GetStreamsLiveCollectionController.ts +1 -1
  137. package/src/utils/linkedObject/postLinkedObject.ts +8 -28
  138. package/src/utils/linkedObject/streamLinkedObject.ts +0 -2
  139. package/src/utils/postTypePredicate.ts +6 -20
  140. package/dist/streamRepository/api/editStream.d.ts +0 -18
  141. package/dist/streamRepository/api/editStream.d.ts.map +0 -1
  142. package/dist/streamRepository/internalApi/getLiveChat.d.ts +0 -16
  143. package/dist/streamRepository/internalApi/getLiveChat.d.ts.map +0 -1
  144. package/src/streamRepository/api/editStream.ts +0 -51
  145. package/src/streamRepository/internalApi/getLiveChat.ts +0 -59
@@ -32,7 +32,7 @@ export const queryGlobalFeed = async (
32
32
  const client = getActiveClient();
33
33
  client.log('feed/queryGlobalFeed', query);
34
34
 
35
- const { queryToken, ...params } = query ?? {};
35
+ const { queryToken, dataTypes, resolveParent, ...params } = query ?? {};
36
36
 
37
37
  const options = (() => {
38
38
  if (queryToken) return { token: queryToken };
@@ -44,6 +44,8 @@ export const queryGlobalFeed = async (
44
44
  {
45
45
  params: {
46
46
  ...params,
47
+ dataTypes,
48
+ resolveParent: resolveParent ?? true,
47
49
  options,
48
50
  },
49
51
  },
@@ -1 +1 @@
1
- export * from './api';
1
+ export { getCustomRankingGlobalFeed, getGlobalFeed } from './observers';
@@ -0,0 +1,95 @@
1
+ import hash from 'object-hash';
2
+ import { pullFromCache, pushToCache } from '~/cache/api';
3
+ import { CustomRankingGlobalFeedPaginationController } from './PaginationController';
4
+ import { CustomRankingGlobalFeedQueryStreamController } from './QueryStreamController';
5
+ import { LiveCollectionController } from '~/core/liveCollection/LiveCollectionController';
6
+ import { isNonNullable } from '~/utils';
7
+ import { LinkedObject } from '~/utils/linkedObject';
8
+ import { preparePostPayload } from '~/postRepository/utils/payload';
9
+ import { getGlobalFeedSubscriptions } from '../utils';
10
+
11
+ export class CustomRankingGlobalFeedLiveCollectionController extends LiveCollectionController<
12
+ 'post',
13
+ Amity.CustomRankingGlobalFeedLiveCollection,
14
+ Amity.Post,
15
+ CustomRankingGlobalFeedPaginationController
16
+ > {
17
+ private queryStreamController: CustomRankingGlobalFeedQueryStreamController;
18
+
19
+ private query: Amity.CustomRankingGlobalFeedLiveCollection;
20
+
21
+ constructor(
22
+ query: Amity.CustomRankingGlobalFeedLiveCollection,
23
+ callback: Amity.LiveCollectionCallback<Amity.Post>,
24
+ ) {
25
+ const queryStreamId = hash(query);
26
+ const cacheKey = ['customRankingGlobalFeed', 'collection', queryStreamId];
27
+ const paginationController = new CustomRankingGlobalFeedPaginationController(query);
28
+
29
+ super(paginationController, queryStreamId, cacheKey, callback);
30
+
31
+ this.query = query;
32
+ this.queryStreamController = new CustomRankingGlobalFeedQueryStreamController(
33
+ this.query,
34
+ this.cacheKey,
35
+ this.notifyChange.bind(this),
36
+ preparePostPayload,
37
+ );
38
+
39
+ this.callback = callback.bind(this);
40
+ this.loadPage({ initial: true });
41
+ }
42
+
43
+ protected setup() {
44
+ const collection = pullFromCache<Amity.CustomRankingGlobalFeedLiveCollectionCache>(
45
+ this.cacheKey,
46
+ )?.data;
47
+
48
+ if (!collection) {
49
+ pushToCache(this.cacheKey, {
50
+ data: [],
51
+ params: {},
52
+ });
53
+ }
54
+ }
55
+
56
+ protected async persistModel(queryPayload: Amity.PostPayload & Amity.Pagination) {
57
+ await this.queryStreamController.saveToMainDB(queryPayload);
58
+ }
59
+
60
+ protected persistQueryStream({
61
+ response,
62
+ direction,
63
+ refresh,
64
+ }: Amity.LiveCollectionPersistQueryStreamParams<'post'>) {
65
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
66
+ }
67
+
68
+ startSubscription() {
69
+ return this.queryStreamController.subscribeRTE(getGlobalFeedSubscriptions(this.cacheKey));
70
+ }
71
+
72
+ notifyChange({ origin, loading, error }: Amity.LiveCollectionNotifyParams) {
73
+ const collection = pullFromCache<Amity.CustomRankingGlobalFeedLiveCollectionCache>(
74
+ this.cacheKey,
75
+ )?.data;
76
+ if (!collection) return;
77
+
78
+ const data = (
79
+ collection.data
80
+ .map(id => pullFromCache<Amity.InternalPost>(['post', 'get', id])!)
81
+ .filter(isNonNullable)
82
+ .map(({ data }) => data) ?? []
83
+ ).map(LinkedObject.post);
84
+
85
+ if (!this.shouldNotify(data) && origin === 'event') return;
86
+
87
+ this.callback({
88
+ onNextPage: () => this.loadPage({ direction: Amity.LiveCollectionPageDirection.NEXT }),
89
+ data,
90
+ hasNextPage: !!this.paginationController.getNextToken(),
91
+ loading,
92
+ error,
93
+ });
94
+ }
95
+ }
@@ -0,0 +1,25 @@
1
+ import { PaginationController } from '~/core/liveCollection/PaginationController';
2
+
3
+ export class CustomRankingGlobalFeedPaginationController extends PaginationController<
4
+ 'post',
5
+ Amity.CustomRankingGlobalFeedLiveCollection
6
+ > {
7
+ async getRequest(
8
+ queryParams: Amity.CustomRankingGlobalFeedLiveCollection,
9
+ token: string | undefined,
10
+ ) {
11
+ const { limit, ...params } = queryParams;
12
+ const options = token ? { token } : { limit };
13
+
14
+ const { data: queryResponse } = await this.http.get<Amity.PostPayload & Amity.Pagination>(
15
+ `/api/v5/me/global-feeds`,
16
+ {
17
+ params: {
18
+ ...params,
19
+ options,
20
+ },
21
+ },
22
+ );
23
+ return queryResponse;
24
+ }
25
+ }
@@ -0,0 +1,101 @@
1
+ import { QueryStreamController } from '~/core/liveCollection/QueryStreamController';
2
+ import { pullFromCache, pushToCache } from '~/cache/api';
3
+ import { ingestInCache } from '~/cache/api/ingestInCache';
4
+ import { getResolver } from '~/core/model';
5
+ import { getActiveClient } from '~/client';
6
+ import { EnumPostActions } from '~/postRepository/observers/enums';
7
+
8
+ export class CustomRankingGlobalFeedQueryStreamController extends QueryStreamController<
9
+ Amity.PostPayload,
10
+ Amity.CustomRankingGlobalFeedLiveCollection
11
+ > {
12
+ private notifyChange: (params: Amity.LiveCollectionNotifyParams) => void;
13
+
14
+ private preparePayload: (response: Amity.PostPayload) => Amity.ProcessedPostPayload;
15
+
16
+ constructor(
17
+ query: Amity.CustomRankingGlobalFeedLiveCollection,
18
+ cacheKey: string[],
19
+ notifyChange: (params: Amity.LiveCollectionNotifyParams) => void,
20
+ preparePayload: (response: Amity.PostPayload) => Amity.ProcessedPostPayload,
21
+ ) {
22
+ super(query, cacheKey);
23
+ this.notifyChange = notifyChange;
24
+ this.preparePayload = preparePayload;
25
+ }
26
+
27
+ async saveToMainDB(response: Amity.PostPayload) {
28
+ const processedPayload = await this.preparePayload(response);
29
+
30
+ const client = getActiveClient();
31
+ const cachedAt = client.cache && Date.now();
32
+
33
+ if (client.cache) {
34
+ ingestInCache(processedPayload, { cachedAt });
35
+ }
36
+ }
37
+
38
+ appendToQueryStream(
39
+ response: Amity.PostPayload & Partial<Amity.Pagination>,
40
+ direction: Amity.LiveCollectionPageDirection,
41
+ refresh = false,
42
+ ) {
43
+ if (refresh) {
44
+ pushToCache(this.cacheKey, {
45
+ data: response.posts.map(getResolver('post')),
46
+ });
47
+ } else {
48
+ const collection = pullFromCache<Amity.CommunityLiveCollectionCache>(this.cacheKey)?.data;
49
+
50
+ const posts = collection?.data ?? [];
51
+
52
+ pushToCache(this.cacheKey, {
53
+ ...collection,
54
+ data: [...new Set([...posts, ...response.posts.map(getResolver('post'))])],
55
+ });
56
+ }
57
+ }
58
+
59
+ reactor(action: EnumPostActions) {
60
+ return (post: Amity.InternalPost) => {
61
+ const collection = pullFromCache<Amity.CustomRankingGlobalFeedLiveCollectionCache>(
62
+ this.cacheKey,
63
+ )?.data;
64
+
65
+ if (!collection) return;
66
+
67
+ if (post.parentPostId && !collection.data.includes(post.parentPostId)) return;
68
+
69
+ // Delete Action
70
+ if (action === EnumPostActions.OnPostDeleted) {
71
+ // Parent Post - Remove from collection
72
+ collection.data = collection.data.filter(postId => postId !== post.postId);
73
+ }
74
+
75
+ if (action === EnumPostActions.OnPostCreated || action === EnumPostActions.OnPostApproved) {
76
+ // If the query has dataTypes array with value, check if post.dataType is include in the array
77
+ if (this.query.dataTypes && this.query.dataTypes.length > 0) {
78
+ if (!this.query.dataTypes.includes(post.dataType)) return;
79
+ }
80
+
81
+ collection.data = [...new Set([post.postId, ...collection.data])];
82
+ }
83
+
84
+ if (action === EnumPostActions.OnPostDeclined) {
85
+ collection.data = collection.data.filter(postId => postId !== post.postId);
86
+ }
87
+
88
+ pushToCache(this.cacheKey, collection);
89
+ this.notifyChange({ origin: Amity.LiveDataOrigin.EVENT, loading: false });
90
+ };
91
+ }
92
+
93
+ subscribeRTE(
94
+ createSubscriber: {
95
+ fn: (reactor: (post: Amity.InternalPost) => void) => Amity.Unsubscriber;
96
+ action: EnumPostActions;
97
+ }[],
98
+ ) {
99
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
100
+ }
101
+ }
@@ -0,0 +1,57 @@
1
+ import { getActiveClient } from '~/client/api';
2
+ import { dropFromCache } from '~/cache/api';
3
+
4
+ import { ENABLE_CACHE_MESSAGE } from '~/utils/constants';
5
+ import { CustomRankingGlobalFeedLiveCollectionController } from './getCustomRankingGlobalFeed/LiveCollectionController';
6
+
7
+ /* begin_public_function
8
+ id: post.query
9
+ */
10
+ /**
11
+ * ```js
12
+ * import { PostRepository } from '@amityco/ts-sdk'
13
+ *
14
+ * let posts = []
15
+ * const unsub = PostRepository.getPosts({
16
+ * targetType: Amity.PostTargetType,
17
+ * targetId: Amity.Post['targetId'],
18
+ * }, response => merge(posts, response.data))
19
+ * ```
20
+ *
21
+ * Observe all mutations on a list of {@link Amity.Post} for a given target object
22
+ *
23
+ * @param params.targetType the type of the target
24
+ * @param params.targetId the ID of the target
25
+ * @param callback the function to call when new data are available
26
+ * @param config
27
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
28
+ *
29
+ * @category Posts Live Collection
30
+ */
31
+ export const getCustomRankingGlobalFeed = (
32
+ params: Amity.CustomRankingGlobalFeedLiveCollection,
33
+ callback: Amity.LiveCollectionCallback<Amity.Post>,
34
+ config?: Amity.LiveCollectionConfig,
35
+ ): Amity.Unsubscriber => {
36
+ const { log, cache } = getActiveClient();
37
+
38
+ if (!cache) {
39
+ console.log(ENABLE_CACHE_MESSAGE);
40
+ }
41
+
42
+ const timestamp = Date.now();
43
+ log(`getCustomRankingGlobalFeed(tmpid: ${timestamp}) > listen`);
44
+
45
+ const liveCollection = new CustomRankingGlobalFeedLiveCollectionController(params, callback);
46
+ const disposers = liveCollection.startSubscription();
47
+
48
+ const cacheKey = liveCollection.getCacheKey();
49
+
50
+ disposers.push(() => dropFromCache(cacheKey));
51
+
52
+ return () => {
53
+ log(`getCustomRankingGlobalFeed(tmpid: ${timestamp}) > dispose`);
54
+ disposers.forEach(fn => fn());
55
+ };
56
+ };
57
+ /* end_public_function */
@@ -0,0 +1,91 @@
1
+ import hash from 'object-hash';
2
+ import { pullFromCache, pushToCache } from '~/cache/api';
3
+ import { GlobalFeedPaginationController } from './PaginationController';
4
+ import { GlobalFeedQueryStreamController } from './QueryStreamController';
5
+ import { LiveCollectionController } from '~/core/liveCollection/LiveCollectionController';
6
+ import { isNonNullable } from '~/utils';
7
+ import { LinkedObject } from '~/utils/linkedObject';
8
+ import { preparePostPayload } from '~/postRepository/utils/payload';
9
+ import { getGlobalFeedSubscriptions } from '../utils';
10
+
11
+ export class GlobalFeedLiveCollectionController extends LiveCollectionController<
12
+ 'post',
13
+ Amity.GlobalFeedLiveCollection,
14
+ Amity.Post,
15
+ GlobalFeedPaginationController
16
+ > {
17
+ private queryStreamController: GlobalFeedQueryStreamController;
18
+
19
+ private query: Amity.GlobalFeedLiveCollection;
20
+
21
+ constructor(
22
+ query: Amity.GlobalFeedLiveCollection,
23
+ callback: Amity.LiveCollectionCallback<Amity.Post>,
24
+ ) {
25
+ const queryStreamId = hash(query);
26
+ const cacheKey = ['globalFeed', 'collection', queryStreamId];
27
+ const paginationController = new GlobalFeedPaginationController(query);
28
+
29
+ super(paginationController, queryStreamId, cacheKey, callback);
30
+
31
+ this.query = query;
32
+ this.queryStreamController = new GlobalFeedQueryStreamController(
33
+ this.query,
34
+ this.cacheKey,
35
+ this.notifyChange.bind(this),
36
+ preparePostPayload,
37
+ );
38
+
39
+ this.callback = callback.bind(this);
40
+ this.loadPage({ initial: true });
41
+ }
42
+
43
+ protected setup() {
44
+ const collection = pullFromCache<Amity.GlobalFeedLiveCollectionCache>(this.cacheKey)?.data;
45
+
46
+ if (!collection) {
47
+ pushToCache(this.cacheKey, {
48
+ data: [],
49
+ params: {},
50
+ });
51
+ }
52
+ }
53
+
54
+ protected async persistModel(queryPayload: Amity.PostPayload & Amity.Pagination) {
55
+ await this.queryStreamController.saveToMainDB(queryPayload);
56
+ }
57
+
58
+ protected persistQueryStream({
59
+ response,
60
+ direction,
61
+ refresh,
62
+ }: Amity.LiveCollectionPersistQueryStreamParams<'post'>) {
63
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
64
+ }
65
+
66
+ startSubscription() {
67
+ return this.queryStreamController.subscribeRTE(getGlobalFeedSubscriptions(this.cacheKey));
68
+ }
69
+
70
+ notifyChange({ origin, loading, error }: Amity.LiveCollectionNotifyParams) {
71
+ const collection = pullFromCache<Amity.GlobalFeedLiveCollectionCache>(this.cacheKey)?.data;
72
+ if (!collection) return;
73
+
74
+ const data = (
75
+ collection.data
76
+ .map(id => pullFromCache<Amity.InternalPost>(['post', 'get', id])!)
77
+ .filter(isNonNullable)
78
+ .map(({ data }) => data) ?? []
79
+ ).map(LinkedObject.post);
80
+
81
+ if (!this.shouldNotify(data) && origin === 'event') return;
82
+
83
+ this.callback({
84
+ onNextPage: () => this.loadPage({ direction: Amity.LiveCollectionPageDirection.NEXT }),
85
+ data,
86
+ hasNextPage: !!this.paginationController.getNextToken(),
87
+ loading,
88
+ error,
89
+ });
90
+ }
91
+ }
@@ -0,0 +1,23 @@
1
+ import { PaginationController } from '~/core/liveCollection/PaginationController';
2
+
3
+ export class GlobalFeedPaginationController extends PaginationController<
4
+ 'post',
5
+ Amity.GlobalFeedLiveCollection
6
+ > {
7
+ async getRequest(queryParams: Amity.GlobalFeedLiveCollection, token: string | undefined) {
8
+ const { limit, resolveParent, ...params } = queryParams;
9
+ const options = token ? { token } : { limit };
10
+
11
+ const { data: queryResponse } = await this.http.get<Amity.PostPayload & Amity.Pagination>(
12
+ `/api/v4/me/global-feeds`,
13
+ {
14
+ params: {
15
+ ...params,
16
+ resolveParent: resolveParent ?? true,
17
+ options,
18
+ },
19
+ },
20
+ );
21
+ return queryResponse;
22
+ }
23
+ }
@@ -0,0 +1,99 @@
1
+ import { QueryStreamController } from '~/core/liveCollection/QueryStreamController';
2
+ import { pullFromCache, pushToCache } from '~/cache/api';
3
+ import { ingestInCache } from '~/cache/api/ingestInCache';
4
+ import { getResolver } from '~/core/model';
5
+ import { getActiveClient } from '~/client';
6
+ import { EnumPostActions } from '~/postRepository/observers/enums';
7
+
8
+ export class GlobalFeedQueryStreamController extends QueryStreamController<
9
+ Amity.PostPayload,
10
+ Amity.GlobalFeedLiveCollection
11
+ > {
12
+ private notifyChange: (params: Amity.LiveCollectionNotifyParams) => void;
13
+
14
+ private preparePayload: (response: Amity.PostPayload) => Amity.ProcessedPostPayload;
15
+
16
+ constructor(
17
+ query: Amity.GlobalFeedLiveCollection,
18
+ cacheKey: string[],
19
+ notifyChange: (params: Amity.LiveCollectionNotifyParams) => void,
20
+ preparePayload: (response: Amity.PostPayload) => Amity.ProcessedPostPayload,
21
+ ) {
22
+ super(query, cacheKey);
23
+ this.notifyChange = notifyChange;
24
+ this.preparePayload = preparePayload;
25
+ }
26
+
27
+ async saveToMainDB(response: Amity.PostPayload) {
28
+ const processedPayload = await this.preparePayload(response);
29
+
30
+ const client = getActiveClient();
31
+ const cachedAt = client.cache && Date.now();
32
+
33
+ if (client.cache) {
34
+ ingestInCache(processedPayload, { cachedAt });
35
+ }
36
+ }
37
+
38
+ appendToQueryStream(
39
+ response: Amity.PostPayload & Partial<Amity.Pagination>,
40
+ direction: Amity.LiveCollectionPageDirection,
41
+ refresh = false,
42
+ ) {
43
+ if (refresh) {
44
+ pushToCache(this.cacheKey, {
45
+ data: response.posts.map(getResolver('post')),
46
+ });
47
+ } else {
48
+ const collection = pullFromCache<Amity.CommunityLiveCollectionCache>(this.cacheKey)?.data;
49
+
50
+ const posts = collection?.data ?? [];
51
+
52
+ pushToCache(this.cacheKey, {
53
+ ...collection,
54
+ data: [...new Set([...posts, ...response.posts.map(getResolver('post'))])],
55
+ });
56
+ }
57
+ }
58
+
59
+ reactor(action: EnumPostActions) {
60
+ return (post: Amity.InternalPost) => {
61
+ const collection = pullFromCache<Amity.GlobalFeedLiveCollectionCache>(this.cacheKey)?.data;
62
+
63
+ if (!collection) return;
64
+
65
+ if (post.parentPostId && !collection.data.includes(post.parentPostId)) return;
66
+
67
+ // Delete Action
68
+ if (action === EnumPostActions.OnPostDeleted) {
69
+ // Parent Post - Remove from collection
70
+ collection.data = collection.data.filter(postId => postId !== post.postId);
71
+ }
72
+
73
+ if (action === EnumPostActions.OnPostCreated || action === EnumPostActions.OnPostApproved) {
74
+ // If the query has dataTypes array with value, check if post.dataType is include in the array
75
+ if (this.query.dataTypes && this.query.dataTypes.length > 0) {
76
+ if (!this.query.dataTypes.includes(post.dataType)) return;
77
+ }
78
+
79
+ collection.data = [...new Set([post.postId, ...collection.data])];
80
+ }
81
+
82
+ if (action === EnumPostActions.OnPostDeclined) {
83
+ collection.data = collection.data.filter(postId => postId !== post.postId);
84
+ }
85
+
86
+ pushToCache(this.cacheKey, collection);
87
+ this.notifyChange({ origin: Amity.LiveDataOrigin.EVENT, loading: false });
88
+ };
89
+ }
90
+
91
+ subscribeRTE(
92
+ createSubscriber: {
93
+ fn: (reactor: (post: Amity.InternalPost) => void) => Amity.Unsubscriber;
94
+ action: EnumPostActions;
95
+ }[],
96
+ ) {
97
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
98
+ }
99
+ }
@@ -0,0 +1,56 @@
1
+ import { getActiveClient } from '~/client/api';
2
+ import { dropFromCache } from '~/cache/api';
3
+
4
+ import { ENABLE_CACHE_MESSAGE } from '~/utils/constants';
5
+ import { GlobalFeedLiveCollectionController } from './getGlobalFeed/LiveCollectionController';
6
+
7
+ /* begin_public_function
8
+ id: post.query
9
+ */
10
+ /**
11
+ * ```js
12
+ * import { PostRepository } from '@amityco/ts-sdk'
13
+ *
14
+ * let posts = []
15
+ * const unsub = PostRepository.getPosts({
16
+ * targetType: Amity.PostTargetType,
17
+ * targetId: Amity.Post['targetId'],
18
+ * }, response => merge(posts, response.data))
19
+ * ```
20
+ *
21
+ * Observe all mutations on a list of {@link Amity.Post} for a given target object
22
+ * @param params.targetType the type of the target
23
+ * @param params.targetId the ID of the target
24
+ * @param callback the function to call when new data are available
25
+ * @param config
26
+ * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
27
+ *
28
+ * @category Posts Live Collection
29
+ */
30
+ export const getGlobalFeed = (
31
+ params: Amity.GlobalFeedLiveCollection,
32
+ callback: Amity.LiveCollectionCallback<Amity.Post>,
33
+ config?: Amity.LiveCollectionConfig,
34
+ ): Amity.Unsubscriber => {
35
+ const { log, cache } = getActiveClient();
36
+
37
+ if (!cache) {
38
+ console.log(ENABLE_CACHE_MESSAGE);
39
+ }
40
+
41
+ const timestamp = Date.now();
42
+ log(`getGlobalFeed(tmpid: ${timestamp}) > listen`);
43
+
44
+ const liveCollection = new GlobalFeedLiveCollectionController(params, callback);
45
+ const disposers = liveCollection.startSubscription();
46
+
47
+ const cacheKey = liveCollection.getCacheKey();
48
+
49
+ disposers.push(() => dropFromCache(cacheKey));
50
+
51
+ return () => {
52
+ log(`getGlobalFeed(tmpid: ${timestamp}) > dispose`);
53
+ disposers.forEach(fn => fn());
54
+ };
55
+ };
56
+ /* end_public_function */
@@ -0,0 +1,2 @@
1
+ export { getCustomRankingGlobalFeed } from './getCustomRankingGlobalFeed';
2
+ export { getGlobalFeed } from './getGlobalFeed';
@@ -0,0 +1,85 @@
1
+ import { pullFromCache } from '~/cache/api';
2
+ import { onCommentCreated, onCommentDeleted } from '~/commentRepository';
3
+ import { getPost } from '~/postRepository/internalApi';
4
+ import {
5
+ onPostCreated,
6
+ onPostUpdated,
7
+ onPostDeleted,
8
+ onPostFlagged,
9
+ onPostUnflagged,
10
+ onPostReactionAdded,
11
+ onPostReactionRemoved,
12
+ onPostApproved,
13
+ onPostDeclined,
14
+ } from '~/postRepository/events';
15
+ import { onLocalPostDeleted } from '~/postRepository/events/onLocalPostDeleted';
16
+ import { onLocalPostReactionAdded } from '~/postRepository/events/onLocalPostReactionAdded';
17
+ import { onLocalPostReactionRemoved } from '~/postRepository/events/onLocalPostReactionRemoved';
18
+ import { onPostUpdatedLocal } from '~/postRepository/events/onPostUpdatedLocal';
19
+ import { EnumPostActions } from '~/postRepository/observers/enums';
20
+ import { convertEventPayload } from '~/utils/event';
21
+ import { onCommentCreatedLocal } from '~/commentRepository/events/onCommentCreatedLocal';
22
+ import { onCommentDeleteLocal } from '~/commentRepository/events/onCommentDeletedLocal';
23
+ import { onCommentReactionAdded, onCommentReactionRemoved } from '~/commentRepository/events';
24
+ import { onLocalCommentReactionAdded } from '~/commentRepository/events/onLocalCommentReactionAdded';
25
+ import { onLocalCommentReactionRemoved } from '~/commentRepository/events/onLocalCommentReactionRemoved';
26
+
27
+ type CommentEventHandler = (callback: Amity.Listener<Amity.InternalComment>) => Amity.Unsubscriber;
28
+
29
+ const commentEventHanlder = (
30
+ callback: Amity.Listener<Amity.InternalComment>,
31
+ eventHandler: CommentEventHandler,
32
+ cacheKey: Amity.CacheKey,
33
+ ) => {
34
+ return eventHandler(async (comment: Amity.InternalComment) => {
35
+ const currentCollection =
36
+ pullFromCache<Amity.CustomRankingGlobalFeedLiveCollectionCache>(cacheKey)?.data;
37
+
38
+ if (!currentCollection || !currentCollection.data.includes(comment.referenceId)) return;
39
+
40
+ await getPost(comment.referenceId);
41
+ callback(comment);
42
+ });
43
+ };
44
+
45
+ const generateCommentSubscriptions = (cacheKey: Amity.CacheKey) => {
46
+ const eventHandlers = [
47
+ onCommentCreated,
48
+ onCommentDeleted,
49
+ onCommentReactionAdded,
50
+ onCommentReactionRemoved,
51
+ onCommentCreatedLocal,
52
+ onCommentDeleteLocal,
53
+ onLocalCommentReactionAdded,
54
+ onLocalCommentReactionRemoved,
55
+ ];
56
+
57
+ return eventHandlers.map(handler => ({
58
+ fn: convertEventPayload(
59
+ (callback: Amity.Listener<Amity.InternalComment>) =>
60
+ commentEventHanlder(callback, handler, cacheKey),
61
+ 'referenceId',
62
+ 'post',
63
+ ),
64
+ action: EnumPostActions.OnPostUpdated,
65
+ }));
66
+ };
67
+
68
+ export const getGlobalFeedSubscriptions = (cacheKey: Amity.CacheKey) => {
69
+ return [
70
+ { fn: onPostCreated, action: EnumPostActions.OnPostCreated },
71
+ { fn: onPostUpdated, action: EnumPostActions.OnPostUpdated },
72
+ { fn: onPostUpdatedLocal, action: EnumPostActions.OnPostUpdated },
73
+ { fn: onPostDeleted, action: EnumPostActions.OnPostDeleted },
74
+ { fn: onPostFlagged, action: EnumPostActions.OnPostFlagged },
75
+ { fn: onPostUnflagged, action: EnumPostActions.OnPostUnflagged },
76
+ { fn: onPostApproved, action: EnumPostActions.OnPostApproved },
77
+ { fn: onPostDeclined, action: EnumPostActions.OnPostDeclined },
78
+ { fn: onPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
79
+ { fn: onPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
80
+ { fn: onLocalPostReactionAdded, action: EnumPostActions.OnPostReactionAdded },
81
+ { fn: onLocalPostReactionRemoved, action: EnumPostActions.OnPostReactionRemoved },
82
+ { fn: onLocalPostDeleted, action: EnumPostActions.OnPostDeleted },
83
+ ...generateCommentSubscriptions(cacheKey),
84
+ ];
85
+ };
@@ -5,3 +5,4 @@ export * from './fileUrlWithSize';
5
5
  export * from './uploadVideo';
6
6
  export * from './uploadImage';
7
7
  export * from './updateAltText';
8
+ export * from './uploadClip';