@amityco/ts-sdk-react-native 6.26.1-c3b0164.0 → 6.26.2

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 (25) hide show
  1. package/.env +26 -26
  2. package/dist/@types/core/payload.d.ts +1 -0
  3. package/dist/@types/core/payload.d.ts.map +1 -1
  4. package/dist/commentRepository/observers/getComments/CommentLiveCollectionController.d.ts +14 -0
  5. package/dist/commentRepository/observers/getComments/CommentLiveCollectionController.d.ts.map +1 -0
  6. package/dist/commentRepository/observers/getComments/CommentPaginationController.d.ts +5 -0
  7. package/dist/commentRepository/observers/getComments/CommentPaginationController.d.ts.map +1 -0
  8. package/dist/commentRepository/observers/getComments/CommentQueryStreamController.d.ts +15 -0
  9. package/dist/commentRepository/observers/getComments/CommentQueryStreamController.d.ts.map +1 -0
  10. package/dist/commentRepository/observers/getComments/enums.d.ts +10 -0
  11. package/dist/commentRepository/observers/getComments/enums.d.ts.map +1 -0
  12. package/dist/commentRepository/observers/getComments.d.ts.map +1 -1
  13. package/dist/commentRepository/utils/payload.d.ts +2 -0
  14. package/dist/commentRepository/utils/payload.d.ts.map +1 -0
  15. package/dist/index.cjs.js +160 -111
  16. package/dist/index.esm.js +160 -111
  17. package/dist/index.umd.js +3 -3
  18. package/package.json +1 -1
  19. package/src/@types/core/payload.ts +5 -0
  20. package/src/commentRepository/observers/getComments/CommentLiveCollectionController.ts +132 -0
  21. package/src/commentRepository/observers/getComments/CommentPaginationController.ts +30 -0
  22. package/src/commentRepository/observers/getComments/CommentQueryStreamController.ts +90 -0
  23. package/src/commentRepository/observers/getComments/enums.ts +9 -0
  24. package/src/commentRepository/observers/getComments.ts +5 -141
  25. package/src/commentRepository/utils/payload.ts +19 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amityco/ts-sdk-react-native",
3
- "version": "6.26.1-c3b0164.0",
3
+ "version": "6.26.2",
4
4
  "license": "CC-BY-ND-4.0",
5
5
  "author": "amity.co <developers@amity.co> (https://amity.co)",
6
6
  "description": "Amity Social Cloud Typescript SDK",
@@ -361,6 +361,11 @@ declare global {
361
361
  communityUsers: Amity.Membership<'community'>[];
362
362
  };
363
363
 
