@amityco/ts-sdk 0.0.1-beta.30 → 0.0.1-beta.32
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/@types/core/cache.d.ts +3 -0
- package/dist/@types/core/cache.d.ts.map +1 -1
- package/dist/@types/core/errors.d.ts +2 -1
- package/dist/@types/core/errors.d.ts.map +1 -1
- package/dist/@types/core/events.d.ts +2 -0
- package/dist/@types/core/events.d.ts.map +1 -1
- package/dist/@types/core/live.d.ts +8 -4
- package/dist/@types/core/live.d.ts.map +1 -1
- package/dist/@types/core/query.d.ts +1 -1
- package/dist/@types/core/query.d.ts.map +1 -1
- package/dist/@types/domains/channel.d.ts +1 -0
- package/dist/@types/domains/channel.d.ts.map +1 -1
- package/dist/@types/domains/message.d.ts +13 -6
- package/dist/@types/domains/message.d.ts.map +1 -1
- package/dist/@types/domains/post.d.ts +10 -3
- package/dist/@types/domains/post.d.ts.map +1 -1
- package/dist/@types/domains/user.d.ts +1 -0
- package/dist/@types/domains/user.d.ts.map +1 -1
- package/dist/@types/index.d.ts +2 -2
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/cache/api/backupCache.d.ts.map +1 -1
- package/dist/cache/api/isInTombstone.d.ts +18 -0
- package/dist/cache/api/isInTombstone.d.ts.map +1 -0
- package/dist/cache/api/pushToTombstone.d.ts +17 -0
- package/dist/cache/api/pushToTombstone.d.ts.map +1 -0
- package/dist/cache/api/tests/pushToCache.test.d.ts +2 -0
- package/dist/cache/api/tests/pushToCache.test.d.ts.map +1 -0
- package/dist/cache/utils/index.d.ts +17 -0
- package/dist/cache/utils/index.d.ts.map +1 -1
- package/dist/channel/api/addChannelMembers.d.ts.map +1 -1
- package/dist/channel/api/getChannel.d.ts.map +1 -1
- package/dist/channel/api/queryChannelMembers.d.ts +1 -1
- package/dist/channel/api/queryChannelMembers.d.ts.map +1 -1
- package/dist/channel/api/queryChannels.d.ts +1 -1
- package/dist/channel/api/queryChannels.d.ts.map +1 -1
- package/dist/channel/api/tests/addChannelMembers.test.d.ts +2 -0
- package/dist/channel/api/tests/addChannelMembers.test.d.ts.map +1 -0
- package/dist/channel/api/tests/getChannel.test.d.ts +2 -0
- package/dist/channel/api/tests/getChannel.test.d.ts.map +1 -0
- package/dist/channel/api/tests/queryChannelMembers.test.d.ts +2 -0
- package/dist/channel/api/tests/queryChannelMembers.test.d.ts.map +1 -0
- package/dist/channel/api/tests/queryChannels.test.d.ts +2 -0
- package/dist/channel/api/tests/queryChannels.test.d.ts.map +1 -0
- package/dist/channel/events/index.d.ts +2 -0
- package/dist/channel/events/index.d.ts.map +1 -1
- package/dist/channel/events/onChannelMemberAdded.d.ts.map +1 -1
- package/dist/channel/events/onChannelMemberBanned.d.ts +17 -0
- package/dist/channel/events/onChannelMemberBanned.d.ts.map +1 -0
- package/dist/channel/events/onChannelMemberUnbanned.d.ts +17 -0
- package/dist/channel/events/onChannelMemberUnbanned.d.ts.map +1 -0
- package/dist/channel/events/tests/onChannelMemberBanned.test.d.ts +2 -0
- package/dist/channel/events/tests/onChannelMemberBanned.test.d.ts.map +1 -0
- package/dist/channel/events/tests/onChannelMemberUnbanned.test.d.ts +2 -0
- package/dist/channel/events/tests/onChannelMemberUnbanned.test.d.ts.map +1 -0
- package/dist/channel/observers/liveChannelMembers.d.ts.map +1 -1
- package/dist/channel/observers/liveChannels.d.ts.map +1 -1
- package/dist/channel/{tests/utils → utils/tests}/prepareChannelPayload.test.d.ts +0 -0
- package/dist/channel/utils/tests/prepareChannelPayload.test.d.ts.map +1 -0
- package/dist/core/events.d.ts +3 -3
- package/dist/core/events.d.ts.map +1 -1
- package/dist/core/query/filtering.d.ts +11 -0
- package/dist/core/query/filtering.d.ts.map +1 -1
- package/dist/core/query/query.d.ts.map +1 -1
- package/dist/core/transports/http.d.ts +5 -0
- package/dist/core/transports/http.d.ts.map +1 -1
- package/dist/core/transports/test/http.test.d.ts +2 -0
- package/dist/core/transports/test/http.test.d.ts.map +1 -0
- package/dist/index.cjs.js +980 -534
- package/dist/index.esm.js +962 -526
- package/dist/index.umd.js +4 -4
- package/dist/message/api/createMessage.d.ts +4 -1
- package/dist/message/api/createMessage.d.ts.map +1 -1
- package/dist/message/api/deleteMessage.d.ts.map +1 -1
- package/dist/message/api/getMessage.d.ts +1 -1
- package/dist/message/api/getMessage.d.ts.map +1 -1
- package/dist/message/api/getMessages.d.ts.map +1 -1
- package/dist/message/api/queryMessages.d.ts.map +1 -1
- package/dist/message/api/tests/createMessage.test.d.ts +2 -0
- package/dist/message/api/tests/createMessage.test.d.ts.map +1 -0
- package/dist/message/api/tests/deleteMessage.test.d.ts +2 -0
- package/dist/message/api/tests/deleteMessage.test.d.ts.map +1 -0
- package/dist/message/api/tests/getMessage.test.d.ts +2 -0
- package/dist/message/api/tests/getMessage.test.d.ts.map +1 -0
- package/dist/message/api/tests/getMessages.test.d.ts +2 -0
- package/dist/message/api/tests/getMessages.test.d.ts.map +1 -0
- package/dist/message/api/tests/queryMessages.test.d.ts +2 -0
- package/dist/message/api/tests/queryMessages.test.d.ts.map +1 -0
- package/dist/message/api/tests/updateMessage.test.d.ts +2 -0
- package/dist/message/api/tests/updateMessage.test.d.ts.map +1 -0
- package/dist/message/api/updateMessage.d.ts.map +1 -1
- package/dist/message/events/index.d.ts +1 -0
- package/dist/message/events/index.d.ts.map +1 -1
- package/dist/message/events/onMessageFetched.d.ts +17 -0
- package/dist/message/events/onMessageFetched.d.ts.map +1 -0
- package/dist/message/observers/index.d.ts +2 -1
- package/dist/message/observers/index.d.ts.map +1 -1
- package/dist/message/observers/liveMessage.d.ts +18 -0
- package/dist/message/observers/liveMessage.d.ts.map +1 -0
- package/dist/message/observers/liveMessages.d.ts.map +1 -1
- package/dist/message/observers/observeMessage.d.ts.map +1 -1
- package/dist/message/tests/observers/liveMessage.test.d.ts +2 -0
- package/dist/message/tests/observers/liveMessage.test.d.ts.map +1 -0
- package/dist/message/{observers/tests → tests/observers}/liveMessages.test.d.ts +0 -0
- package/dist/message/tests/observers/liveMessages.test.d.ts.map +1 -0
- package/dist/post/api/deletePost.d.ts.map +1 -1
- package/dist/post/api/getPost.d.ts.map +1 -1
- package/dist/post/api/updatePost.d.ts +6 -1
- package/dist/post/api/updatePost.d.ts.map +1 -1
- package/dist/reaction/api/addReaction.d.ts.map +1 -1
- package/dist/reaction/api/removeReaction.d.ts.map +1 -1
- package/dist/reaction/api/tests/addReaction.test.d.ts +2 -0
- package/dist/reaction/api/tests/addReaction.test.d.ts.map +1 -0
- package/dist/reaction/api/tests/removeReaction.test.d.ts +2 -0
- package/dist/reaction/api/tests/removeReaction.test.d.ts.map +1 -0
- package/dist/user/api/getUser.d.ts +1 -1
- package/dist/user/api/getUser.d.ts.map +1 -1
- package/dist/user/api/getUsers.d.ts.map +1 -1
- package/dist/user/api/queryUsers.d.ts.map +1 -1
- package/dist/user/api/tests/queryUsers.test.d.ts +2 -0
- package/dist/user/api/tests/queryUsers.test.d.ts.map +1 -0
- package/dist/user/api/updateUser.d.ts.map +1 -1
- package/dist/user/events/index.d.ts +1 -0
- package/dist/user/events/index.d.ts.map +1 -1
- package/dist/user/events/onUserFetched.d.ts +17 -0
- package/dist/user/events/onUserFetched.d.ts.map +1 -0
- package/dist/user/observers/index.d.ts +1 -0
- package/dist/user/observers/index.d.ts.map +1 -1
- package/dist/user/observers/liveUser.d.ts +18 -0
- package/dist/user/observers/liveUser.d.ts.map +1 -0
- package/dist/user/observers/observeUser.d.ts.map +1 -1
- package/dist/user/tests/api/getUser.test.d.ts +2 -0
- package/dist/user/tests/api/getUser.test.d.ts.map +1 -0
- package/dist/user/tests/observers/liveUser.test.d.ts +2 -0
- package/dist/user/tests/observers/liveUser.test.d.ts.map +1 -0
- package/dist/utils/constants.d.ts +3 -0
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/tests/dummy/channel.d.ts +15 -0
- package/dist/utils/tests/dummy/channel.d.ts.map +1 -1
- package/dist/utils/tests/dummy/message.d.ts +12 -1
- package/dist/utils/tests/dummy/message.d.ts.map +1 -1
- package/dist/utils/tests/dummy/post.d.ts +12 -1
- package/dist/utils/tests/dummy/post.d.ts.map +1 -1
- package/dist/utils/tests/dummy/user.d.ts +10 -0
- package/dist/utils/tests/dummy/user.d.ts.map +1 -1
- package/package.json +2 -1
- package/src/@types/core/cache.ts +4 -0
- package/src/@types/core/errors.ts +1 -0
- package/src/@types/core/events.ts +2 -0
- package/src/@types/core/live.ts +10 -4
- package/src/@types/core/query.ts +1 -1
- package/src/@types/domains/channel.ts +6 -0
- package/src/@types/domains/message.ts +13 -10
- package/src/@types/domains/post.ts +10 -3
- package/src/@types/domains/user.ts +8 -0
- package/src/@types/index.ts +2 -2
- package/src/cache/api/backupCache.ts +0 -1
- package/src/cache/api/index.ts +2 -1
- package/src/cache/api/isInTombstone.ts +41 -0
- package/src/cache/api/pushToTombstone.ts +33 -0
- package/src/cache/api/tests/pushToCache.test.ts +57 -0
- package/src/cache/utils/index.ts +22 -0
- package/src/channel/api/addChannelMembers.ts +9 -1
- package/src/channel/api/getChannel.ts +20 -5
- package/src/channel/api/queryChannelMembers.ts +53 -5
- package/src/channel/api/queryChannels.ts +31 -4
- package/src/channel/api/tests/addChannelMembers.test.ts +95 -0
- package/src/channel/api/tests/getChannel.test.ts +108 -0
- package/src/channel/api/tests/queryChannelMembers.test.ts +115 -0
- package/src/channel/api/tests/queryChannels.test.ts +121 -0
- package/src/channel/events/index.ts +5 -0
- package/src/channel/events/onChannelMemberAdded.ts +1 -1
- package/src/channel/events/onChannelMemberBanned.ts +36 -0
- package/src/channel/events/onChannelMemberUnbanned.ts +36 -0
- package/src/channel/events/tests/onChannelMemberBanned.test.ts +58 -0
- package/src/channel/events/tests/onChannelMemberUnbanned.test.ts +58 -0
- package/src/channel/observers/liveChannelMembers.ts +28 -4
- package/src/channel/observers/liveChannels.ts +7 -1
- package/src/channel/observers/tests/liveChannelMembers.test.ts +53 -11
- package/src/channel/observers/tests/liveChannels.test.ts +50 -21
- package/src/channel/{tests/utils → utils/tests}/prepareChannelPayload.test.ts +1 -1
- package/src/core/events.ts +2 -1
- package/src/core/query/filtering.ts +49 -0
- package/src/core/query/query.ts +9 -6
- package/src/core/tests/query/query.test.ts +12 -2
- package/src/core/transports/http.ts +3 -17
- package/src/core/transports/test/http.test.ts +83 -0
- package/src/message/api/createMessage.ts +15 -9
- package/src/message/api/deleteMessage.ts +4 -4
- package/src/message/api/getMessage.ts +32 -4
- package/src/message/api/getMessages.ts +6 -1
- package/src/message/api/queryMessages.ts +3 -0
- package/src/message/api/tests/createMessage.test.ts +99 -0
- package/src/message/api/tests/deleteMessage.test.ts +110 -0
- package/src/message/api/tests/getMessage.test.ts +121 -0
- package/src/message/api/tests/getMessages.test.ts +108 -0
- package/src/message/api/tests/queryMessages.test.ts +115 -0
- package/src/message/api/tests/updateMessage.test.ts +100 -0
- package/src/message/api/updateMessage.ts +2 -0
- package/src/message/events/index.ts +1 -0
- package/src/message/events/onMessageFetched.ts +30 -0
- package/src/message/observers/index.ts +2 -1
- package/src/message/observers/liveMessage.ts +100 -0
- package/src/message/observers/liveMessages.ts +3 -1
- package/src/message/observers/observeMessage.ts +4 -0
- package/src/message/tests/observers/liveMessage.test.ts +248 -0
- package/src/message/{observers/tests → tests/observers}/liveMessages.test.ts +29 -3
- package/src/post/api/deletePost.ts +4 -3
- package/src/post/api/getPost.ts +8 -4
- package/src/post/api/updatePost.ts +6 -1
- package/src/post/tests/api/queryPosts.test.ts +117 -18
- package/src/reaction/api/addReaction.ts +1 -4
- package/src/reaction/api/removeReaction.ts +1 -4
- package/src/reaction/api/tests/addReaction.test.ts +37 -0
- package/src/reaction/api/tests/removeReaction.test.ts +43 -0
- package/src/user/api/getUser.ts +32 -5
- package/src/user/api/getUsers.ts +3 -0
- package/src/user/api/queryUsers.ts +27 -5
- package/src/user/api/tests/queryUsers.test.ts +124 -0
- package/src/user/api/updateUser.ts +3 -0
- package/src/user/events/index.ts +1 -0
- package/src/user/events/onUserFetched.ts +19 -0
- package/src/user/observers/index.ts +1 -0
- package/src/user/observers/liveUser.ts +89 -0
- package/src/user/observers/observeUser.ts +2 -0
- package/src/user/tests/api/getUser.test.ts +112 -0
- package/src/user/tests/observers/liveUser.test.ts +224 -0
- package/src/utils/constants.ts +5 -0
- package/src/utils/tests/dummy/channel.ts +43 -0
- package/src/utils/tests/dummy/message.ts +16 -2
- package/src/utils/tests/dummy/post.ts +26 -3
- package/src/utils/tests/dummy/user.ts +11 -0
- package/dist/channel/tests/utils/prepareChannelPayload.test.d.ts.map +0 -1
- package/dist/message/observers/tests/liveMessages.test.d.ts.map +0 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { encode, decode } from 'js-base64';
|
|
2
|
-
import mitt from 'mitt';
|
|
3
2
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
3
|
+
import mitt from 'mitt';
|
|
4
4
|
import debug from 'debug';
|
|
5
5
|
import axios from 'axios';
|
|
6
|
+
import qs from 'qs';
|
|
6
7
|
import HttpAgent, { HttpsAgent } from 'agentkeepalive';
|
|
7
8
|
import io from 'socket.io-client';
|
|
8
9
|
import nativeIdGenerator from 'react-native-uuid';
|
|
@@ -61,6 +62,24 @@ const VideoSize = Object.freeze({
|
|
|
61
62
|
ORIGINAL: 'original',
|
|
62
63
|
});
|
|
63
64
|
|
|
65
|
+
const MessageContentType = Object.freeze({
|
|
66
|
+
TEXT: 'text',
|
|
67
|
+
IMAGE: 'image',
|
|
68
|
+
FILE: 'file',
|
|
69
|
+
VIDEO: 'video',
|
|
70
|
+
AUDIO: 'audio',
|
|
71
|
+
CUSTOM: 'custom',
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const PostContentType = Object.freeze({
|
|
75
|
+
TEXT: 'text',
|
|
76
|
+
IMAGE: 'image',
|
|
77
|
+
FILE: 'file',
|
|
78
|
+
VIDEO: 'video',
|
|
79
|
+
LIVESTREAM: 'liveStream',
|
|
80
|
+
POLL: 'poll',
|
|
81
|
+
});
|
|
82
|
+
|
|
64
83
|
var _a$1;
|
|
65
84
|
/* eslint-disable no-undef */
|
|
66
85
|
const theGlobal =
|
|
@@ -336,6 +355,78 @@ const PAYLOAD2MODEL = {
|
|
|
336
355
|
followCounts: 'followCount',
|
|
337
356
|
};
|
|
338
357
|
|
|
358
|
+
// cache constants
|
|
359
|
+
const CACHE_KEY_GET = 'get';
|
|
360
|
+
const CACHE_KEY_TOMBSTONE = 'dead';
|
|
361
|
+
const CACHE_LIFESPAN = 1 * 60 * 1000; // 1 minute
|
|
362
|
+
const CACHE_LIFESPAN_TOMBSTONE = 3 * 60 * 1000; // 3 minutes
|
|
363
|
+
/**
|
|
364
|
+
* Shallow-clones an object and sort its keys
|
|
365
|
+
*
|
|
366
|
+
* @param source a plain object to clone
|
|
367
|
+
* @returns a clone of source, with keys sorted with default javascript sorting
|
|
368
|
+
*
|
|
369
|
+
* @category Cache
|
|
370
|
+
* @hidden
|
|
371
|
+
*/
|
|
372
|
+
const normalize = (source) => Object.keys(source)
|
|
373
|
+
.sort()
|
|
374
|
+
.reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: source[key] })), {});
|
|
375
|
+
/**
|
|
376
|
+
* Encodes a given {@link Amity.CacheKey} to a plain string
|
|
377
|
+
*
|
|
378
|
+
* @param key the key to encode
|
|
379
|
+
* @returns an encoded string
|
|
380
|
+
*
|
|
381
|
+
* @category Cache
|
|
382
|
+
* @hidden
|
|
383
|
+
*/
|
|
384
|
+
const encodeKey = (key) => JSON.stringify(key, (_, val) => (typeof val === 'object' ? normalize(val) : val));
|
|
385
|
+
/**
|
|
386
|
+
* Decodes a string back into a {@link Amity.CacheKey}
|
|
387
|
+
|
|
388
|
+
*
|
|
389
|
+
* @param key the string key to decode
|
|
390
|
+
* @returns a plain Amity.CacheKey object.
|
|
391
|
+
*
|
|
392
|
+
* @category Cache
|
|
393
|
+
* @hidden
|
|
394
|
+
*/
|
|
395
|
+
const decodeKey = (key) => JSON.parse(key);
|
|
396
|
+
/**
|
|
397
|
+
* Performs a recursive partial deep equal check on two objects.
|
|
398
|
+
*
|
|
399
|
+
* @param predicate the reference object containing the partial information
|
|
400
|
+
* @param candidate the object to check against
|
|
401
|
+
* @returns true if the candidate contains all the values of the predicate
|
|
402
|
+
*
|
|
403
|
+
* @category Cache
|
|
404
|
+
*/
|
|
405
|
+
const partialMatch = (predicate, candidate) => {
|
|
406
|
+
if (predicate === candidate)
|
|
407
|
+
return true;
|
|
408
|
+
// if one or the other is nullish, there can't be equality
|
|
409
|
+
if (!predicate || !candidate)
|
|
410
|
+
return false;
|
|
411
|
+
// we only perform recursive check on objects
|
|
412
|
+
if (typeof predicate !== 'object') {
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
// recursively call for partial match based on the predicate
|
|
416
|
+
return Object.keys(predicate).every(key => partialMatch(predicate[key], candidate[key]));
|
|
417
|
+
};
|
|
418
|
+
/**
|
|
419
|
+
* checks if passed error code is included in
|
|
420
|
+
* Tombstone errors list
|
|
421
|
+
*
|
|
422
|
+
* @param errorCode as {@link Amity.ServerError}
|
|
423
|
+
* @returns success boolean if the given errorCode
|
|
424
|
+
* is included in Tombstone errors list
|
|
425
|
+
*
|
|
426
|
+
* @category Cache
|
|
427
|
+
*/
|
|
428
|
+
const checkIfShouldGoesToTombstone = (errorCode) => [400400 /* Amity.ServerError.ITEM_NOT_FOUND */, 400300 /* Amity.ServerError.FORBIDDEN */].includes(errorCode);
|
|
429
|
+
|
|
339
430
|
/* eslint-disable no-use-before-define */
|
|
340
431
|
/**
|
|
341
432
|
* Type guard to check and cast that a given async function is has the ".locally" property
|
|
@@ -394,7 +485,7 @@ const isLocal = (model) => {
|
|
|
394
485
|
*
|
|
395
486
|
* @hidden
|
|
396
487
|
*/
|
|
397
|
-
const isFresh = (model, lifeSpan =
|
|
488
|
+
const isFresh = (model, lifeSpan = CACHE_LIFESPAN) => {
|
|
398
489
|
var _a;
|
|
399
490
|
return Date.now() - ((_a = model === null || model === void 0 ? void 0 : model.cachedAt) !== null && _a !== void 0 ? _a : 0) <= lifeSpan;
|
|
400
491
|
};
|
|
@@ -428,12 +519,10 @@ const createQuery = (func, ...args) => ({ func, args });
|
|
|
428
519
|
*
|
|
429
520
|
* @category Query
|
|
430
521
|
*/
|
|
431
|
-
const queryOptions = (policy, lifeSpan =
|
|
522
|
+
const queryOptions = (policy, lifeSpan = CACHE_LIFESPAN) => {
|
|
432
523
|
if (policy === 'cache_only')
|
|
433
524
|
return { lifeSpan: Infinity };
|
|
434
|
-
|
|
435
|
-
return { lifeSpan: 0 };
|
|
436
|
-
return { lifeSpan };
|
|
525
|
+
return { lifeSpan: lifeSpan < CACHE_LIFESPAN ? CACHE_LIFESPAN : lifeSpan };
|
|
437
526
|
};
|
|
438
527
|
/**
|
|
439
528
|
* ```js
|
|
@@ -454,8 +543,9 @@ const queryOptions = (policy, lifeSpan = 2 * 60 * 1000) => {
|
|
|
454
543
|
*/
|
|
455
544
|
const runQuery = ({ func, args }, callback, options = queryOptions('cache_then_server')) => {
|
|
456
545
|
let local;
|
|
546
|
+
const { lifeSpan } = queryOptions('cache_then_server', options.lifeSpan);
|
|
457
547
|
// offline first
|
|
458
|
-
if (isOffline(func)
|
|
548
|
+
if (isOffline(func)) {
|
|
459
549
|
try {
|
|
460
550
|
local = isMutator(func) ? func.optimistically(...args) : func.locally(...args);
|
|
461
551
|
}
|
|
@@ -466,7 +556,7 @@ const runQuery = ({ func, args }, callback, options = queryOptions('cache_then_s
|
|
|
466
556
|
error,
|
|
467
557
|
}));
|
|
468
558
|
}
|
|
469
|
-
const shouldAbort = isCachable(local) && isFresh(local,
|
|
559
|
+
const shouldAbort = isCachable(local) && isFresh(local, lifeSpan);
|
|
470
560
|
callback === null || callback === void 0 ? void 0 : callback(createSnapshot(local, {
|
|
471
561
|
origin: 'local',
|
|
472
562
|
loading: !(isFetcher(func) && shouldAbort),
|
|
@@ -533,54 +623,6 @@ function createSnapshot(data, options) {
|
|
|
533
623
|
return Object.assign(Object.assign({}, options), { data });
|
|
534
624
|
}
|
|
535
625
|
|
|
536
|
-
// Note:
|
|
537
|
-
// this file should contain a suite of filtering utilities to help the
|
|
538
|
-
// local version of the query functions.
|
|
539
|
-
/**
|
|
540
|
-
* Filter a given collection with strict equality against a param
|
|
541
|
-
*
|
|
542
|
-
* @param collection the collection to filter
|
|
543
|
-
* @param key the key of the collection's items to challenge
|
|
544
|
-
* @param value the expected value
|
|
545
|
-
* @returns a filtered collection with items only matching the criteria
|
|
546
|
-
*
|
|
547
|
-
* @hidden
|
|
548
|
-
*/
|
|
549
|
-
const filterByPropEquality = (collection, key, value) => (value !== undefined ? collection.filter(item => item[key] === value) : collection);
|
|
550
|
-
const filterByPropInclusion = (collection, key, value) => (value !== undefined ? collection.filter(item => value.includes(item[key])) : collection);
|
|
551
|
-
|
|
552
|
-
// Note:
|
|
553
|
-
// this file should contain a suite of sorting utilities to help the
|
|
554
|
-
// local version of the query functions.
|
|
555
|
-
/**
|
|
556
|
-
* Alphabetic sorting of objects having a displayName
|
|
557
|
-
*/
|
|
558
|
-
const sortByDisplayName = ({ displayName: a }, { displayName: b }) => {
|
|
559
|
-
if (a === b)
|
|
560
|
-
return 0;
|
|
561
|
-
return a < b ? -1 : 1;
|
|
562
|
-
};
|
|
563
|
-
/**
|
|
564
|
-
* Sorting a collection by their apparition order (oldest first)
|
|
565
|
-
*/
|
|
566
|
-
const sortByChannelSegment = ({ channelSegment: a }, { channelSegment: b }) => a - b;
|
|
567
|
-
/**
|
|
568
|
-
* Sorting a collection by their apparition order (oldest first)
|
|
569
|
-
*/
|
|
570
|
-
const sortBySegmentNumber = ({ segmentNumber: a }, { segmentNumber: b }) => a - b;
|
|
571
|
-
/**
|
|
572
|
-
* Sorting a collection by its oldest items
|
|
573
|
-
*/
|
|
574
|
-
const sortByFirstCreated = ({ createdAt: a }, { createdAt: b }) => new Date(a).valueOf() - new Date(b).valueOf();
|
|
575
|
-
/**
|
|
576
|
-
* Sorting a collection by its newest items
|
|
577
|
-
*/
|
|
578
|
-
const sortByLastCreated = ({ createdAt: a }, { createdAt: b }) => new Date(b).valueOf() - new Date(a).valueOf();
|
|
579
|
-
/**
|
|
580
|
-
* Sorting a collection by the items with most recent activity
|
|
581
|
-
*/
|
|
582
|
-
const sortByLastActivity = ({ lastActivity: a }, { lastActivity: b }) => new Date(b).valueOf() - new Date(a).valueOf();
|
|
583
|
-
|
|
584
626
|
/* eslint-disable max-classes-per-file */
|
|
585
627
|
/**
|
|
586
628
|
* Generic ASC error
|
|
@@ -670,257 +712,62 @@ const setActiveClient = (client) => {
|
|
|
670
712
|
activeClient = client;
|
|
671
713
|
};
|
|
672
714
|
|
|
673
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
674
|
-
let tasks = [];
|
|
675
|
-
let timer;
|
|
676
715
|
/**
|
|
677
|
-
*
|
|
716
|
+
* ```js
|
|
717
|
+
* import { enableCache } from '@amityco/ts-sdk'
|
|
718
|
+
* enableCache()
|
|
719
|
+
* ```
|
|
678
720
|
*
|
|
679
|
-
*
|
|
721
|
+
* Adds a new {@link Amity.Cache} object to
|
|
722
|
+
* an {@link Amity.Client} instance
|
|
723
|
+
*
|
|
724
|
+
* @param prevState a previous state of cache instance (useful for SSR)
|
|
725
|
+
* @param persistIf a function to determine if an entry inserted in cache
|
|
726
|
+
* is destined to be also saved in the persistent storage when
|
|
727
|
+
* calling {@link backupCache}
|
|
728
|
+
*
|
|
729
|
+
* @category Cache API
|
|
680
730
|
*/
|
|
681
|
-
const
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}, 0);
|
|
731
|
+
const enableCache = (prevState = {}, persistIf) => {
|
|
732
|
+
const client = getActiveClient();
|
|
733
|
+
if (client.cache)
|
|
734
|
+
return;
|
|
735
|
+
client.log('cache/api/enableCache');
|
|
736
|
+
client.cache = { data: prevState, persistIf };
|
|
688
737
|
};
|
|
689
738
|
|
|
690
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
691
|
-
// need to sync up the list
|
|
692
|
-
const WS_EVENTS = [
|
|
693
|
-
'disconnected',
|
|
694
|
-
'error',
|
|
695
|
-
'connect_error',
|
|
696
|
-
'reconnect_error',
|
|
697
|
-
'reconnect_failed',
|
|
698
|
-
'v3.channel.didCreate',
|
|
699
|
-
'v3.channel.didUpdate',
|
|
700
|
-
'v3.channel.didDelete',
|
|
701
|
-
'v3.channel.didJoin',
|
|
702
|
-
'v3.channel.didLeave',
|
|
703
|
-
'v3.channel.didAddUsers',
|
|
704
|
-
'v3.channel.didRemoveUsers',
|
|
705
|
-
'v3.channel.didBan',
|
|
706
|
-
'v3.channel.didUnban',
|
|
707
|
-
'v3.message.didCreate',
|
|
708
|
-
'v3.message.didUpdate',
|
|
709
|
-
'v3.message.didDelete',
|
|
710
|
-
];
|
|
711
|
-
const MQTT_EVENTS = [
|
|
712
|
-
'connect',
|
|
713
|
-
'message',
|
|
714
|
-
'disconnect',
|
|
715
|
-
'error',
|
|
716
|
-
'close',
|
|
717
|
-
'end',
|
|
718
|
-
'reconnect',
|
|
719
|
-
];
|
|
720
|
-
/** @hidden */
|
|
721
|
-
const createEventEmitter = () => {
|
|
722
|
-
return mitt();
|
|
723
|
-
};
|
|
724
739
|
/**
|
|
725
|
-
*
|
|
726
|
-
*
|
|
740
|
+
* ```js
|
|
741
|
+
* import { disableCache } from '@amityco/ts-sdk'
|
|
742
|
+
* disableCache()
|
|
743
|
+
* ```
|
|
727
744
|
*
|
|
728
|
-
*
|
|
729
|
-
* @
|
|
745
|
+
* Wipes the existing {@link Amity.Cache} object attached to
|
|
746
|
+
* an {@link Amity.Client} instance
|
|
730
747
|
*
|
|
731
|
-
* @category
|
|
732
|
-
* @hidden
|
|
748
|
+
* @category Cache API
|
|
733
749
|
*/
|
|
734
|
-
const
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
mqttClient.on('message', (topic, payload) => {
|
|
745
|
-
const message = JSON.parse(payload.toString());
|
|
746
|
-
emitter.emit(message.eventType, message.data);
|
|
747
|
-
});
|
|
748
|
-
};
|
|
750
|
+
const disableCache = () => {
|
|
751
|
+
const client = getActiveClient();
|
|
752
|
+
if (!client.cache)
|
|
753
|
+
return;
|
|
754
|
+
client.log('cache/api/disableCache');
|
|
755
|
+
// we do this so that testing if cache is enabled
|
|
756
|
+
// is only `if (client.cache)
|
|
757
|
+
delete client.cache;
|
|
758
|
+
};
|
|
759
|
+
|
|
749
760
|
/**
|
|
750
|
-
*
|
|
761
|
+
* ```js
|
|
762
|
+
* import { restoreCache } from '@amityco/ts-sdk'
|
|
763
|
+
* const success = await restoreCache()
|
|
764
|
+
* ```
|
|
751
765
|
*
|
|
752
|
-
*
|
|
753
|
-
*
|
|
754
|
-
* @param event The websocket event name
|
|
755
|
-
* @param fn A wrapper for the callback.
|
|
756
|
-
* @returns A dispose function to unsubscribe to the event
|
|
766
|
+
* Reads a previously saved {@link Amity.Cache} from a persistent storage,
|
|
767
|
+
* and inserts it into the current {@link Amity.Cache} instance.
|
|
757
768
|
*
|
|
758
|
-
*
|
|
759
|
-
* @
|
|
760
|
-
*/
|
|
761
|
-
const createEventSubscriber = (client, namespace, event, fn) => {
|
|
762
|
-
const { log, emitter } = client;
|
|
763
|
-
const timestamp = Date.now();
|
|
764
|
-
log(`${namespace}(tmpid: ${timestamp}) > listen`);
|
|
765
|
-
const handler = (...payload) => {
|
|
766
|
-
log(`${namespace}(tmpid: ${timestamp}) > trigger`, payload);
|
|
767
|
-
fn(...payload);
|
|
768
|
-
};
|
|
769
|
-
emitter.on(event, handler);
|
|
770
|
-
return () => {
|
|
771
|
-
log(`${namespace}(tmpid: ${timestamp}) > dispose`);
|
|
772
|
-
emitter.off(event, handler);
|
|
773
|
-
};
|
|
774
|
-
};
|
|
775
|
-
/**
|
|
776
|
-
* Wrapper around dispatch event
|
|
777
|
-
*
|
|
778
|
-
* @hidden
|
|
779
|
-
*/
|
|
780
|
-
const fireEvent = (event, payload) => {
|
|
781
|
-
const { emitter } = getActiveClient();
|
|
782
|
-
scheduleTask(() => {
|
|
783
|
-
emitter.emit(event, payload);
|
|
784
|
-
});
|
|
785
|
-
};
|
|
786
|
-
|
|
787
|
-
let activeUser = null;
|
|
788
|
-
/**
|
|
789
|
-
* for internal use
|
|
790
|
-
*/
|
|
791
|
-
const getActiveUser = () => {
|
|
792
|
-
if (!activeUser) {
|
|
793
|
-
throw new ASCError('Connect client first', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
|
|
794
|
-
}
|
|
795
|
-
return activeUser;
|
|
796
|
-
};
|
|
797
|
-
const setActiveUser = (user) => {
|
|
798
|
-
activeUser = {
|
|
799
|
-
_id: user._id,
|
|
800
|
-
userId: user.userId,
|
|
801
|
-
path: user.path,
|
|
802
|
-
};
|
|
803
|
-
};
|
|
804
|
-
|
|
805
|
-
var SubscriptionLevels;
|
|
806
|
-
(function (SubscriptionLevels) {
|
|
807
|
-
SubscriptionLevels["COMMUNITY"] = "community";
|
|
808
|
-
SubscriptionLevels["POST"] = "post";
|
|
809
|
-
SubscriptionLevels["COMMENT"] = "comment";
|
|
810
|
-
SubscriptionLevels["POST_AND_COMMENT"] = "post_and_comment";
|
|
811
|
-
SubscriptionLevels["USER"] = "user";
|
|
812
|
-
})(SubscriptionLevels || (SubscriptionLevels = {}));
|
|
813
|
-
const getCommunityUserTopic = (path, level) => {
|
|
814
|
-
switch (level) {
|
|
815
|
-
case 'post':
|
|
816
|
-
return `${path}/post/+`;
|
|
817
|
-
case 'comment':
|
|
818
|
-
return `${path}/post/+/comment/+`;
|
|
819
|
-
case 'post_and_comment':
|
|
820
|
-
return `${path}/post/#`;
|
|
821
|
-
default:
|
|
822
|
-
return path;
|
|
823
|
-
}
|
|
824
|
-
};
|
|
825
|
-
const getCommunityTopic = ({ path }, level = SubscriptionLevels.COMMUNITY) => getCommunityUserTopic(path, level);
|
|
826
|
-
const getUserTopic = ({ path }, level = SubscriptionLevels.USER) => getCommunityUserTopic(level === SubscriptionLevels.USER ? path : path.replace(/^(\w*)/, '$1/social'), level);
|
|
827
|
-
const getPostTopic = ({ path }, level = SubscriptionLevels.POST) => {
|
|
828
|
-
switch (level) {
|
|
829
|
-
case 'comment':
|
|
830
|
-
return `${path}/comment/+`;
|
|
831
|
-
default:
|
|
832
|
-
return path;
|
|
833
|
-
}
|
|
834
|
-
};
|
|
835
|
-
const getCommentTopic = ({ path }) => {
|
|
836
|
-
return path;
|
|
837
|
-
};
|
|
838
|
-
const getMyFollowersTopic = () => {
|
|
839
|
-
const user = getActiveUser();
|
|
840
|
-
const [networkId] = user.path.split('/user/');
|
|
841
|
-
return `${networkId}/membership/${user._id}/+/+`;
|
|
842
|
-
};
|
|
843
|
-
const getMyFollowingsTopic = () => {
|
|
844
|
-
const user = getActiveUser();
|
|
845
|
-
const [networkId] = user.path.split('/user/');
|
|
846
|
-
return `${networkId}/membership/+/${user._id}/+`;
|
|
847
|
-
};
|
|
848
|
-
/** @hidden */
|
|
849
|
-
const getNetworkTopic = () => {
|
|
850
|
-
const user = getActiveUser();
|
|
851
|
-
const [networkId] = user.path.split('/user/');
|
|
852
|
-
return networkId;
|
|
853
|
-
};
|
|
854
|
-
let mqttAccessToken;
|
|
855
|
-
let mqttUserId;
|
|
856
|
-
function subscribeTopic(topic, callback) {
|
|
857
|
-
const { mqtt, emitter, accessToken } = getActiveClient();
|
|
858
|
-
const user = getActiveUser();
|
|
859
|
-
if (mqttAccessToken !== accessToken || mqttUserId !== user._id) {
|
|
860
|
-
mqttAccessToken = accessToken;
|
|
861
|
-
mqttUserId = user._id;
|
|
862
|
-
mqtt.connect({ accessToken: mqttAccessToken, userId: mqttUserId });
|
|
863
|
-
proxyMqttEvents(mqtt, emitter);
|
|
864
|
-
}
|
|
865
|
-
return mqtt.subscribe(topic, callback);
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
/**
|
|
869
|
-
* ```js
|
|
870
|
-
* import { enableCache } from '@amityco/ts-sdk'
|
|
871
|
-
* enableCache()
|
|
872
|
-
* ```
|
|
873
|
-
*
|
|
874
|
-
* Adds a new {@link Amity.Cache} object to
|
|
875
|
-
* an {@link Amity.Client} instance
|
|
876
|
-
*
|
|
877
|
-
* @param prevState a previous state of cache instance (useful for SSR)
|
|
878
|
-
* @param persistIf a function to determine if an entry inserted in cache
|
|
879
|
-
* is destined to be also saved in the persistent storage when
|
|
880
|
-
* calling {@link backupCache}
|
|
881
|
-
*
|
|
882
|
-
* @category Cache API
|
|
883
|
-
*/
|
|
884
|
-
const enableCache = (prevState = {}, persistIf) => {
|
|
885
|
-
const client = getActiveClient();
|
|
886
|
-
if (client.cache)
|
|
887
|
-
return;
|
|
888
|
-
client.log('cache/api/enableCache');
|
|
889
|
-
client.cache = { data: prevState, persistIf };
|
|
890
|
-
};
|
|
891
|
-
|
|
892
|
-
/**
|
|
893
|
-
* ```js
|
|
894
|
-
* import { disableCache } from '@amityco/ts-sdk'
|
|
895
|
-
* disableCache()
|
|
896
|
-
* ```
|
|
897
|
-
*
|
|
898
|
-
* Wipes the existing {@link Amity.Cache} object attached to
|
|
899
|
-
* an {@link Amity.Client} instance
|
|
900
|
-
*
|
|
901
|
-
* @category Cache API
|
|
902
|
-
*/
|
|
903
|
-
const disableCache = () => {
|
|
904
|
-
const client = getActiveClient();
|
|
905
|
-
if (!client.cache)
|
|
906
|
-
return;
|
|
907
|
-
client.log('cache/api/disableCache');
|
|
908
|
-
// we do this so that testing if cache is enabled
|
|
909
|
-
// is only `if (client.cache)
|
|
910
|
-
delete client.cache;
|
|
911
|
-
};
|
|
912
|
-
|
|
913
|
-
/**
|
|
914
|
-
* ```js
|
|
915
|
-
* import { restoreCache } from '@amityco/ts-sdk'
|
|
916
|
-
* const success = await restoreCache()
|
|
917
|
-
* ```
|
|
918
|
-
*
|
|
919
|
-
* Reads a previously saved {@link Amity.Cache} from a persistent storage,
|
|
920
|
-
* and inserts it into the current {@link Amity.Cache} instance.
|
|
921
|
-
*
|
|
922
|
-
* The strategy for persistent storage will depend on the runtime,
|
|
923
|
-
* which is supported by @react-native-async-storage/async-storage.
|
|
769
|
+
* The strategy for persistent storage will depend on the runtime,
|
|
770
|
+
* which is supported by @react-native-async-storage/async-storage.
|
|
924
771
|
*
|
|
925
772
|
* The current userId will be appended to the given storageKey to ensures
|
|
926
773
|
* the cached data concerns only the current user.
|
|
@@ -949,7 +796,6 @@ const restoreCache = async (storageKey = 'amitySdk') => {
|
|
|
949
796
|
return true;
|
|
950
797
|
};
|
|
951
798
|
|
|
952
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
953
799
|
/**
|
|
954
800
|
* ```js
|
|
955
801
|
* import { backupCache } from '@amityco/ts-sdk'
|
|
@@ -1016,62 +862,6 @@ const wipeCache = async (storageKey = 'amitySdk') => {
|
|
|
1016
862
|
return true;
|
|
1017
863
|
};
|
|
1018
864
|
|
|
1019
|
-
/**
|
|
1020
|
-
* Shallow-clones an object and sort its keys
|
|
1021
|
-
*
|
|
1022
|
-
* @param source a plain object to clone
|
|
1023
|
-
* @returns a clone of source, with keys sorted with default javascript sorting
|
|
1024
|
-
*
|
|
1025
|
-
* @category Cache
|
|
1026
|
-
* @hidden
|
|
1027
|
-
*/
|
|
1028
|
-
const normalize = (source) => Object.keys(source)
|
|
1029
|
-
.sort()
|
|
1030
|
-
.reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: source[key] })), {});
|
|
1031
|
-
/**
|
|
1032
|
-
* Encodes a given {@link Amity.CacheKey} to a plain string
|
|
1033
|
-
*
|
|
1034
|
-
* @param key the key to encode
|
|
1035
|
-
* @returns an encoded string
|
|
1036
|
-
*
|
|
1037
|
-
* @category Cache
|
|
1038
|
-
* @hidden
|
|
1039
|
-
*/
|
|
1040
|
-
const encodeKey = (key) => JSON.stringify(key, (_, val) => (typeof val === 'object' ? normalize(val) : val));
|
|
1041
|
-
/**
|
|
1042
|
-
* Decodes a string back into a {@link Amity.CacheKey}
|
|
1043
|
-
|
|
1044
|
-
*
|
|
1045
|
-
* @param key the string key to decode
|
|
1046
|
-
* @returns a plain Amity.CacheKey object.
|
|
1047
|
-
*
|
|
1048
|
-
* @category Cache
|
|
1049
|
-
* @hidden
|
|
1050
|
-
*/
|
|
1051
|
-
const decodeKey = (key) => JSON.parse(key);
|
|
1052
|
-
/**
|
|
1053
|
-
* Performs a recursive partial deep equal check on two objects.
|
|
1054
|
-
*
|
|
1055
|
-
* @param predicate the reference object containing the partial information
|
|
1056
|
-
* @param candidate the object to check against
|
|
1057
|
-
* @returns true if the candidate contains all the values of the predicate
|
|
1058
|
-
*
|
|
1059
|
-
* @category Cache
|
|
1060
|
-
*/
|
|
1061
|
-
const partialMatch = (predicate, candidate) => {
|
|
1062
|
-
if (predicate === candidate)
|
|
1063
|
-
return true;
|
|
1064
|
-
// if one or the other is nullish, there can't be equality
|
|
1065
|
-
if (!predicate || !candidate)
|
|
1066
|
-
return false;
|
|
1067
|
-
// we only perform recursive check on objects
|
|
1068
|
-
if (typeof predicate !== 'object') {
|
|
1069
|
-
return false;
|
|
1070
|
-
}
|
|
1071
|
-
// recursively call for partial match based on the predicate
|
|
1072
|
-
return Object.keys(predicate).every(key => partialMatch(predicate[key], candidate[key]));
|
|
1073
|
-
};
|
|
1074
|
-
|
|
1075
865
|
/**
|
|
1076
866
|
* ```js
|
|
1077
867
|
* import { queryCache } from '@amityco/ts-sdk'
|
|
@@ -1188,66 +978,348 @@ const mergeInCache = (key, mutation, options) => {
|
|
|
1188
978
|
};
|
|
1189
979
|
|
|
1190
980
|
/**
|
|
1191
|
-
* ```js
|
|
1192
|
-
* import { upsertInCache } from '@amityco/ts-sdk'
|
|
1193
|
-
* upsertInCache<Amity.User>(["user", "foobar"], user)
|
|
1194
|
-
* ```
|
|
1195
|
-
*
|
|
1196
|
-
* Insert or update any provided value as {@link Amity.CacheEntry} for
|
|
1197
|
-
* the matching {@link Amity.CacheKey}
|
|
1198
|
-
*
|
|
1199
|
-
* @param key the key to save the object to
|
|
1200
|
-
* @param data the object to save
|
|
1201
|
-
* @param options customisation object around cache behavior (default gives a 2mn lifespan)
|
|
1202
|
-
* @returns a success boolean if the object was saved in cache
|
|
981
|
+
* ```js
|
|
982
|
+
* import { upsertInCache } from '@amityco/ts-sdk'
|
|
983
|
+
* upsertInCache<Amity.User>(["user", "foobar"], user)
|
|
984
|
+
* ```
|
|
985
|
+
*
|
|
986
|
+
* Insert or update any provided value as {@link Amity.CacheEntry} for
|
|
987
|
+
* the matching {@link Amity.CacheKey}
|
|
988
|
+
*
|
|
989
|
+
* @param key the key to save the object to
|
|
990
|
+
* @param data the object to save
|
|
991
|
+
* @param options customisation object around cache behavior (default gives a 2mn lifespan)
|
|
992
|
+
* @returns a success boolean if the object was saved in cache
|
|
993
|
+
*
|
|
994
|
+
* @category Cache API
|
|
995
|
+
* @hidden
|
|
996
|
+
*/
|
|
997
|
+
const upsertInCache = (key, data, options = { cachedAt: Date.now() }) => {
|
|
998
|
+
const { log, cache } = getActiveClient();
|
|
999
|
+
if (!cache)
|
|
1000
|
+
return false;
|
|
1001
|
+
log('cache/api/upsertInCache', { key, data, options });
|
|
1002
|
+
const cached = pullFromCache(key);
|
|
1003
|
+
return cached ? mergeInCache(key, data, options) : pushToCache(key, data, options);
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* ```js
|
|
1008
|
+
* import { dropFromCache } from '@amityco/ts-sdk'
|
|
1009
|
+
* const success = dropFromCache(['user', 'foobar'])
|
|
1010
|
+
* ```
|
|
1011
|
+
*
|
|
1012
|
+
* Removes an existing {@link Amity.CacheEntry} from the {@link Amity.Client}'s
|
|
1013
|
+
* {@link Amity.Cache} from a given {@link Amity.CacheKey}
|
|
1014
|
+
*
|
|
1015
|
+
* @param key The key of the object to delete
|
|
1016
|
+
* @param exact If false, the function will delete all keys satisfying the given key
|
|
1017
|
+
* @returns A success boolean if the object was deleted
|
|
1018
|
+
*
|
|
1019
|
+
* @category Cache API
|
|
1020
|
+
*/
|
|
1021
|
+
const dropFromCache = (key, exact = false) => {
|
|
1022
|
+
const { log, cache } = getActiveClient();
|
|
1023
|
+
if (!cache)
|
|
1024
|
+
return false;
|
|
1025
|
+
log('cache/api/dropFromCache', { key, exact });
|
|
1026
|
+
if (!exact) {
|
|
1027
|
+
return Object.keys(cache.data)
|
|
1028
|
+
.map(stringKey => decodeKey(stringKey))
|
|
1029
|
+
.filter(candidate => partialMatch(key, candidate))
|
|
1030
|
+
.map(filteredKey => dropFromCache(filteredKey, true))
|
|
1031
|
+
.every(returned => returned);
|
|
1032
|
+
}
|
|
1033
|
+
const encodedKey = encodeKey(key);
|
|
1034
|
+
if (encodedKey in cache.data) {
|
|
1035
|
+
delete cache.data[encodedKey];
|
|
1036
|
+
return true;
|
|
1037
|
+
}
|
|
1038
|
+
return false;
|
|
1039
|
+
};
|
|
1040
|
+
|
|
1041
|
+
// Note:
|
|
1042
|
+
// this file should contain a suite of filtering utilities to help the
|
|
1043
|
+
// local version of the query functions.
|
|
1044
|
+
/**
|
|
1045
|
+
* Filter a given collection with strict equality against a param
|
|
1046
|
+
*
|
|
1047
|
+
* @param collection the collection to filter
|
|
1048
|
+
* @param key the key of the collection's items to challenge
|
|
1049
|
+
* @param value the expected value
|
|
1050
|
+
* @returns a filtered collection with items only matching the criteria
|
|
1051
|
+
*
|
|
1052
|
+
* @hidden
|
|
1053
|
+
*/
|
|
1054
|
+
const filterByPropEquality = (collection, key, value) => (value !== undefined ? collection.filter(item => item[key] === value) : collection);
|
|
1055
|
+
const filterByPropInclusion = (collection, key, value) => (value !== undefined ? collection.filter(item => value.includes(item[key])) : collection);
|
|
1056
|
+
/**
|
|
1057
|
+
* Filter a channel collection by membership of the userId
|
|
1058
|
+
*
|
|
1059
|
+
* @param collection the channel collection to filter
|
|
1060
|
+
* @param membership the membership to be filtered by
|
|
1061
|
+
* @param userId user id to be filtered by
|
|
1062
|
+
* @returns a filtered collection with items only matching the criteria
|
|
1063
|
+
*
|
|
1064
|
+
* @hidden
|
|
1065
|
+
*/
|
|
1066
|
+
const filterByChannelMembership = (collection, membership, userId) => {
|
|
1067
|
+
if (membership === 'all') {
|
|
1068
|
+
return collection;
|
|
1069
|
+
}
|
|
1070
|
+
return collection.filter(c => {
|
|
1071
|
+
var _a;
|
|
1072
|
+
// get resolver for the channel by user
|
|
1073
|
+
const channelUserCacheKey = getResolver('channelUsers')({
|
|
1074
|
+
channelId: c.channelId,
|
|
1075
|
+
userId,
|
|
1076
|
+
});
|
|
1077
|
+
const channelUser = (_a = pullFromCache([
|
|
1078
|
+
'channelUsers',
|
|
1079
|
+
'get',
|
|
1080
|
+
channelUserCacheKey,
|
|
1081
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
1082
|
+
// if channel user is defined for user, user is a member
|
|
1083
|
+
if (membership === 'member' && channelUser) {
|
|
1084
|
+
return true;
|
|
1085
|
+
}
|
|
1086
|
+
// if channel user by user id not found, user is not a member of that
|
|
1087
|
+
// channel
|
|
1088
|
+
if (membership === 'notMember' && !channelUser) {
|
|
1089
|
+
return true;
|
|
1090
|
+
}
|
|
1091
|
+
return false;
|
|
1092
|
+
});
|
|
1093
|
+
};
|
|
1094
|
+
|
|
1095
|
+
// Note:
|
|
1096
|
+
// this file should contain a suite of sorting utilities to help the
|
|
1097
|
+
// local version of the query functions.
|
|
1098
|
+
/**
|
|
1099
|
+
* Alphabetic sorting of objects having a displayName
|
|
1100
|
+
*/
|
|
1101
|
+
const sortByDisplayName = ({ displayName: a }, { displayName: b }) => {
|
|
1102
|
+
if (a === b)
|
|
1103
|
+
return 0;
|
|
1104
|
+
return a < b ? -1 : 1;
|
|
1105
|
+
};
|
|
1106
|
+
/**
|
|
1107
|
+
* Sorting a collection by their apparition order (oldest first)
|
|
1108
|
+
*/
|
|
1109
|
+
const sortByChannelSegment = ({ channelSegment: a }, { channelSegment: b }) => a - b;
|
|
1110
|
+
/**
|
|
1111
|
+
* Sorting a collection by their apparition order (oldest first)
|
|
1112
|
+
*/
|
|
1113
|
+
const sortBySegmentNumber = ({ segmentNumber: a }, { segmentNumber: b }) => a - b;
|
|
1114
|
+
/**
|
|
1115
|
+
* Sorting a collection by its oldest items
|
|
1116
|
+
*/
|
|
1117
|
+
const sortByFirstCreated = ({ createdAt: a }, { createdAt: b }) => new Date(a).valueOf() - new Date(b).valueOf();
|
|
1118
|
+
/**
|
|
1119
|
+
* Sorting a collection by its newest items
|
|
1120
|
+
*/
|
|
1121
|
+
const sortByLastCreated = ({ createdAt: a }, { createdAt: b }) => new Date(b).valueOf() - new Date(a).valueOf();
|
|
1122
|
+
/**
|
|
1123
|
+
* Sorting a collection by the items with most recent activity
|
|
1124
|
+
*/
|
|
1125
|
+
const sortByLastActivity = ({ lastActivity: a }, { lastActivity: b }) => new Date(b).valueOf() - new Date(a).valueOf();
|
|
1126
|
+
|
|
1127
|
+
/* eslint-disable @typescript-eslint/ban-types */
|
|
1128
|
+
let tasks = [];
|
|
1129
|
+
let timer;
|
|
1130
|
+
/**
|
|
1131
|
+
* Add a function to run just before the next tick
|
|
1132
|
+
*
|
|
1133
|
+
* @param task function to schedule for later execution
|
|
1134
|
+
*/
|
|
1135
|
+
const scheduleTask = (task) => {
|
|
1136
|
+
clearTimeout(timer);
|
|
1137
|
+
tasks.push(task);
|
|
1138
|
+
timer = setTimeout(() => {
|
|
1139
|
+
tasks.forEach(fn => fn());
|
|
1140
|
+
tasks = [];
|
|
1141
|
+
}, 0);
|
|
1142
|
+
};
|
|
1143
|
+
|
|
1144
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
1145
|
+
// need to sync up the list
|
|
1146
|
+
const WS_EVENTS = [
|
|
1147
|
+
'disconnected',
|
|
1148
|
+
'error',
|
|
1149
|
+
'connect_error',
|
|
1150
|
+
'reconnect_error',
|
|
1151
|
+
'reconnect_failed',
|
|
1152
|
+
'v3.channel.didCreate',
|
|
1153
|
+
'v3.channel.didUpdate',
|
|
1154
|
+
'v3.channel.didDelete',
|
|
1155
|
+
'v3.channel.didJoin',
|
|
1156
|
+
'v3.channel.didLeave',
|
|
1157
|
+
'v3.channel.didAddUsers',
|
|
1158
|
+
'v3.channel.didRemoveUsers',
|
|
1159
|
+
'v3.channel.didBan',
|
|
1160
|
+
'v3.channel.didUnban',
|
|
1161
|
+
'v3.message.didFetch',
|
|
1162
|
+
'v3.message.didCreate',
|
|
1163
|
+
'v3.message.didUpdate',
|
|
1164
|
+
'v3.message.didDelete',
|
|
1165
|
+
];
|
|
1166
|
+
const MQTT_EVENTS = [
|
|
1167
|
+
'connect',
|
|
1168
|
+
'message',
|
|
1169
|
+
'disconnect',
|
|
1170
|
+
'error',
|
|
1171
|
+
'close',
|
|
1172
|
+
'end',
|
|
1173
|
+
'reconnect',
|
|
1174
|
+
];
|
|
1175
|
+
/** @hidden */
|
|
1176
|
+
const createEventEmitter = () => {
|
|
1177
|
+
return mitt();
|
|
1178
|
+
};
|
|
1179
|
+
/**
|
|
1180
|
+
* Wraps the websocket events into the client's event emitter for
|
|
1181
|
+
* abstraction of transport.
|
|
1182
|
+
*
|
|
1183
|
+
* @param ws A websocket connection to listen from
|
|
1184
|
+
* @param emitter An event emitter to wire the events to
|
|
1185
|
+
*
|
|
1186
|
+
* @category Transport
|
|
1187
|
+
* @hidden
|
|
1188
|
+
*/
|
|
1189
|
+
const proxyWebsocketEvents = (ws, emitter) => {
|
|
1190
|
+
WS_EVENTS.forEach(event => {
|
|
1191
|
+
ws.on(event, (param) => emitter.emit(event, param));
|
|
1192
|
+
});
|
|
1193
|
+
};
|
|
1194
|
+
const proxyMqttEvents = (mqttClient, emitter) => {
|
|
1195
|
+
MQTT_EVENTS.forEach(event => {
|
|
1196
|
+
mqttClient.on(event, (...params) => emitter.emit(event, params.length === 1 ? params[0] : params));
|
|
1197
|
+
});
|
|
1198
|
+
// @ts-ignore
|
|
1199
|
+
mqttClient.on('message', (topic, payload) => {
|
|
1200
|
+
const message = JSON.parse(payload.toString());
|
|
1201
|
+
emitter.emit(message.eventType, message.data);
|
|
1202
|
+
});
|
|
1203
|
+
};
|
|
1204
|
+
/**
|
|
1205
|
+
* Standardize the subscription of SSE through web sockets
|
|
1206
|
+
*
|
|
1207
|
+
* @param client The current client for which to subscribe the event to
|
|
1208
|
+
* @param namespace A unique name for the logger
|
|
1209
|
+
* @param event The websocket event name
|
|
1210
|
+
* @param fn A wrapper for the callback.
|
|
1211
|
+
* @returns A dispose function to unsubscribe to the event
|
|
1212
|
+
*
|
|
1213
|
+
* @category Transport
|
|
1214
|
+
* @hidden
|
|
1215
|
+
*/
|
|
1216
|
+
const createEventSubscriber = (client, namespace, event, fn) => {
|
|
1217
|
+
const { log, emitter } = client;
|
|
1218
|
+
const timestamp = Date.now();
|
|
1219
|
+
log(`${namespace}(tmpid: ${timestamp}) > listen`);
|
|
1220
|
+
const handler = (...payload) => {
|
|
1221
|
+
log(`${namespace}(tmpid: ${timestamp}) > trigger`, payload);
|
|
1222
|
+
fn(...payload);
|
|
1223
|
+
};
|
|
1224
|
+
emitter.on(event, handler);
|
|
1225
|
+
return () => {
|
|
1226
|
+
log(`${namespace}(tmpid: ${timestamp}) > dispose`);
|
|
1227
|
+
emitter.off(event, handler);
|
|
1228
|
+
};
|
|
1229
|
+
};
|
|
1230
|
+
/**
|
|
1231
|
+
* Wrapper around dispatch event
|
|
1203
1232
|
*
|
|
1204
|
-
* @category Cache API
|
|
1205
1233
|
* @hidden
|
|
1206
1234
|
*/
|
|
1207
|
-
const
|
|
1208
|
-
const {
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
const cached = pullFromCache(key);
|
|
1213
|
-
return cached ? mergeInCache(key, data, options) : pushToCache(key, data, options);
|
|
1235
|
+
const fireEvent = (event, payload) => {
|
|
1236
|
+
const { emitter } = getActiveClient();
|
|
1237
|
+
scheduleTask(() => {
|
|
1238
|
+
emitter.emit(event, payload);
|
|
1239
|
+
});
|
|
1214
1240
|
};
|
|
1215
1241
|
|
|
1242
|
+
let activeUser = null;
|
|
1216
1243
|
/**
|
|
1217
|
-
*
|
|
1218
|
-
* import { dropFromCache } from '@amityco/ts-sdk'
|
|
1219
|
-
* const success = dropFromCache(['user', 'foobar'])
|
|
1220
|
-
* ```
|
|
1221
|
-
*
|
|
1222
|
-
* Removes an existing {@link Amity.CacheEntry} from the {@link Amity.Client}'s
|
|
1223
|
-
* {@link Amity.Cache} from a given {@link Amity.CacheKey}
|
|
1224
|
-
*
|
|
1225
|
-
* @param key The key of the object to delete
|
|
1226
|
-
* @param exact If false, the function will delete all keys satisfying the given key
|
|
1227
|
-
* @returns A success boolean if the object was deleted
|
|
1228
|
-
*
|
|
1229
|
-
* @category Cache API
|
|
1244
|
+
* for internal use
|
|
1230
1245
|
*/
|
|
1231
|
-
const
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
return false;
|
|
1235
|
-
log('cache/api/dropFromCache', { key, exact });
|
|
1236
|
-
if (!exact) {
|
|
1237
|
-
return Object.keys(cache.data)
|
|
1238
|
-
.map(stringKey => decodeKey(stringKey))
|
|
1239
|
-
.filter(candidate => partialMatch(key, candidate))
|
|
1240
|
-
.map(filteredKey => dropFromCache(filteredKey, true))
|
|
1241
|
-
.every(returned => returned);
|
|
1242
|
-
}
|
|
1243
|
-
const encodedKey = encodeKey(key);
|
|
1244
|
-
if (encodedKey in cache.data) {
|
|
1245
|
-
delete cache.data[encodedKey];
|
|
1246
|
-
return true;
|
|
1246
|
+
const getActiveUser = () => {
|
|
1247
|
+
if (!activeUser) {
|
|
1248
|
+
throw new ASCError('Connect client first', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
|
|
1247
1249
|
}
|
|
1248
|
-
return
|
|
1250
|
+
return activeUser;
|
|
1251
|
+
};
|
|
1252
|
+
const setActiveUser = (user) => {
|
|
1253
|
+
activeUser = {
|
|
1254
|
+
_id: user._id,
|
|
1255
|
+
userId: user.userId,
|
|
1256
|
+
path: user.path,
|
|
1257
|
+
};
|
|
1249
1258
|
};
|
|
1250
1259
|
|
|
1260
|
+
var SubscriptionLevels;
|
|
1261
|
+
(function (SubscriptionLevels) {
|
|
1262
|
+
SubscriptionLevels["COMMUNITY"] = "community";
|
|
1263
|
+
SubscriptionLevels["POST"] = "post";
|
|
1264
|
+
SubscriptionLevels["COMMENT"] = "comment";
|
|
1265
|
+
SubscriptionLevels["POST_AND_COMMENT"] = "post_and_comment";
|
|
1266
|
+
SubscriptionLevels["USER"] = "user";
|
|
1267
|
+
})(SubscriptionLevels || (SubscriptionLevels = {}));
|
|
1268
|
+
const getCommunityUserTopic = (path, level) => {
|
|
1269
|
+
switch (level) {
|
|
1270
|
+
case 'post':
|
|
1271
|
+
return `${path}/post/+`;
|
|
1272
|
+
case 'comment':
|
|
1273
|
+
return `${path}/post/+/comment/+`;
|
|
1274
|
+
case 'post_and_comment':
|
|
1275
|
+
return `${path}/post/#`;
|
|
1276
|
+
default:
|
|
1277
|
+
return path;
|
|
1278
|
+
}
|
|
1279
|
+
};
|
|
1280
|
+
const getCommunityTopic = ({ path }, level = SubscriptionLevels.COMMUNITY) => getCommunityUserTopic(path, level);
|
|
1281
|
+
const getUserTopic = ({ path }, level = SubscriptionLevels.USER) => getCommunityUserTopic(level === SubscriptionLevels.USER ? path : path.replace(/^(\w*)/, '$1/social'), level);
|
|
1282
|
+
const getPostTopic = ({ path }, level = SubscriptionLevels.POST) => {
|
|
1283
|
+
switch (level) {
|
|
1284
|
+
case 'comment':
|
|
1285
|
+
return `${path}/comment/+`;
|
|
1286
|
+
default:
|
|
1287
|
+
return path;
|
|
1288
|
+
}
|
|
1289
|
+
};
|
|
1290
|
+
const getCommentTopic = ({ path }) => {
|
|
1291
|
+
return path;
|
|
1292
|
+
};
|
|
1293
|
+
const getMyFollowersTopic = () => {
|
|
1294
|
+
const user = getActiveUser();
|
|
1295
|
+
const [networkId] = user.path.split('/user/');
|
|
1296
|
+
return `${networkId}/membership/${user._id}/+/+`;
|
|
1297
|
+
};
|
|
1298
|
+
const getMyFollowingsTopic = () => {
|
|
1299
|
+
const user = getActiveUser();
|
|
1300
|
+
const [networkId] = user.path.split('/user/');
|
|
1301
|
+
return `${networkId}/membership/+/${user._id}/+`;
|
|
1302
|
+
};
|
|
1303
|
+
/** @hidden */
|
|
1304
|
+
const getNetworkTopic = () => {
|
|
1305
|
+
const user = getActiveUser();
|
|
1306
|
+
const [networkId] = user.path.split('/user/');
|
|
1307
|
+
return networkId;
|
|
1308
|
+
};
|
|
1309
|
+
let mqttAccessToken;
|
|
1310
|
+
let mqttUserId;
|
|
1311
|
+
function subscribeTopic(topic, callback) {
|
|
1312
|
+
const { mqtt, emitter, accessToken } = getActiveClient();
|
|
1313
|
+
const user = getActiveUser();
|
|
1314
|
+
if (mqttAccessToken !== accessToken || mqttUserId !== user._id) {
|
|
1315
|
+
mqttAccessToken = accessToken;
|
|
1316
|
+
mqttUserId = user._id;
|
|
1317
|
+
mqtt.connect({ accessToken: mqttAccessToken, userId: mqttUserId });
|
|
1318
|
+
proxyMqttEvents(mqtt, emitter);
|
|
1319
|
+
}
|
|
1320
|
+
return mqtt.subscribe(topic, callback);
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1251
1323
|
/**
|
|
1252
1324
|
* Creates a pre-configured logger instance
|
|
1253
1325
|
*
|
|
@@ -1310,21 +1382,8 @@ const unwrapPayload = (response) => {
|
|
|
1310
1382
|
* Axios param serializer (for querystring)
|
|
1311
1383
|
* @hidden
|
|
1312
1384
|
*/
|
|
1313
|
-
const stringify = (params
|
|
1314
|
-
return
|
|
1315
|
-
.filter(([, value]) => value !== undefined)
|
|
1316
|
-
.map(([name, value]) => {
|
|
1317
|
-
const key = prefix ? `${prefix}[${name}]` : name;
|
|
1318
|
-
if (Array.isArray(value)) {
|
|
1319
|
-
return value.map(item => `${key}[]=${item}`).join('&');
|
|
1320
|
-
}
|
|
1321
|
-
if (typeof value !== 'object') {
|
|
1322
|
-
return `${key}=${value}`;
|
|
1323
|
-
}
|
|
1324
|
-
// @ts-ignore
|
|
1325
|
-
return stringify(value, prefix !== null && prefix !== void 0 ? prefix : name);
|
|
1326
|
-
})
|
|
1327
|
-
.join('&');
|
|
1385
|
+
const stringify = (params) => {
|
|
1386
|
+
return qs.stringify(params, { arrayFormat: 'brackets' });
|
|
1328
1387
|
};
|
|
1329
1388
|
/**
|
|
1330
1389
|
* Creates a pre-configured axios instance
|
|
@@ -20564,6 +20623,61 @@ const isConnected = () => {
|
|
|
20564
20623
|
client.ws.connected);
|
|
20565
20624
|
};
|
|
20566
20625
|
|
|
20626
|
+
/**
|
|
20627
|
+
* ```js
|
|
20628
|
+
* import { isInTombstone } from '@amityco/ts-sdk'
|
|
20629
|
+
* const user = isInTombstone(["message", "messageId"])
|
|
20630
|
+
* ```
|
|
20631
|
+
*
|
|
20632
|
+
* Checks if the {@link Amity.TombstoneCacheOptions} exists
|
|
20633
|
+
* in cache and it's not expired means it's in tombstone
|
|
20634
|
+
* and we throw an Error
|
|
20635
|
+
*
|
|
20636
|
+
* @param model the model to check
|
|
20637
|
+
* @param modelId the object id to check
|
|
20638
|
+
* @returns the matching cache entry, or undefined.
|
|
20639
|
+
*
|
|
20640
|
+
* @category Cache API
|
|
20641
|
+
*/
|
|
20642
|
+
const isInTombstone = (model, modelId) => {
|
|
20643
|
+
const { log, cache } = getActiveClient();
|
|
20644
|
+
const key = [model, CACHE_KEY_TOMBSTONE, modelId];
|
|
20645
|
+
if (!cache)
|
|
20646
|
+
return;
|
|
20647
|
+
log('cache/api/isInTombstone', key);
|
|
20648
|
+
const isInTombstone = pullFromCache(key);
|
|
20649
|
+
const { lifeSpan } = queryOptions('cache_then_server', CACHE_LIFESPAN_TOMBSTONE);
|
|
20650
|
+
if (isInTombstone && isFresh(isInTombstone.data, lifeSpan)) {
|
|
20651
|
+
throw new ASCApiError('Item not found!', 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
20652
|
+
}
|
|
20653
|
+
};
|
|
20654
|
+
|
|
20655
|
+
/**
|
|
20656
|
+
* ```js
|
|
20657
|
+
* import { pushToTombstone } from '@amityco/ts-sdk'
|
|
20658
|
+
* pushToTombstone(["message", "messageId"], { cachedAt: Date.now() })
|
|
20659
|
+
* ```
|
|
20660
|
+
*
|
|
20661
|
+
* Removes an existing {@link Amity.CacheEntry} from the {@link Amity.Client}'s
|
|
20662
|
+
* {@link Amity.Cache} from a given {@link Amity.CacheKey}
|
|
20663
|
+
*
|
|
20664
|
+
* @param model the model to remove and push to Tombstone
|
|
20665
|
+
* @param modelId the related model id
|
|
20666
|
+
*
|
|
20667
|
+
* @category Cache API
|
|
20668
|
+
* @hidden
|
|
20669
|
+
*/
|
|
20670
|
+
const pushToTombstone = (model, modelId) => {
|
|
20671
|
+
const { log, cache } = getActiveClient();
|
|
20672
|
+
const cacheKey = [model, CACHE_KEY_TOMBSTONE, modelId];
|
|
20673
|
+
const data = { cachedAt: Date.now() };
|
|
20674
|
+
if (!cache)
|
|
20675
|
+
return;
|
|
20676
|
+
log('cache/api/pushToTombstone', { cacheKey, data });
|
|
20677
|
+
dropFromCache([model, CACHE_KEY_GET, modelId], true);
|
|
20678
|
+
pushToCache(cacheKey, data);
|
|
20679
|
+
};
|
|
20680
|
+
|
|
20567
20681
|
/**
|
|
20568
20682
|
* ```js
|
|
20569
20683
|
* import { getUser } from '@amityco/ts-sdk'
|
|
@@ -20578,15 +20692,29 @@ const isConnected = () => {
|
|
|
20578
20692
|
* @category User API
|
|
20579
20693
|
* @async
|
|
20580
20694
|
*/
|
|
20581
|
-
const getUser = async (userId) => {
|
|
20695
|
+
const getUser = async (userId, isLive = false) => {
|
|
20582
20696
|
const client = getActiveClient();
|
|
20583
20697
|
client.log('user/getUser', userId);
|
|
20584
|
-
|
|
20585
|
-
|
|
20698
|
+
if (!isLive) {
|
|
20699
|
+
console.log('getUser will be deprecated on 25th November 2022, please use liveUser instead.');
|
|
20700
|
+
}
|
|
20701
|
+
isInTombstone('user', userId);
|
|
20702
|
+
let data;
|
|
20703
|
+
try {
|
|
20704
|
+
const response = await client.http.get(`/api/v3/users/${encodeURIComponent(userId)}`);
|
|
20705
|
+
data = response.data;
|
|
20706
|
+
}
|
|
20707
|
+
catch (error) {
|
|
20708
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
20709
|
+
pushToTombstone('user', userId);
|
|
20710
|
+
}
|
|
20711
|
+
throw error;
|
|
20712
|
+
}
|
|
20586
20713
|
const cachedAt = client.cache && Date.now();
|
|
20587
20714
|
if (client.cache)
|
|
20588
20715
|
ingestInCache(data, { cachedAt });
|
|
20589
20716
|
const { users } = data;
|
|
20717
|
+
fireEvent('user.fetched', data);
|
|
20590
20718
|
return {
|
|
20591
20719
|
data: users.find(user => user.userId === userId),
|
|
20592
20720
|
cachedAt,
|
|
@@ -20636,6 +20764,7 @@ const getUsers = async (userIds) => {
|
|
|
20636
20764
|
const cachedAt = client.cache && Date.now();
|
|
20637
20765
|
if (client.cache)
|
|
20638
20766
|
ingestInCache(data, { cachedAt });
|
|
20767
|
+
fireEvent('user.fetched', data);
|
|
20639
20768
|
return {
|
|
20640
20769
|
data: data.users,
|
|
20641
20770
|
cachedAt,
|
|
@@ -20718,8 +20847,7 @@ function __rest(s, e) {
|
|
|
20718
20847
|
const queryUsers = async (query = {}) => {
|
|
20719
20848
|
const client = getActiveClient();
|
|
20720
20849
|
client.log('user/queryUsers', query);
|
|
20721
|
-
const { page, displayName, filter = 'all', sortBy = 'displayName' } = query, params = __rest(query, ["page", "displayName", "filter", "sortBy"]);
|
|
20722
|
-
// API-FIX: parameters should be querystring.
|
|
20850
|
+
const { page = { limit: 10 }, displayName, filter = 'all', sortBy = 'displayName' } = query, params = __rest(query, ["page", "displayName", "filter", "sortBy"]);
|
|
20723
20851
|
const { data } = await client.http.get(`/api/v3/users`, {
|
|
20724
20852
|
params: Object.assign(Object.assign({}, params), { keyword: displayName, filter,
|
|
20725
20853
|
sortBy, options: {
|
|
@@ -20732,9 +20860,14 @@ const queryUsers = async (query = {}) => {
|
|
|
20732
20860
|
const cachedAt = client.cache && Date.now();
|
|
20733
20861
|
if (client.cache) {
|
|
20734
20862
|
ingestInCache(payload, { cachedAt });
|
|
20735
|
-
|
|
20863
|
+
/*
|
|
20864
|
+
* using query as cache key over params because if the keyword, filter, sort
|
|
20865
|
+
* change the API will NOT cache results, when it should
|
|
20866
|
+
*/
|
|
20867
|
+
const cacheKey = ['user', 'query', Object.assign(Object.assign({}, query), { options: Object.assign({}, page) })];
|
|
20736
20868
|
pushToCache(cacheKey, { users: users.map(getResolver('user')), paging });
|
|
20737
20869
|
}
|
|
20870
|
+
fireEvent('user.fetched', data);
|
|
20738
20871
|
const prevPage = toPage(paging.previous);
|
|
20739
20872
|
const nextPage = toPage(paging.next);
|
|
20740
20873
|
return { data: users, cachedAt, prevPage, nextPage };
|
|
@@ -20759,8 +20892,13 @@ queryUsers.locally = (query = {}) => {
|
|
|
20759
20892
|
client.log('user/queryUsers.locally', query);
|
|
20760
20893
|
if (!client.cache)
|
|
20761
20894
|
return;
|
|
20762
|
-
const
|
|
20763
|
-
const
|
|
20895
|
+
const { page = { limit: 10 } } = query !== null && query !== void 0 ? query : {};
|
|
20896
|
+
const cacheKey = [
|
|
20897
|
+
'user',
|
|
20898
|
+
'query',
|
|
20899
|
+
Object.assign(Object.assign({}, query), { options: Object.assign({}, page) }),
|
|
20900
|
+
];
|
|
20901
|
+
const { data, cachedAt } = (_a = pullFromCache(cacheKey)) !== null && _a !== void 0 ? _a : {};
|
|
20764
20902
|
const users = (_b = data === null || data === void 0 ? void 0 : data.users.map(userId => pullFromCache(['user', 'get', userId])).filter(Boolean).map(({ data }) => data)) !== null && _b !== void 0 ? _b : [];
|
|
20765
20903
|
const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
|
|
20766
20904
|
const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
|
|
@@ -20798,12 +20936,30 @@ const updateUser = async (userId, patch) => {
|
|
|
20798
20936
|
if (client.cache)
|
|
20799
20937
|
ingestInCache(data, { cachedAt });
|
|
20800
20938
|
const { users } = data;
|
|
20939
|
+
fireEvent('user.updated', data);
|
|
20801
20940
|
return {
|
|
20802
20941
|
data: users.find(user => user.userId === userId),
|
|
20803
20942
|
cachedAt,
|
|
20804
20943
|
};
|
|
20805
20944
|
};
|
|
20806
20945
|
|
|
20946
|
+
/**
|
|
20947
|
+
* ```js
|
|
20948
|
+
* import { onUserFetched } from '@amityco/ts-sdk'
|
|
20949
|
+
* const dispose = onUserFetched(user => {
|
|
20950
|
+
* // ...
|
|
20951
|
+
* })
|
|
20952
|
+
* ```
|
|
20953
|
+
*
|
|
20954
|
+
* Fired when a {@link Amity.User} has been fetched
|
|
20955
|
+
*
|
|
20956
|
+
* @param callback The function to call when the event was fired
|
|
20957
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
20958
|
+
*
|
|
20959
|
+
* @category User Events
|
|
20960
|
+
*/
|
|
20961
|
+
const onUserFetched = (callback) => createUserEventSubscriber('user.fetched', callback);
|
|
20962
|
+
|
|
20807
20963
|
/**
|
|
20808
20964
|
* ```js
|
|
20809
20965
|
* import { onUserUpdated } from '@amityco/ts-sdk'
|
|
@@ -20872,6 +21028,68 @@ const onUserUnflagged = (callback) => createUserEventSubscriber('user.unflagged'
|
|
|
20872
21028
|
*/
|
|
20873
21029
|
const onUserFlagCleared = (callback) => createUserEventSubscriber('user.flagCleared', callback);
|
|
20874
21030
|
|
|
21031
|
+
const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
|
|
21032
|
+
const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
|
|
21033
|
+
const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
|
|
21034
|
+
const LIVE_OBJECT_ENABLE_CACHE_MESSAGE = 'For using Live Object feature you need to enable Cache!';
|
|
21035
|
+
const UNSYNCED_OBJECT_CACHED_AT_MESSAGE = 'Observing unsynced object is not supported by Live Object.';
|
|
21036
|
+
const UNSYNCED_OBJECT_CACHED_AT_VALUE = -5;
|
|
21037
|
+
|
|
21038
|
+
/**
|
|
21039
|
+
* ```js
|
|
21040
|
+
* import { liveUser } from '@amityco/ts-sdk'
|
|
21041
|
+
*
|
|
21042
|
+
* let users = []
|
|
21043
|
+
* const unsub = liveUser(userId, response => merge(users, response.data))
|
|
21044
|
+
* ```
|
|
21045
|
+
*
|
|
21046
|
+
* Observe all mutation on a given {@link Amity.User}
|
|
21047
|
+
*
|
|
21048
|
+
* @param userId the ID of the user to observe
|
|
21049
|
+
* @param callback the function to call when new data are available
|
|
21050
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the users
|
|
21051
|
+
*
|
|
21052
|
+
* @category Message Live Object
|
|
21053
|
+
*/
|
|
21054
|
+
const liveUser = (userId, callback) => {
|
|
21055
|
+
const { log, cache } = getActiveClient();
|
|
21056
|
+
let user;
|
|
21057
|
+
if (!cache) {
|
|
21058
|
+
console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
|
|
21059
|
+
}
|
|
21060
|
+
const timestamp = Date.now();
|
|
21061
|
+
log(`liveUser(tmpid: ${timestamp}) > listen`);
|
|
21062
|
+
const disposers = [];
|
|
21063
|
+
const dispatcher = (data) => {
|
|
21064
|
+
var _a;
|
|
21065
|
+
// we check updatedAt to see if the current snapshot is new so
|
|
21066
|
+
// we won't send old data back, only fresh new data
|
|
21067
|
+
if (user && ((_a = data.data) === null || _a === void 0 ? void 0 : _a.updatedAt) === (user === null || user === void 0 ? void 0 : user.updatedAt) && data.origin !== 'server')
|
|
21068
|
+
return;
|
|
21069
|
+
callback(data);
|
|
21070
|
+
user = data.data;
|
|
21071
|
+
};
|
|
21072
|
+
const realtimeRouter = (user, action) => {
|
|
21073
|
+
dispatcher({ loading: false, data: user, origin: 'event' });
|
|
21074
|
+
};
|
|
21075
|
+
const onFetch = () => {
|
|
21076
|
+
const query = createQuery(getUser, userId, true);
|
|
21077
|
+
runQuery(query, ({ loading, data, error, origin }) => {
|
|
21078
|
+
dispatcher({ loading, data, origin, error });
|
|
21079
|
+
if (error) {
|
|
21080
|
+
// Terminate observe functionality on error
|
|
21081
|
+
disposers.forEach(fn => fn());
|
|
21082
|
+
}
|
|
21083
|
+
});
|
|
21084
|
+
};
|
|
21085
|
+
disposers.push(onUserFetched(user => realtimeRouter(user)), onUserUpdated(user => realtimeRouter(user)), onUserDeleted(user => realtimeRouter(user)), onUserFlagged(user => realtimeRouter(user)), onUserUnflagged(user => realtimeRouter(user)), onUserFlagCleared(user => realtimeRouter(user)));
|
|
21086
|
+
onFetch();
|
|
21087
|
+
return () => {
|
|
21088
|
+
log(`liveUser(tmpid: ${timestamp}) > dispose`);
|
|
21089
|
+
disposers.forEach(fn => fn());
|
|
21090
|
+
};
|
|
21091
|
+
};
|
|
21092
|
+
|
|
20875
21093
|
/**
|
|
20876
21094
|
* ```js
|
|
20877
21095
|
* import { observeUser } from '@amityco/ts-sdk'
|
|
@@ -20891,6 +21109,7 @@ const observeUser = (userId, callback) => {
|
|
|
20891
21109
|
const { log } = getActiveClient();
|
|
20892
21110
|
const timestamp = Date.now();
|
|
20893
21111
|
log(`observeUser(tmpid: ${timestamp}) > listen`);
|
|
21112
|
+
console.log('observeUser will be deprecated on 25th November 2022, please use liveUser instead.');
|
|
20894
21113
|
// wrapper function to make sure
|
|
20895
21114
|
const router = (result, action) => {
|
|
20896
21115
|
var _a, _b, _c;
|
|
@@ -21300,15 +21519,30 @@ const dispatchReactable = (referenceType, model) => {
|
|
|
21300
21519
|
* @category Message API
|
|
21301
21520
|
* @async
|
|
21302
21521
|
*/
|
|
21303
|
-
const getMessage = async (messageId) => {
|
|
21522
|
+
const getMessage = async (messageId, isLive = false) => {
|
|
21304
21523
|
const client = getActiveClient();
|
|
21305
21524
|
client.log('message/getMessage', messageId);
|
|
21306
|
-
|
|
21307
|
-
|
|
21525
|
+
if (!isLive) {
|
|
21526
|
+
console.log('getMessage will be deprecated on 15th November 2022, please use liveMessage instead.');
|
|
21527
|
+
}
|
|
21528
|
+
isInTombstone('message', messageId);
|
|
21529
|
+
let data;
|
|
21530
|
+
try {
|
|
21531
|
+
// API-FIX: endpoint should not be /list, parameters should be querystring.
|
|
21532
|
+
const response = await client.http.get(`/api/v3/messages/${encodeURIComponent(messageId)}`);
|
|
21533
|
+
data = response.data;
|
|
21534
|
+
}
|
|
21535
|
+
catch (error) {
|
|
21536
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
21537
|
+
pushToTombstone('message', messageId);
|
|
21538
|
+
}
|
|
21539
|
+
throw error;
|
|
21540
|
+
}
|
|
21308
21541
|
const cachedAt = client.cache && Date.now();
|
|
21309
21542
|
if (client.cache)
|
|
21310
21543
|
ingestInCache(data, { cachedAt });
|
|
21311
21544
|
const { messages } = data;
|
|
21545
|
+
fireEvent('v3.message.didFetch', { messages });
|
|
21312
21546
|
return {
|
|
21313
21547
|
data: messages.find(message => message.messageId === messageId),
|
|
21314
21548
|
cachedAt,
|
|
@@ -21365,8 +21599,10 @@ const getMessages = async (messageIds) => {
|
|
|
21365
21599
|
const cachedAt = client.cache && Date.now();
|
|
21366
21600
|
if (client.cache)
|
|
21367
21601
|
ingestInCache(data, { cachedAt });
|
|
21602
|
+
const { messages } = data;
|
|
21603
|
+
fireEvent('v3.message.didFetch', { messages });
|
|
21368
21604
|
return {
|
|
21369
|
-
data:
|
|
21605
|
+
data: messages,
|
|
21370
21606
|
cachedAt,
|
|
21371
21607
|
};
|
|
21372
21608
|
};
|
|
@@ -21443,6 +21679,7 @@ const queryMessages = async (query) => {
|
|
|
21443
21679
|
];
|
|
21444
21680
|
pushToCache(cacheKey, { messages: messages.map(getResolver('message')), paging });
|
|
21445
21681
|
}
|
|
21682
|
+
fireEvent('v3.message.didFetch', { messages });
|
|
21446
21683
|
const nextPage = toPage(paging.next);
|
|
21447
21684
|
const prevPage = toPage(paging.previous);
|
|
21448
21685
|
return { data: messages, cachedAt, prevPage, nextPage };
|
|
@@ -21508,8 +21745,8 @@ const createMessage = async (bundle) => {
|
|
|
21508
21745
|
const cachedAt = client.cache && Date.now();
|
|
21509
21746
|
if (client.cache)
|
|
21510
21747
|
ingestInCache(data, { cachedAt });
|
|
21511
|
-
// no need for event, fired by server
|
|
21512
21748
|
const { messages } = data;
|
|
21749
|
+
fireEvent('v3.message.didCreate', { messages });
|
|
21513
21750
|
return {
|
|
21514
21751
|
data: messages[0],
|
|
21515
21752
|
cachedAt,
|
|
@@ -21551,11 +21788,12 @@ createMessage.optimistically = (bundle) => {
|
|
|
21551
21788
|
// as reused to update created and updated time, which should be the same
|
|
21552
21789
|
const createdTime = new Date().toISOString();
|
|
21553
21790
|
const message = Object.assign({ userId: client.userId, channelSegment: ((_b = channel === null || channel === void 0 ? void 0 : channel.data.messageCount) !== null && _b !== void 0 ? _b : 0) + 1, createdAt: createdTime, updatedAt: createdTime }, bundleWithMessageId);
|
|
21554
|
-
|
|
21791
|
+
const cachedAt = UNSYNCED_OBJECT_CACHED_AT_VALUE;
|
|
21792
|
+
pushToCache(['message', 'get', message.messageId], message, { cachedAt });
|
|
21555
21793
|
fireEvent('v3.message.didCreate', { messages: [message] });
|
|
21556
21794
|
return {
|
|
21795
|
+
cachedAt,
|
|
21557
21796
|
data: message,
|
|
21558
|
-
cachedAt: -1,
|
|
21559
21797
|
};
|
|
21560
21798
|
};
|
|
21561
21799
|
|
|
@@ -21584,6 +21822,7 @@ const updateMessage = async (messageId, patch) => {
|
|
|
21584
21822
|
if (client.cache)
|
|
21585
21823
|
ingestInCache(data, { cachedAt });
|
|
21586
21824
|
const { messages } = data;
|
|
21825
|
+
fireEvent('v3.message.didUpdate', { messages });
|
|
21587
21826
|
return {
|
|
21588
21827
|
data: messages.find(message => message.messageId === messageId),
|
|
21589
21828
|
cachedAt,
|
|
@@ -21643,7 +21882,7 @@ const deleteMessage = async (messageId) => {
|
|
|
21643
21882
|
// API-FIX: This endpoint has not been implemented yet.
|
|
21644
21883
|
await client.http.delete(`/api/v3/messages/${encodeURIComponent(messageId)}`);
|
|
21645
21884
|
const deleted = await getMessage(messageId);
|
|
21646
|
-
|
|
21885
|
+
fireEvent('v3.message.didDelete', { messages: [deleted.data] });
|
|
21647
21886
|
return deleted.data;
|
|
21648
21887
|
};
|
|
21649
21888
|
/**
|
|
@@ -21830,6 +22069,7 @@ getPosts.locally = (postIds) => {
|
|
|
21830
22069
|
const getPost = async (postId) => {
|
|
21831
22070
|
const client = getActiveClient();
|
|
21832
22071
|
client.log('post/getPost', postId);
|
|
22072
|
+
isInTombstone('post', postId);
|
|
21833
22073
|
let data;
|
|
21834
22074
|
try {
|
|
21835
22075
|
// API-FIX: endpoint should not be /list, parameters should be querystring.
|
|
@@ -21837,8 +22077,8 @@ const getPost = async (postId) => {
|
|
|
21837
22077
|
data = response.data;
|
|
21838
22078
|
}
|
|
21839
22079
|
catch (error) {
|
|
21840
|
-
if ((error === null || error === void 0 ? void 0 : error.code)
|
|
21841
|
-
|
|
22080
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
22081
|
+
pushToTombstone('post', postId);
|
|
21842
22082
|
}
|
|
21843
22083
|
throw error;
|
|
21844
22084
|
}
|
|
@@ -22618,7 +22858,7 @@ const deletePost = async (postId, permanent = false) => {
|
|
|
22618
22858
|
fireEvent('post.deleted', { posts: [deleted] });
|
|
22619
22859
|
if (permanent) {
|
|
22620
22860
|
setTimeout(() => {
|
|
22621
|
-
|
|
22861
|
+
pushToTombstone('post', postId);
|
|
22622
22862
|
}, 0);
|
|
22623
22863
|
}
|
|
22624
22864
|
else {
|
|
@@ -23014,17 +23254,6 @@ const deleteComment = async (commentId, permanent = false) => {
|
|
|
23014
23254
|
return deleted;
|
|
23015
23255
|
};
|
|
23016
23256
|
|
|
23017
|
-
/** @hidden */
|
|
23018
|
-
const fetchReference = async (referenceType, referenceId) => {
|
|
23019
|
-
if (referenceType === 'message')
|
|
23020
|
-
return getMessage(referenceId);
|
|
23021
|
-
if (referenceType === 'post')
|
|
23022
|
-
return getPost(referenceId);
|
|
23023
|
-
if (referenceType === 'comment')
|
|
23024
|
-
return getComment(referenceId);
|
|
23025
|
-
throw new Error(`Incorrect referenceType: ${referenceType}`);
|
|
23026
|
-
};
|
|
23027
|
-
|
|
23028
23257
|
/** @hidden */
|
|
23029
23258
|
const preparePayloadForCache = (event, payload) => {
|
|
23030
23259
|
var _a, _b;
|
|
@@ -23112,7 +23341,6 @@ const prepareMessagePayloadForCache = (payload) => {
|
|
|
23112
23341
|
* @async
|
|
23113
23342
|
* */
|
|
23114
23343
|
const addReaction = async (referenceType, referenceId, reactionName) => {
|
|
23115
|
-
var _a, _b;
|
|
23116
23344
|
const client = getActiveClient();
|
|
23117
23345
|
client.log('reaction/createReaction', {
|
|
23118
23346
|
referenceId,
|
|
@@ -23124,9 +23352,7 @@ const addReaction = async (referenceType, referenceId, reactionName) => {
|
|
|
23124
23352
|
referenceType,
|
|
23125
23353
|
reactionName,
|
|
23126
23354
|
});
|
|
23127
|
-
|
|
23128
|
-
dispatchReactable(referenceType, model.data);
|
|
23129
|
-
return (_b = (_a = model.data.myReactions) === null || _a === void 0 ? void 0 : _a.includes(reactionName)) !== null && _b !== void 0 ? _b : false;
|
|
23355
|
+
return true;
|
|
23130
23356
|
};
|
|
23131
23357
|
/**
|
|
23132
23358
|
* ```js
|
|
@@ -23183,7 +23409,6 @@ addReaction.optimistically = (referenceType, referenceId, reactionName) => {
|
|
|
23183
23409
|
* @async
|
|
23184
23410
|
* */
|
|
23185
23411
|
const removeReaction = async (referenceType, referenceId, reactionName) => {
|
|
23186
|
-
var _a, _b;
|
|
23187
23412
|
const client = getActiveClient();
|
|
23188
23413
|
client.log('reaction/removeReaction', {
|
|
23189
23414
|
referenceId,
|
|
@@ -23193,9 +23418,7 @@ const removeReaction = async (referenceType, referenceId, reactionName) => {
|
|
|
23193
23418
|
await client.http.delete(`/api/v2/reactions`, {
|
|
23194
23419
|
data: { referenceId, referenceType, reactionName },
|
|
23195
23420
|
});
|
|
23196
|
-
|
|
23197
|
-
dispatchReactable(referenceType, model.data);
|
|
23198
|
-
return (_b = !((_a = model.data.myReactions) === null || _a === void 0 ? void 0 : _a.includes(reactionName))) !== null && _b !== void 0 ? _b : false;
|
|
23421
|
+
return true;
|
|
23199
23422
|
};
|
|
23200
23423
|
/**
|
|
23201
23424
|
* ```js
|
|
@@ -23872,10 +24095,6 @@ const onReactorRemoved = (referenceType, referenceId, callback) => {
|
|
|
23872
24095
|
return createEventSubscriber(client, 'comment.removeReaction', 'comment.removeReaction', filter);
|
|
23873
24096
|
};
|
|
23874
24097
|
|
|
23875
|
-
const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
|
|
23876
|
-
const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
|
|
23877
|
-
const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
|
|
23878
|
-
|
|
23879
24098
|
/**
|
|
23880
24099
|
* ```js
|
|
23881
24100
|
* import { liveReactions } from '@amityco/ts-sdk'
|
|
@@ -24152,9 +24371,24 @@ const queryChannels = async (query) => {
|
|
|
24152
24371
|
* @category Channel API
|
|
24153
24372
|
*/
|
|
24154
24373
|
queryChannels.locally = (query) => {
|
|
24374
|
+
var _a, _b;
|
|
24155
24375
|
const client = getActiveClient();
|
|
24156
24376
|
client.log('channel/queryChannels.locally', query);
|
|
24157
|
-
|
|
24377
|
+
const _c = query !== null && query !== void 0 ? query : {}, { page = { limit: 10 } } = _c, params = __rest(_c, ["page"]);
|
|
24378
|
+
const cacheKey = ['channel', 'query', Object.assign(Object.assign({}, params), { options: Object.assign({}, page) })];
|
|
24379
|
+
const { data, cachedAt } = (_a = pullFromCache(cacheKey)) !== null && _a !== void 0 ? _a : {};
|
|
24380
|
+
if (!(data === null || data === void 0 ? void 0 : data.channels.length))
|
|
24381
|
+
return;
|
|
24382
|
+
const channels = data.channels
|
|
24383
|
+
// ck -> cacheKey, abbrevated to avoid confusion from the above cache key
|
|
24384
|
+
.map(ck => pullFromCache(['channel', 'get', ck]))
|
|
24385
|
+
.filter(Boolean)
|
|
24386
|
+
.map(({ data }) => data);
|
|
24387
|
+
const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
|
|
24388
|
+
const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
|
|
24389
|
+
return channels.length === ((_b = data === null || data === void 0 ? void 0 : data.channels) === null || _b === void 0 ? void 0 : _b.length)
|
|
24390
|
+
? { data: channels, cachedAt, prevPage, nextPage }
|
|
24391
|
+
: undefined;
|
|
24158
24392
|
};
|
|
24159
24393
|
|
|
24160
24394
|
/**
|
|
@@ -24237,9 +24471,18 @@ getChannels.locally = (channelIds) => {
|
|
|
24237
24471
|
const getChannel = async (channelId) => {
|
|
24238
24472
|
const client = getActiveClient();
|
|
24239
24473
|
client.log('channel/getChannel', channelId);
|
|
24240
|
-
|
|
24241
|
-
|
|
24242
|
-
|
|
24474
|
+
isInTombstone('channel', channelId);
|
|
24475
|
+
let data;
|
|
24476
|
+
try {
|
|
24477
|
+
const { data: payload } = await client.http.get(`/api/v3/channels/${encodeURIComponent(channelId)}`);
|
|
24478
|
+
data = prepareChannelPayload(payload);
|
|
24479
|
+
}
|
|
24480
|
+
catch (error) {
|
|
24481
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
24482
|
+
pushToTombstone('channel', channelId);
|
|
24483
|
+
}
|
|
24484
|
+
throw error;
|
|
24485
|
+
}
|
|
24243
24486
|
const cachedAt = client.cache && Date.now();
|
|
24244
24487
|
if (client.cache)
|
|
24245
24488
|
ingestInCache(data, { cachedAt });
|
|
@@ -24431,8 +24674,8 @@ const leaveChannel = async (channelId) => {
|
|
|
24431
24674
|
const queryChannelMembers = async (query) => {
|
|
24432
24675
|
const client = getActiveClient();
|
|
24433
24676
|
client.log('channel/queryChannelMembers', query);
|
|
24434
|
-
const _a = query !== null && query !== void 0 ? query : {}, { page
|
|
24435
|
-
const { data: queryPayload } = await client.http.get(`/api/v4/channels/${encodeURIComponent(channelId)}/users`, {
|
|
24677
|
+
const _a = query !== null && query !== void 0 ? query : {}, { page = { limit: 10 } } = _a, params = __rest(_a, ["page"]);
|
|
24678
|
+
const { data: queryPayload } = await client.http.get(`/api/v4/channels/${encodeURIComponent(params.channelId)}/users`, {
|
|
24436
24679
|
params: Object.assign(Object.assign({}, params), { options: {
|
|
24437
24680
|
token: toToken(page, 'skiplimit'),
|
|
24438
24681
|
} }),
|
|
@@ -24443,6 +24686,15 @@ const queryChannelMembers = async (query) => {
|
|
|
24443
24686
|
const cachedAt = client.cache && Date.now();
|
|
24444
24687
|
if (client.cache) {
|
|
24445
24688
|
ingestInCache(data);
|
|
24689
|
+
const cacheKey = [
|
|
24690
|
+
'channelUsers',
|
|
24691
|
+
'query',
|
|
24692
|
+
Object.assign(Object.assign({}, params), { options: Object.assign({}, page) }),
|
|
24693
|
+
];
|
|
24694
|
+
pushToCache(cacheKey, {
|
|
24695
|
+
channelUsers: channelUsers.map(({ channelId, userId }) => getResolver('channelUsers')({ channelId, userId })),
|
|
24696
|
+
paging,
|
|
24697
|
+
});
|
|
24446
24698
|
}
|
|
24447
24699
|
const nextPage = toPage(paging.next);
|
|
24448
24700
|
const prevPage = toPage(paging.previous);
|
|
@@ -24462,9 +24714,30 @@ const queryChannelMembers = async (query) => {
|
|
|
24462
24714
|
* @category Post API
|
|
24463
24715
|
*/
|
|
24464
24716
|
queryChannelMembers.locally = (query) => {
|
|
24717
|
+
var _a, _b;
|
|
24465
24718
|
const client = getActiveClient();
|
|
24466
|
-
client.log('channel/queryChannelMembers', query);
|
|
24467
|
-
|
|
24719
|
+
client.log('channel/queryChannelMembers.locally', query);
|
|
24720
|
+
if (!client.cache)
|
|
24721
|
+
return;
|
|
24722
|
+
const { page = { limit: 10 } } = query, params = __rest(query, ["page"]);
|
|
24723
|
+
const cacheKey = [
|
|
24724
|
+
'channelUsers',
|
|
24725
|
+
'query',
|
|
24726
|
+
Object.assign(Object.assign({}, params), { options: Object.assign({}, page) }),
|
|
24727
|
+
];
|
|
24728
|
+
const { data, cachedAt } = (_a = pullFromCache(cacheKey)) !== null && _a !== void 0 ? _a : {};
|
|
24729
|
+
if (!(data === null || data === void 0 ? void 0 : data.channelUsers.length))
|
|
24730
|
+
return;
|
|
24731
|
+
const channelUsers = data.channelUsers
|
|
24732
|
+
// ck -> cacheKey, abbrevated to avoid confusion from the above cache key
|
|
24733
|
+
.map(ck => pullFromCache(['channelUsers', 'get', ck]))
|
|
24734
|
+
.filter(Boolean)
|
|
24735
|
+
.map(({ data }) => data);
|
|
24736
|
+
const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
|
|
24737
|
+
const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
|
|
24738
|
+
return channelUsers.length === ((_b = data === null || data === void 0 ? void 0 : data.channelUsers) === null || _b === void 0 ? void 0 : _b.length)
|
|
24739
|
+
? { data: channelUsers, cachedAt, prevPage, nextPage }
|
|
24740
|
+
: undefined;
|
|
24468
24741
|
};
|
|
24469
24742
|
|
|
24470
24743
|
/**
|
|
@@ -24489,7 +24762,10 @@ const addChannelMembers = async (channelId, userIds) => {
|
|
|
24489
24762
|
const data = prepareChannelPayload(payload);
|
|
24490
24763
|
if (client.cache)
|
|
24491
24764
|
ingestInCache(data);
|
|
24492
|
-
|
|
24765
|
+
/*
|
|
24766
|
+
* should fire event for each user that was added
|
|
24767
|
+
*/
|
|
24768
|
+
userIds.forEach(id => fireEvent('v3.channel.didAddUsers', Object.assign(Object.assign({}, data), { channelUsers: data.channelUsers.filter(u => u.userId === id) })));
|
|
24493
24769
|
const { channelUsers } = data;
|
|
24494
24770
|
return !!channelUsers.find(channelUser => channelUser.channelId === channelId && channelUser.membership === 'member');
|
|
24495
24771
|
};
|
|
@@ -24812,6 +25088,56 @@ const onChannelMemberRemoved = (callback) => {
|
|
|
24812
25088
|
return createEventSubscriber(client, 'onChannelMemberRemoved', 'v3.channel.didRemoveUsers', filter);
|
|
24813
25089
|
};
|
|
24814
25090
|
|
|
25091
|
+
/**
|
|
25092
|
+
* ```js
|
|
25093
|
+
* import { onChannelMemberBanned } from '@amityco/ts-sdk'
|
|
25094
|
+
* const dispose = onChannelMemberBanned((channel, member) => {
|
|
25095
|
+
* // ...
|
|
25096
|
+
* })
|
|
25097
|
+
* ```
|
|
25098
|
+
*
|
|
25099
|
+
* Fired when any {@link Amity.User} has been banned from any {@link Amity.Channel}
|
|
25100
|
+
*
|
|
25101
|
+
* @param callback The function to call when the event was fired
|
|
25102
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
25103
|
+
*
|
|
25104
|
+
* @category Channel Events
|
|
25105
|
+
*/
|
|
25106
|
+
const onChannelMemberBanned = (callback) => {
|
|
25107
|
+
const client = getActiveClient();
|
|
25108
|
+
const filter = (payload) => {
|
|
25109
|
+
const data = prepareChannelPayload(payload);
|
|
25110
|
+
ingestInCache(data);
|
|
25111
|
+
callback(data.channels[0], data.channelUsers.find(cu => cu.membership === 'banned'));
|
|
25112
|
+
};
|
|
25113
|
+
return createEventSubscriber(client, 'onChannelMemberBanned', 'v3.channel.didBan', filter);
|
|
25114
|
+
};
|
|
25115
|
+
|
|
25116
|
+
/**
|
|
25117
|
+
* ```js
|
|
25118
|
+
* import { onChannelMemberUnbanned } from '@amityco/ts-sdk'
|
|
25119
|
+
* const dispose = onChannelMemberUnbanned((channel, member) => {
|
|
25120
|
+
* // ...
|
|
25121
|
+
* })
|
|
25122
|
+
* ```
|
|
25123
|
+
*
|
|
25124
|
+
* Fired when any {@link Amity.User} has been unbanned from any {@link Amity.Channel}
|
|
25125
|
+
*
|
|
25126
|
+
* @param callback The function to call when the event was fired
|
|
25127
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
25128
|
+
*
|
|
25129
|
+
* @category Channel Events
|
|
25130
|
+
*/
|
|
25131
|
+
const onChannelMemberUnbanned = (callback) => {
|
|
25132
|
+
const client = getActiveClient();
|
|
25133
|
+
const filter = (payload) => {
|
|
25134
|
+
const data = prepareChannelPayload(payload);
|
|
25135
|
+
ingestInCache(data);
|
|
25136
|
+
callback(data.channels[0], data.channelUsers.find(cu => cu.membership === 'none'));
|
|
25137
|
+
};
|
|
25138
|
+
return createEventSubscriber(client, 'onChannelMemberBanned', 'v3.channel.didUnban', filter);
|
|
25139
|
+
};
|
|
25140
|
+
|
|
24815
25141
|
/**
|
|
24816
25142
|
* ```js
|
|
24817
25143
|
* import { observeChannel } from '@amityco/ts-sdk'
|
|
@@ -24906,7 +25232,7 @@ const observeChannels = (callback) => {
|
|
|
24906
25232
|
* @category Channel Live Collection
|
|
24907
25233
|
*/
|
|
24908
25234
|
const liveChannels = (params, callback, config) => {
|
|
24909
|
-
const { log, cache } = getActiveClient();
|
|
25235
|
+
const { log, cache, userId } = getActiveClient();
|
|
24910
25236
|
if (!cache) {
|
|
24911
25237
|
console.log(ENABLE_CACHE_MESSAGE);
|
|
24912
25238
|
}
|
|
@@ -24934,6 +25260,10 @@ const liveChannels = (params, callback, config) => {
|
|
|
24934
25260
|
if (params.excludeTags) {
|
|
24935
25261
|
channels = channels.filter(c => { var _a; return !((_a = c.tags) === null || _a === void 0 ? void 0 : _a.some(t => { var _a; return (_a = params.excludeTags) === null || _a === void 0 ? void 0 : _a.includes(t); })); });
|
|
24936
25262
|
}
|
|
25263
|
+
// userId is required to be able to filter channel by current active user
|
|
25264
|
+
if (params.membership && userId) {
|
|
25265
|
+
channels = filterByChannelMembership(channels, params.membership, userId);
|
|
25266
|
+
}
|
|
24937
25267
|
const sortBy = params.sortBy || 'lastCreated';
|
|
24938
25268
|
if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
|
|
24939
25269
|
channels = channels.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
|
|
@@ -25043,7 +25373,20 @@ const liveChannelMembers = (params, callback, config) => {
|
|
|
25043
25373
|
.filter(Boolean)
|
|
25044
25374
|
.map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
|
|
25045
25375
|
channelMembers = filterByPropEquality(channelMembers, 'roles', params.roles);
|
|
25046
|
-
|
|
25376
|
+
if (params.memberships) {
|
|
25377
|
+
/*
|
|
25378
|
+
* even though membership includes muted as a possible value
|
|
25379
|
+
* when querying the server.
|
|
25380
|
+
* Muted is specified under seperarte property namely isMuted
|
|
25381
|
+
* Hence why I've seperately checked for it's equality
|
|
25382
|
+
*/
|
|
25383
|
+
if (params.memberships.some(m => ['member', 'banned'].includes(m))) {
|
|
25384
|
+
channelMembers = filterByPropInclusion(channelMembers, 'membership', params.memberships);
|
|
25385
|
+
}
|
|
25386
|
+
if (params.memberships.includes('muted')) {
|
|
25387
|
+
channelMembers = filterByPropEquality(channelMembers, 'isMuted', true);
|
|
25388
|
+
}
|
|
25389
|
+
}
|
|
25047
25390
|
if (params.search) {
|
|
25048
25391
|
const containsMatcher = new RegExp(params.search);
|
|
25049
25392
|
channelMembers = channelMembers.filter(m => m.userId.match(containsMatcher));
|
|
@@ -25071,7 +25414,7 @@ const liveChannelMembers = (params, callback, config) => {
|
|
|
25071
25414
|
if (action === 'onMemberAdded') {
|
|
25072
25415
|
collection.data = [...new Set([channelMemberCacheId, ...collection.data])];
|
|
25073
25416
|
}
|
|
25074
|
-
|
|
25417
|
+
if (action === 'onMemberRemoved') {
|
|
25075
25418
|
collection.data = collection.data.filter(m => m !== channelMemberCacheId);
|
|
25076
25419
|
}
|
|
25077
25420
|
pushToCache(cacheKey, collection);
|
|
@@ -25098,7 +25441,7 @@ const liveChannelMembers = (params, callback, config) => {
|
|
|
25098
25441
|
responder(data);
|
|
25099
25442
|
}, queryOptions(policy));
|
|
25100
25443
|
};
|
|
25101
|
-
disposers.push(onChannelMemberAdded((_, member) => realtimeRouter(member, 'onMemberAdded')), onChannelMemberRemoved((_, member) => realtimeRouter(member, 'onMemberRemoved')));
|
|
25444
|
+
disposers.push(onChannelMemberAdded((_, member) => realtimeRouter(member, 'onMemberAdded')), onChannelMemberRemoved((_, member) => realtimeRouter(member, 'onMemberRemoved')), onChannelMemberBanned((_, member) => realtimeRouter(member, 'onChannelMemberBanned')), onChannelMemberUnbanned((_, member) => realtimeRouter(member, 'onChannelMemberUnbanned')));
|
|
25102
25445
|
onFetch();
|
|
25103
25446
|
return () => {
|
|
25104
25447
|
log(`liveChannelMembers(tmpid: ${timestamp}) > dispose`);
|
|
@@ -25185,82 +25528,92 @@ const onMessageDeleted = (callback) => {
|
|
|
25185
25528
|
|
|
25186
25529
|
/**
|
|
25187
25530
|
* ```js
|
|
25188
|
-
* import {
|
|
25189
|
-
*
|
|
25190
|
-
*
|
|
25191
|
-
*
|
|
25531
|
+
* import { onMessageFetched } from '@amityco/ts-sdk'
|
|
25532
|
+
* const dispose = onMessageFetched(message => {
|
|
25533
|
+
* // ...
|
|
25534
|
+
* })
|
|
25192
25535
|
* ```
|
|
25193
25536
|
*
|
|
25194
|
-
*
|
|
25537
|
+
* Fired when an {@link Amity.Message} has been fetched
|
|
25195
25538
|
*
|
|
25196
|
-
* @param
|
|
25197
|
-
* @
|
|
25198
|
-
* @param callback the function to call when new data are available
|
|
25199
|
-
* @param policy a query policy option for this observer
|
|
25200
|
-
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the message
|
|
25539
|
+
* @param callback The function to call when the event was fired
|
|
25540
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
25201
25541
|
*
|
|
25202
|
-
* @category Message
|
|
25542
|
+
* @category Message Events
|
|
25203
25543
|
*/
|
|
25204
|
-
const
|
|
25205
|
-
const
|
|
25206
|
-
const
|
|
25207
|
-
|
|
25208
|
-
|
|
25209
|
-
const router = (result, action) => {
|
|
25210
|
-
var _a, _b, _c;
|
|
25211
|
-
// filter function
|
|
25212
|
-
if (((_a = result.data) === null || _a === void 0 ? void 0 : _a.messageId) !== messageId)
|
|
25213
|
-
return;
|
|
25214
|
-
if (callback instanceof Function)
|
|
25215
|
-
return callback(result);
|
|
25216
|
-
if (action !== 'onFetch')
|
|
25217
|
-
(_b = callback.onEvent) === null || _b === void 0 ? void 0 : _b.call(callback, action, result);
|
|
25218
|
-
(_c = callback[action]) === null || _c === void 0 ? void 0 : _c.call(callback, result);
|
|
25219
|
-
};
|
|
25220
|
-
const disposers = [];
|
|
25221
|
-
disposers.push(onMessageUpdated(data => router({ data, loading: false, origin: 'event' }, 'onUpdate')), onMessageDeleted(data => router({ data, loading: false, origin: 'event' }, 'onDelete')));
|
|
25222
|
-
if (policy !== 'no_fetch') {
|
|
25223
|
-
runQuery(createQuery(getMessage, messageId), result => result.data && router(result, 'onFetch'), queryOptions(policy));
|
|
25224
|
-
}
|
|
25225
|
-
return () => {
|
|
25226
|
-
log(`observeMessages(tmpid: ${timestamp}) > dispose`);
|
|
25227
|
-
disposers.forEach(fn => fn());
|
|
25544
|
+
const onMessageFetched = (callback) => {
|
|
25545
|
+
const client = getActiveClient();
|
|
25546
|
+
const filter = (payload) => {
|
|
25547
|
+
ingestInCache(payload);
|
|
25548
|
+
callback(payload.messages[0]);
|
|
25228
25549
|
};
|
|
25550
|
+
return createEventSubscriber(client, 'message/onMessageFetched', 'v3.message.didFetch', filter);
|
|
25229
25551
|
};
|
|
25230
25552
|
|
|
25231
25553
|
/**
|
|
25232
25554
|
* ```js
|
|
25233
|
-
* import {
|
|
25555
|
+
* import { liveMessage } from '@amityco/ts-sdk'
|
|
25234
25556
|
*
|
|
25235
25557
|
* let messages = []
|
|
25236
|
-
* const unsub =
|
|
25558
|
+
* const unsub = liveMessage(messageId, response => merge(messages, response.data))
|
|
25237
25559
|
* ```
|
|
25238
25560
|
*
|
|
25239
|
-
* Observe all
|
|
25561
|
+
* Observe all mutation on a given {@link Amity.Message}
|
|
25240
25562
|
*
|
|
25241
|
-
* @param
|
|
25563
|
+
* @param messageId the ID of the message to observe
|
|
25242
25564
|
* @param callback the function to call when new data are available
|
|
25243
25565
|
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
|
|
25244
25566
|
*
|
|
25245
|
-
* @category Message
|
|
25567
|
+
* @category Message Live Object
|
|
25246
25568
|
*/
|
|
25247
|
-
const
|
|
25248
|
-
const { log } = getActiveClient();
|
|
25569
|
+
const liveMessage = (messageId, callback) => {
|
|
25570
|
+
const { log, cache } = getActiveClient();
|
|
25571
|
+
let message;
|
|
25572
|
+
let isUnsyncedObject = false;
|
|
25573
|
+
if (!cache) {
|
|
25574
|
+
console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
|
|
25575
|
+
}
|
|
25249
25576
|
const timestamp = Date.now();
|
|
25250
|
-
log(`
|
|
25577
|
+
log(`liveMessage(tmpid: ${timestamp}) > listen`);
|
|
25251
25578
|
const disposers = [];
|
|
25252
|
-
const
|
|
25253
|
-
var _a
|
|
25254
|
-
|
|
25579
|
+
const dispatcher = (data) => {
|
|
25580
|
+
var _a;
|
|
25581
|
+
// we check updatedAt to see if the current snapshot is new so
|
|
25582
|
+
// we won't send old data back, only fresh new data
|
|
25583
|
+
if (message && ((_a = data.data) === null || _a === void 0 ? void 0 : _a.updatedAt) === (message === null || message === void 0 ? void 0 : message.updatedAt) && data.origin !== 'server')
|
|
25255
25584
|
return;
|
|
25256
|
-
|
|
25257
|
-
|
|
25258
|
-
(_b = callback.onEvent) === null || _b === void 0 ? void 0 : _b.call(callback, action, message);
|
|
25259
|
-
(_c = callback[action]) === null || _c === void 0 ? void 0 : _c.call(callback, message);
|
|
25585
|
+
callback(data);
|
|
25586
|
+
message = data.data;
|
|
25260
25587
|
};
|
|
25261
|
-
|
|
25588
|
+
const realtimeRouter = (message, action) => {
|
|
25589
|
+
dispatcher({ loading: false, data: message, origin: 'event' });
|
|
25590
|
+
};
|
|
25591
|
+
const onFetch = () => {
|
|
25592
|
+
const query = createQuery(getMessage, messageId, true);
|
|
25593
|
+
runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
|
|
25594
|
+
if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
|
|
25595
|
+
dispatcher({
|
|
25596
|
+
data,
|
|
25597
|
+
origin,
|
|
25598
|
+
loading: false,
|
|
25599
|
+
error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
|
|
25600
|
+
});
|
|
25601
|
+
isUnsyncedObject = true;
|
|
25602
|
+
disposers.forEach(fn => fn());
|
|
25603
|
+
}
|
|
25604
|
+
else if (!isUnsyncedObject) {
|
|
25605
|
+
dispatcher({ loading, data, origin, error });
|
|
25606
|
+
}
|
|
25607
|
+
if (error) {
|
|
25608
|
+
// Terminate observe functionality on error
|
|
25609
|
+
disposers.forEach(fn => fn());
|
|
25610
|
+
}
|
|
25611
|
+
});
|
|
25612
|
+
};
|
|
25613
|
+
disposers.push(onMessageFetched(message => realtimeRouter(message)), onMessageUpdated(message => realtimeRouter(message)), onMessageDeleted(message => realtimeRouter(message)));
|
|
25614
|
+
onFetch();
|
|
25262
25615
|
return () => {
|
|
25263
|
-
log(`
|
|
25616
|
+
log(`liveMessage(tmpid: ${timestamp}) > dispose`);
|
|
25264
25617
|
disposers.forEach(fn => fn());
|
|
25265
25618
|
};
|
|
25266
25619
|
};
|
|
@@ -25349,7 +25702,7 @@ const liveMessages = (params, callback, config) => {
|
|
|
25349
25702
|
responder(data);
|
|
25350
25703
|
}, queryOptions(policy));
|
|
25351
25704
|
};
|
|
25352
|
-
disposers.push(onMessageCreated(message => realtimeRouter(message, 'onCreate')), onMessageDeleted(message => realtimeRouter(message, 'onDelete')), onMessageUpdated(message => realtimeRouter(message, 'onUpdate')));
|
|
25705
|
+
disposers.push(onMessageFetched(message => realtimeRouter(message, 'onFetch')), onMessageCreated(message => realtimeRouter(message, 'onCreate')), onMessageDeleted(message => realtimeRouter(message, 'onDelete')), onMessageUpdated(message => realtimeRouter(message, 'onUpdate')));
|
|
25353
25706
|
onFetch();
|
|
25354
25707
|
return () => {
|
|
25355
25708
|
log(`liveMessages(tmpid: ${timestamp}) > dispose`);
|
|
@@ -25357,6 +25710,89 @@ const liveMessages = (params, callback, config) => {
|
|
|
25357
25710
|
};
|
|
25358
25711
|
};
|
|
25359
25712
|
|
|
25713
|
+
/**
|
|
25714
|
+
* ```js
|
|
25715
|
+
* import { observeMessage } from '@amityco/ts-sdk'
|
|
25716
|
+
*
|
|
25717
|
+
* let message = {}
|
|
25718
|
+
* const unsub = observeMessage(messageId, updated => message = updated)
|
|
25719
|
+
* ```
|
|
25720
|
+
*
|
|
25721
|
+
* Observe all mutations on a {@link Amity.Message} given a single messageId
|
|
25722
|
+
*
|
|
25723
|
+
* @param client the client to observe the message with
|
|
25724
|
+
* @param messageId the ID of the message to observe
|
|
25725
|
+
* @param callback the function to call when new data are available
|
|
25726
|
+
* @param policy a query policy option for this observer
|
|
25727
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the message
|
|
25728
|
+
*
|
|
25729
|
+
* @category Message Observer
|
|
25730
|
+
*/
|
|
25731
|
+
const observeMessage = (messageId, callback, policy = 'cache_then_server') => {
|
|
25732
|
+
const { log } = getActiveClient();
|
|
25733
|
+
const timestamp = Date.now();
|
|
25734
|
+
log(`observeMessage(tmpid: ${timestamp}) > listen`);
|
|
25735
|
+
console.log('observeMessage will be deprecated on 15th November 2022, please use liveMessage instead.');
|
|
25736
|
+
// wrapper function to make sure
|
|
25737
|
+
const router = (result, action) => {
|
|
25738
|
+
var _a, _b, _c;
|
|
25739
|
+
// filter function
|
|
25740
|
+
if (((_a = result.data) === null || _a === void 0 ? void 0 : _a.messageId) !== messageId)
|
|
25741
|
+
return;
|
|
25742
|
+
if (callback instanceof Function)
|
|
25743
|
+
return callback(result);
|
|
25744
|
+
if (action !== 'onFetch')
|
|
25745
|
+
(_b = callback.onEvent) === null || _b === void 0 ? void 0 : _b.call(callback, action, result);
|
|
25746
|
+
(_c = callback[action]) === null || _c === void 0 ? void 0 : _c.call(callback, result);
|
|
25747
|
+
};
|
|
25748
|
+
const disposers = [];
|
|
25749
|
+
disposers.push(onMessageUpdated(data => router({ data, loading: false, origin: 'event' }, 'onUpdate')), onMessageDeleted(data => router({ data, loading: false, origin: 'event' }, 'onDelete')));
|
|
25750
|
+
if (policy !== 'no_fetch') {
|
|
25751
|
+
runQuery(createQuery(getMessage, messageId), result => result.data && router(result, 'onFetch'), queryOptions(policy));
|
|
25752
|
+
}
|
|
25753
|
+
return () => {
|
|
25754
|
+
log(`observeMessages(tmpid: ${timestamp}) > dispose`);
|
|
25755
|
+
disposers.forEach(fn => fn());
|
|
25756
|
+
};
|
|
25757
|
+
};
|
|
25758
|
+
|
|
25759
|
+
/**
|
|
25760
|
+
* ```js
|
|
25761
|
+
* import { observeMessages } from '@amityco/ts-sdk'
|
|
25762
|
+
*
|
|
25763
|
+
* let messages = []
|
|
25764
|
+
* const unsub = observeMessages(channelId, message => merge(messages, message))
|
|
25765
|
+
* ```
|
|
25766
|
+
*
|
|
25767
|
+
* Observe all mutations on a list of {@link Amity.Message} for a given {@link Amity.Channel} object
|
|
25768
|
+
*
|
|
25769
|
+
* @param channelId the ID of the channel where to observe the messages
|
|
25770
|
+
* @param callback the function to call when new data are available
|
|
25771
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
|
|
25772
|
+
*
|
|
25773
|
+
* @category Message Observer
|
|
25774
|
+
*/
|
|
25775
|
+
const observeMessages = (channelId, callback) => {
|
|
25776
|
+
const { log } = getActiveClient();
|
|
25777
|
+
const timestamp = Date.now();
|
|
25778
|
+
log(`observeMessages(tmpid: ${timestamp}) > listen`);
|
|
25779
|
+
const disposers = [];
|
|
25780
|
+
const router = (message, action) => {
|
|
25781
|
+
var _a, _b, _c;
|
|
25782
|
+
if (((_a = message.data) === null || _a === void 0 ? void 0 : _a.channelId) !== channelId)
|
|
25783
|
+
return;
|
|
25784
|
+
if (callback instanceof Function)
|
|
25785
|
+
return callback(message);
|
|
25786
|
+
(_b = callback.onEvent) === null || _b === void 0 ? void 0 : _b.call(callback, action, message);
|
|
25787
|
+
(_c = callback[action]) === null || _c === void 0 ? void 0 : _c.call(callback, message);
|
|
25788
|
+
};
|
|
25789
|
+
disposers.push(onMessageCreated(data => router({ data, loading: false, origin: 'event' }, 'onCreate')), onMessageUpdated(data => router({ data, loading: false, origin: 'event' }, 'onUpdate')), onMessageDeleted(data => router({ data, loading: false, origin: 'event' }, 'onDelete')));
|
|
25790
|
+
return () => {
|
|
25791
|
+
log(`observeMessages(tmpid: ${timestamp}) > dispose`);
|
|
25792
|
+
disposers.forEach(fn => fn());
|
|
25793
|
+
};
|
|
25794
|
+
};
|
|
25795
|
+
|
|
25360
25796
|
const createCommunityEventSubscriber = (event, callback) => {
|
|
25361
25797
|
const client = getActiveClient();
|
|
25362
25798
|
const filter = (payload) => {
|
|
@@ -27539,4 +27975,4 @@ const createUserToken = async (apiKey, apiRegion, params) => {
|
|
|
27539
27975
|
return { accessToken: data.accessToken };
|
|
27540
27976
|
};
|
|
27541
27977
|
|
|
27542
|
-
export { API_REGIONS, CommunityPostSettingMaps, CommunityPostSettings, ContentFeedType, DefaultCommunityPostSetting, FileType, SubscriptionLevels, VERSION$1 as VERSION, VideoResolution, VideoSize, VideoTranscodingStatus, acceptFollower, addChannelMembers, addChannelMembersRole, addCommunityMembers, addCommunityMembersRoles, addReaction, approvePost, backupCache, banChannelMembers, closePoll, connectClient, createChannel, createClient, createComment, createCommunity, createFile, createImage, createMessage, createPoll, createPost, createQuery, createReport, createStream, createUserToken, createVideo, declineFollower, declinePost, deleteChannel, deleteComment, deleteCommunity, deleteFile, deleteMessage, deletePoll, deletePost, deleteReport, deleteStream, disableCache, disconnectClient, disposeStream, dropFromCache, enableCache, fileUrlWithSize, filterByPropEquality, filterByPropInclusion, follow, getActiveClient, getCategory, getChannel, getChannels, getComment, getCommentTopic, getComments, getCommunities, getCommunity, getCommunityTopic, getFeedSettings, getFile, getFollowInfo, getMessage, getMessages, getMyFollowersTopic, getMyFollowingsTopic, getNetworkTopic, getPoll, getPost, getPostTopic, getPosts, getRecommendedCommunities, getRole, getStream, getTopTrendingCommunities, getUser, getUserTopic, getUsers, isAfterBefore, isAfterBeforeRaw, isCachable, isConnected, isFetcher, isFresh, isLocal, isMutator, isOffline, isPaged, isReportedByMe, isSkipLimit, joinChannel, joinCommunity, leaveChannel, leaveCommunity, liveChannelMembers, liveChannels, liveComments, liveFollowers, liveFollowings, liveMessages, livePosts, liveReactions, mergeInCache, observeChannel, observeChannels, observeComment, observeComments, observeCommunity, observeFile, observeFollowInfo, observeFollowers, observeFollowings, observeMessage, observeMessages, observePoll, observePost, observePosts, observeUser, onChannelCreated, onChannelDeleted, onChannelJoined, onChannelLeft, onChannelMemberAdded, onChannelMemberRemoved, onChannelUpdated, onClientBanned, onClientDisconnected, onCommentCreated, onCommentDeleted, onCommentFlagged, onCommentReactionAdded, onCommentReactionRemoved, onCommentUnflagged, onCommentUpdated, onCommunityCreated, onCommunityDeleted, onCommunityJoined, onCommunityLeft, onCommunityUpdated, onCommunityUserAdded, onCommunityUserBanned, onCommunityUserRemoved, onCommunityUserUnbanned, onConnectionError, onFollowInfoUpdated, onFollowRequestAccepted, onFollowRequestCanceled, onFollowRequestDeclined, onFollowerDeleted, onFollowerRequested, onMessageCreated, onMessageDeleted, onMessageUpdated, onPollDeleted, onPollUpdated, onPostApproved, onPostCreated, onPostDeclined, onPostDeleted, onPostFlagged, onPostReactionAdded, onPostReactionRemoved, onPostUnflagged, onPostUpdated, onReactionAdded, onReactionRemoved, onReactorAdded, onReactorRemoved, onStreamRecorded, onStreamStarted, onStreamStopped, onUserDeleted, onUserFlagCleared, onUserFlagged, onUserFollowed, onUserUnflagged, onUserUnfollowed, onUserUpdated, pullFromCache, pushToCache, queryCache, queryCategories, queryChannelMembers, queryChannels, queryComments, queryCommunities, queryCommunityMembers, queryFollowers, queryFollowings, queryGlobalFeed, queryMessages, queryOptions, queryPosts, queryReactions, queryRoles, queryStreams, queryUsers, removeChannelMembers, removeChannelMembersRole, removeCommunityMembers, removeCommunityMembersRoles, removeReaction, restoreCache, runQuery, sortByChannelSegment, sortByDisplayName, sortByFirstCreated, sortByLastActivity, sortByLastCreated, sortBySegmentNumber, subscribeTopic, toPage, toPageRaw, toToken, unbanChannelMembers, unfollow, updateChannel, updateComment, updateCommunity, updateMessage, updatePost, updateStream, updateUser, upsertInCache, votePoll, wipeCache };
|
|
27978
|
+
export { API_REGIONS, CommunityPostSettingMaps, CommunityPostSettings, ContentFeedType, DefaultCommunityPostSetting, FileType, MessageContentType, PostContentType, SubscriptionLevels, VERSION$1 as VERSION, VideoResolution, VideoSize, VideoTranscodingStatus, acceptFollower, addChannelMembers, addChannelMembersRole, addCommunityMembers, addCommunityMembersRoles, addReaction, approvePost, backupCache, banChannelMembers, closePoll, connectClient, createChannel, createClient, createComment, createCommunity, createFile, createImage, createMessage, createPoll, createPost, createQuery, createReport, createStream, createUserToken, createVideo, declineFollower, declinePost, deleteChannel, deleteComment, deleteCommunity, deleteFile, deleteMessage, deletePoll, deletePost, deleteReport, deleteStream, disableCache, disconnectClient, disposeStream, dropFromCache, enableCache, fileUrlWithSize, filterByChannelMembership, filterByPropEquality, filterByPropInclusion, follow, getActiveClient, getCategory, getChannel, getChannels, getComment, getCommentTopic, getComments, getCommunities, getCommunity, getCommunityTopic, getFeedSettings, getFile, getFollowInfo, getMessage, getMessages, getMyFollowersTopic, getMyFollowingsTopic, getNetworkTopic, getPoll, getPost, getPostTopic, getPosts, getRecommendedCommunities, getRole, getStream, getTopTrendingCommunities, getUser, getUserTopic, getUsers, isAfterBefore, isAfterBeforeRaw, isCachable, isConnected, isFetcher, isFresh, isLocal, isMutator, isOffline, isPaged, isReportedByMe, isSkipLimit, joinChannel, joinCommunity, leaveChannel, leaveCommunity, liveChannelMembers, liveChannels, liveComments, liveFollowers, liveFollowings, liveMessage, liveMessages, livePosts, liveReactions, liveUser, mergeInCache, observeChannel, observeChannels, observeComment, observeComments, observeCommunity, observeFile, observeFollowInfo, observeFollowers, observeFollowings, observeMessage, observeMessages, observePoll, observePost, observePosts, observeUser, onChannelCreated, onChannelDeleted, onChannelJoined, onChannelLeft, onChannelMemberAdded, onChannelMemberBanned, onChannelMemberRemoved, onChannelMemberUnbanned, onChannelUpdated, onClientBanned, onClientDisconnected, onCommentCreated, onCommentDeleted, onCommentFlagged, onCommentReactionAdded, onCommentReactionRemoved, onCommentUnflagged, onCommentUpdated, onCommunityCreated, onCommunityDeleted, onCommunityJoined, onCommunityLeft, onCommunityUpdated, onCommunityUserAdded, onCommunityUserBanned, onCommunityUserRemoved, onCommunityUserUnbanned, onConnectionError, onFollowInfoUpdated, onFollowRequestAccepted, onFollowRequestCanceled, onFollowRequestDeclined, onFollowerDeleted, onFollowerRequested, onMessageCreated, onMessageDeleted, onMessageFetched, onMessageUpdated, onPollDeleted, onPollUpdated, onPostApproved, onPostCreated, onPostDeclined, onPostDeleted, onPostFlagged, onPostReactionAdded, onPostReactionRemoved, onPostUnflagged, onPostUpdated, onReactionAdded, onReactionRemoved, onReactorAdded, onReactorRemoved, onStreamRecorded, onStreamStarted, onStreamStopped, onUserDeleted, onUserFetched, onUserFlagCleared, onUserFlagged, onUserFollowed, onUserUnflagged, onUserUnfollowed, onUserUpdated, pullFromCache, pushToCache, queryCache, queryCategories, queryChannelMembers, queryChannels, queryComments, queryCommunities, queryCommunityMembers, queryFollowers, queryFollowings, queryGlobalFeed, queryMessages, queryOptions, queryPosts, queryReactions, queryRoles, queryStreams, queryUsers, removeChannelMembers, removeChannelMembersRole, removeCommunityMembers, removeCommunityMembersRoles, removeReaction, restoreCache, runQuery, sortByChannelSegment, sortByDisplayName, sortByFirstCreated, sortByLastActivity, sortByLastCreated, sortBySegmentNumber, subscribeTopic, toPage, toPageRaw, toToken, unbanChannelMembers, unfollow, updateChannel, updateComment, updateCommunity, updateMessage, updatePost, updateStream, updateUser, upsertInCache, votePoll, wipeCache };
|