364
+ type ProcessedCommentPayload<T extends Amity.CommentContentType = any> = Omit<
365
+ CommentPayload<T>,
366
+ 'users' | 'files' | 'communityUsers'
367
+ >;
368
+
364
369
  type PollPayload = {
365
370
  users: Amity.InternalUser[];
366
371
  polls: Amity.Poll[];
@@ -0,0 +1,132 @@
1
+ import hash from 'object-hash';
2
+ import { pullFromCache, pushToCache } from '~/cache/api';
3
+ import { CommentPaginationController } from './CommentPaginationController';
4
+ import { CommentQueryStreamController } from './CommentQueryStreamController';
5
+ import { LiveCollectionController } from '~/core/liveCollection/LiveCollectionController';
6
+ import {
7
+ onCommentCreated,
8
+ onCommentUpdated,
9
+ onCommentDeleted,
10
+ onCommentFlagged,
11
+ onCommentUnflagged,
12
+ onCommentReactionAdded,
13
+ onCommentReactionRemoved,
14
+ } from '~/commentRepository/events';
15
+ import { filterByPropEquality, sortByFirstCreated, sortByLastCreated } from '~/core/query';
16
+ import { isNonNullable } from '~/utils';
17
+ import { EnumCommentActions } from './enums';
18
+ import { LinkedObject } from '~/utils/linkedObject';
19
+ import { prepareCommentPayload } from '~/commentRepository/utils/payload';
20
+
21
+ export class CommentLiveCollectionController extends LiveCollectionController<
22
+ 'comment',
23
+ Amity.CommentLiveCollection,
24
+ Amity.Comment,
25
+ CommentPaginationController
26
+ > {
27
+ private queryStreamController: CommentQueryStreamController;
28
+
29
+ private query: Amity.CommentLiveCollection;
30
+
31
+ constructor(
32
+ query: Amity.CommentLiveCollection,
33
+ callback: Amity.LiveCollectionCallback<Amity.Comment>,
34
+ ) {
35
+ const queryStreamId = hash(query);
36
+ const cacheKey = ['comments', 'collection', queryStreamId];
37
+ const paginationController = new CommentPaginationController(query);
38
+
39
+ super(paginationController, queryStreamId, cacheKey, callback);
40
+
41
+ this.query = query;
42
+ this.queryStreamController = new CommentQueryStreamController(
43
+ this.query,
44
+ this.cacheKey,
45
+ this.notifyChange.bind(this),
46
+ prepareCommentPayload,
47
+ );
48
+
49
+ this.callback = callback.bind(this);
50
+ this.loadPage({ initial: true });
51
+ }
52
+
53
+ protected setup() {
54
+ const collection = pullFromCache<Amity.CommentLiveCollectionCache>(this.cacheKey)?.data;
55
+ if (!collection) {
56
+ pushToCache(this.cacheKey, {
57
+ data: [],
58
+ params: {},
59
+ });
60
+ }
61
+ }
62
+
63
+ protected async persistModel(queryPayload: Amity.CommentPayload & Amity.Pagination) {
64
+ await this.queryStreamController.saveToMainDB(queryPayload);
65
+ }
66
+
67
+ protected persistQueryStream({
68
+ response,
69
+ direction,
70
+ refresh,
71
+ }: Amity.LiveCollectionPersistQueryStreamParams<'comment'>) {
72
+ this.queryStreamController.appendToQueryStream(response, direction, refresh);
73
+ }
74
+
75
+ startSubscription() {
76
+ return this.queryStreamController.subscribeRTE([
77
+ { fn: onCommentCreated, action: EnumCommentActions.OnCommentCreated },
78
+ { fn: onCommentUpdated, action: EnumCommentActions.OnCommentUpdated },
79
+ { fn: onCommentDeleted, action: EnumCommentActions.OnCommentDeleted },
80
+ { fn: onCommentFlagged, action: EnumCommentActions.OnCommentFlagged },
81
+ { fn: onCommentUnflagged, action: EnumCommentActions.OnCommentUnflagged },
82
+ { fn: onCommentReactionAdded, action: EnumCommentActions.OnCommentReactionAdded },
83
+ { fn: onCommentReactionRemoved, action: EnumCommentActions.OnCommentReactionRemoved },
84
+ ]);
85
+ }
86
+
87
+ notifyChange({ origin, loading, error }: Amity.LiveCollectionNotifyParams) {
88
+ const collection = pullFromCache<Amity.CommentLiveCollectionCache>(this.cacheKey)?.data;
89
+ if (!collection) return;
90
+
91
+ const data = this.applyFilter(
92
+ collection.data
93
+ .map(id => pullFromCache<Amity.InternalComment>(['comments', 'get', id])!)
94
+ .filter(isNonNullable)
95
+ .map(({ data }) => data) ?? [],
96
+ ).map(LinkedObject.comment);
97
+
98
+ if (!this.shouldNotify(data) && origin === 'event') return;
99
+
100
+ this.callback({
101
+ onNextPage: () => this.loadPage({ direction: Amity.LiveCollectionPageDirection.NEXT }),
102
+ data,
103
+ hasNextPage: !!this.paginationController.getNextToken(),
104
+ loading,
105
+ error,
106
+ });
107
+ }
108
+
109
+ applyFilter(data: Amity.InternalComment[]) {
110
+ let comments = data;
111
+
112
+ if (this.query.includeDeleted) {
113
+ comments = filterByPropEquality(comments, 'isDeleted', false);
114
+ }
115
+
116
+ if (this.query.parentId) {
117
+ comments = comments.filter(comment => comment.parentId === this.query.parentId);
118
+ }
119
+
120
+ switch (this.query.sortBy) {
121
+ case 'firstCreated':
122
+ comments = comments.sort(sortByFirstCreated);
123
+ break;
124
+ case 'lastCreated':
125
+ default:
126
+ comments = comments.sort(sortByLastCreated);
127
+ break;
128
+ }
129
+
130
+ return comments;
131
+ }
132
+ }
@@ -0,0 +1,30 @@
1
+ import { PaginationController } from '~/core/liveCollection/PaginationController';
2
+ import { COLLECTION_DEFAULT_PAGINATION_LIMIT } from '~/utils/constants';
3
+ import { inferIsDeleted } from '~/utils/inferIsDeleted';
4
+
5
+ export class CommentPaginationController extends PaginationController<
6
+ 'comment',
7
+ Amity.CommentLiveCollection
8
+ > {
9
+ async getRequest(queryParams: Amity.CommentLiveCollection, token: string | undefined) {
10
+ const { limit = COLLECTION_DEFAULT_PAGINATION_LIMIT, includeDeleted, ...params } = queryParams;
11
+
12
+ const baseOptions = {
13
+ type: params.sortBy || queryParams.limit ? 'pagination' : undefined,
14
+ };
15
+
16
+ const options = token ? { ...baseOptions, token } : { ...baseOptions, limit };
17
+
18
+ const { data: queryResponse } = await this.http.get<Amity.CommentPayload & Amity.Pagination>(
19
+ `/api/v3/comments`,
20
+ {
21
+ params: {
22
+ ...params,
23
+ isDeleted: inferIsDeleted(includeDeleted),
24
+ options,
25
+ },
26
+ },
27
+ );
28
+ return queryResponse;
29
+ }
30
+ }
@@ -0,0 +1,90 @@
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 { EnumCommentActions } from './enums';
7
+
8
+ export class CommentQueryStreamController extends QueryStreamController<
9
+ Amity.CommentPayload,
10
+ Amity.CommentLiveCollection
11
+ > {
12
+ private notifyChange: (params: Amity.LiveCollectionNotifyParams) => void;
13
+
14
+ private preparePayload: (response: Amity.CommentPayload) => Amity.ProcessedCommentPayload;
15
+
16
+ constructor(
17
+ query: Amity.CommentLiveCollection,
18
+ cacheKey: string[],
19
+ notifyChange: (params: Amity.LiveCollectionNotifyParams) => void,
20
+ preparePayload: (response: Amity.CommentPayload) => Amity.ProcessedCommentPayload,
21
+ ) {
22
+ super(query, cacheKey);
23
+ this.notifyChange = notifyChange;
24
+ this.preparePayload = preparePayload;
25
+ }
26
+
27
+ async saveToMainDB(response: Amity.CommentPayload) {
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.CommentPayload & Partial<Amity.Pagination>,
40
+ direction: Amity.LiveCollectionPageDirection,
41
+ refresh = false,
42
+ ) {
43
+ if (refresh) {
44
+ pushToCache(this.cacheKey, {
45
+ data: response.comments.map(getResolver('comment')),
46
+ });
47
+ } else {
48
+ const collection = pullFromCache<Amity.CommunityLiveCollectionCache>(this.cacheKey)?.data;
49
+
50
+ const comments = collection?.data ?? [];
51
+
52
+ pushToCache(this.cacheKey, {
53
+ ...collection,
54
+ data: [...new Set([...comments, ...response.comments.map(getResolver('comment'))])],
55
+ });
56
+ }
57
+ }
58
+
59
+ reactor(action: EnumCommentActions) {
60
+ return (comment: Amity.InternalComment) => {
61
+ const collection = pullFromCache<Amity.CommentLiveCollectionCache>(this.cacheKey)?.data;
62
+
63
+ if (
64
+ this.query.referenceId !== comment.referenceId ||
65
+ this.query.referenceType !== comment.referenceType ||
66
+ !collection
67
+ ) {
68
+ return;
69
+ }
70
+
71
+ if (action === EnumCommentActions.OnCommentCreated) {
72
+ collection.data = [...new Set([comment.commentId, ...collection.data])];
73
+ } else if (action === EnumCommentActions.OnCommentDeleted) {
74
+ collection.data = collection.data.filter(p => p !== comment.commentId);
75
+ }
76
+
77
+ pushToCache(this.cacheKey, collection);
78
+ this.notifyChange({ origin: Amity.LiveDataOrigin.EVENT, loading: false });
79
+ };
80
+ }
81
+
82
+ subscribeRTE(
83
+ createSubscriber: {
84
+ fn: (reactor: (comment: Amity.InternalComment) => void) => Amity.Unsubscriber;
85
+ action: EnumCommentActions;
86
+ }[],
87
+ ) {
88
+ return createSubscriber.map(subscriber => subscriber.fn(this.reactor(subscriber.action)));
89
+ }
90
+ }
@@ -0,0 +1,9 @@
1
+ export enum EnumCommentActions {
2
+ OnCommentCreated = 'onCommentCreated',
3
+ OnCommentUpdated = 'onCommentUpdated',
4
+ OnCommentDeleted = 'onCommentDeleted',
5
+ OnCommentFlagged = 'onCommentFlagged',
6
+ OnCommentUnflagged = 'onCommentUnflagged',
7
+ OnCommentReactionAdded = 'onCommentReactionAdded',
8
+ OnCommentReactionRemoved = 'onCommentReactionRemoved',
9
+ }
@@ -1,34 +1,7 @@
1
- /* eslint-disable no-use-before-define */
2
- import { getResolver } from '~/core/model';
3
1
  import { getActiveClient } from '~/client/api';
4
- import { dropFromCache, pullFromCache, pushToCache } from '~/cache/api';
2
+ import { dropFromCache } from '~/cache/api';
5
3
 
6
- import {
7
- createQuery,
8
- filterByPropEquality,
9
- queryOptions,
10
- runQuery,
11
- sortByFirstCreated,
12
- sortByLastCreated,
13
- } from '~/core/query';
14
-
15
- import {
16
- COLLECTION_DEFAULT_CACHING_POLICY,
17
- COLLECTION_DEFAULT_PAGINATION_LIMIT,
18
- } from '~/utils/constants';
19
-
20
- import { CACHE_SHORTEN_LIFESPAN } from '~/cache/utils';
21
- import { LinkedObject } from '~/utils/linkedObject';
22
- import {
23
- onCommentCreated,
24
- onCommentDeleted,
25
- onCommentFlagged,
26
- onCommentReactionAdded,
27
- onCommentReactionRemoved,
28
- onCommentUnflagged,
29
- onCommentUpdated,
30
- } from '../events';
31
- import { queryComments } from '../internalApi/queryComments';
4
+ import { CommentLiveCollectionController } from './getComments/CommentLiveCollectionController';
32
5
 
33
6
  /* begin_public_function
34
7
  id: comment.query
@@ -67,120 +40,11 @@ export const getComments = (
67
40
  const timestamp = Date.now();
68
41
  log(`getComments(tmpid: ${timestamp}) > listen`);
69
42
 
70
- const { limit: queryLimit, ...queryParams } = params;
71
-
72
- const limit = queryLimit ?? COLLECTION_DEFAULT_PAGINATION_LIMIT;
73
- const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config ?? {};
74
-
75
- const disposers: Amity.Unsubscriber[] = [];
76
-
77
- const sortBy = params.sortBy ? params.sortBy : 'lastCreated';
78
- const cacheKey = [
79
- 'comment',
80
- 'collection',
81
- {
82
- referenceId: params.referenceType,
83
- referenceType: params.referenceId,
84
- parentId: params?.parentId || '',
85
- sortBy,
86
- },
87
- ];
88
-
89
- const responder = (data: Amity.CommentLiveCollectionCache) => {
90
- let comments: Amity.InternalComment[] =
91
- data.data
92
- .map(commentId => pullFromCache<Amity.InternalComment>(['comment', 'get', commentId])!)
93
- .filter(({ data }) => data.parentId === params?.parentId)
94
- .filter(Boolean)
95
- .map(({ data }) => LinkedObject.comment(data)) ?? [];
96
-
97
- if (!params.includeDeleted) {
98
- comments = filterByPropEquality(comments, 'isDeleted', false);
99
- }
100
-
101
- comments = comments.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
102
-
103
- callback({
104
- onNextPage: onFetch,
105
- data: comments,
106
- hasNextPage: !!data.params?.page,
107
- loading: data.loading,
108
- error: data.error,
109
- });
110
- };
111
-
112
- const realtimeRouter = (action: Amity.CommentActionType) => (comment: Amity.InternalComment) => {
113
- const collection = pullFromCache<Amity.CommentLiveCollectionCache>(cacheKey)?.data;
114
-
115
- if (
116
- params.referenceId !== comment.referenceId ||
117
- params.referenceType !== comment.referenceType ||
118
- !collection
119
- ) {
120
- return;
121
- }
122
-
123
- if (action === 'onCreate') {
124
- collection.data = [...new Set([comment.commentId, ...collection.data])];
125
- } else if (action === 'onDelete') {
126
- collection.data = collection.data.filter(p => p !== comment.commentId);
127
- }
128
-
129
- pushToCache(cacheKey, collection);
130
-
131
- responder(collection);
132
- };
133
-
134
- const onFetch = (initial = false) => {
135
- const collection = pullFromCache<Amity.CommentLiveCollectionCache>(cacheKey)?.data;
136
-
137
- const comments = collection?.data ?? [];
138
-
139
- if (!initial && comments.length > 0 && !collection?.params?.page) return;
140
-
141
- const query = createQuery(queryComments, {
142
- ...queryParams,
143
- limit: queryLimit,
144
- page: !initial ? collection?.params.page : undefined,
145
- });
146
-
147
- runQuery(
148
- query,
149
- ({ data: result, error, loading, paging }) => {
150
- const page = paging?.next;
151
-
152
- const data = {
153
- loading,
154
- error,
155
- params: { page },
156
- data: comments,
157
- };
158
-
159
- if (result) {
160
- data.data = initial
161
- ? result.map(getResolver('comment')) // Replace a collection list with new data from BE
162
- : [...new Set([...comments, ...result.map(getResolver('comment'))])];
163
- }
164
-
165
- pushToCache(cacheKey, data);
166
-
167
- responder(data);
168
- },
169
- queryOptions(policy, CACHE_SHORTEN_LIFESPAN),
170
- );
171
- };
43
+ const commentsLiveCollection = new CommentLiveCollectionController(params, callback);
44
+ const disposers = commentsLiveCollection.startSubscription();
172
45
 
173
- disposers.push(
174
- onCommentCreated(realtimeRouter('onCreate')),
175
- onCommentUpdated(realtimeRouter('onUpdate')),
176
- onCommentDeleted(realtimeRouter('onDelete')),
177
- onCommentFlagged(realtimeRouter('onFlagged')),
178
- onCommentUnflagged(realtimeRouter('onUnflagged')),
179
- onCommentReactionAdded(realtimeRouter('onReactionAdded')),
180
- onCommentReactionRemoved(realtimeRouter('onReactionRemoved')),
181
- );
46
+ const cacheKey = commentsLiveCollection.getCacheKey();
182
47
 
183
- onFetch(true);
184
48
  disposers.push(() => dropFromCache(cacheKey));
185
49
 
186
50
  return () => {
@@ -0,0 +1,19 @@
1
+ export function prepareCommentPayload(
2
+ commentPayload: Amity.CommentPayload,
3
+ ): Amity.ProcessedCommentPayload {
4
+ const { comments } = commentPayload;
5
+
6
+ return {
7
+ ...commentPayload,
8
+ comments: comments.map(comment => {
9
+ if (comment.hasOwnProperty('myReactions')) return comment;
10
+
11
+ // Sometimes `myReactions` field will not come with BE response because that field is empty
12
+ // We need to put it with an empty array manually to make it show up in client side
13
+ return {
14
+ myReactions: [],
15
+ ...comment,
16
+ };
17
+ }),
18
+ };
19
+ }