@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.cjs.js
CHANGED
|
@@ -3,20 +3,22 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var jsBase64 = require('js-base64');
|
|
6
|
-
var mitt = require('mitt');
|
|
7
6
|
var AsyncStorage = require('@react-native-async-storage/async-storage');
|
|
7
|
+
var mitt = require('mitt');
|
|
8
8
|
var debug = require('debug');
|
|
9
9
|
var axios = require('axios');
|
|
10
|
+
var qs = require('qs');
|
|
10
11
|
var HttpAgent = require('agentkeepalive');
|
|
11
12
|
var io = require('socket.io-client');
|
|
12
13
|
var nativeIdGenerator = require('react-native-uuid');
|
|
13
14
|
|
|
14
15
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
15
16
|
|
|
16
|
-
var mitt__default = /*#__PURE__*/_interopDefaultLegacy(mitt);
|
|
17
17
|
var AsyncStorage__default = /*#__PURE__*/_interopDefaultLegacy(AsyncStorage);
|
|
18
|
+
var mitt__default = /*#__PURE__*/_interopDefaultLegacy(mitt);
|
|
18
19
|
var debug__default = /*#__PURE__*/_interopDefaultLegacy(debug);
|
|
19
20
|
var axios__default = /*#__PURE__*/_interopDefaultLegacy(axios);
|
|
21
|
+
var qs__default = /*#__PURE__*/_interopDefaultLegacy(qs);
|
|
20
22
|
var HttpAgent__default = /*#__PURE__*/_interopDefaultLegacy(HttpAgent);
|
|
21
23
|
var io__default = /*#__PURE__*/_interopDefaultLegacy(io);
|
|
22
24
|
var nativeIdGenerator__default = /*#__PURE__*/_interopDefaultLegacy(nativeIdGenerator);
|
|
@@ -75,6 +77,24 @@ const VideoSize = Object.freeze({
|
|
|
75
77
|
ORIGINAL: 'original',
|
|
76
78
|
});
|
|
77
79
|
|
|
80
|
+
const MessageContentType = Object.freeze({
|
|
81
|
+
TEXT: 'text',
|
|
82
|
+
IMAGE: 'image',
|
|
83
|
+
FILE: 'file',
|
|
84
|
+
VIDEO: 'video',
|
|
85
|
+
AUDIO: 'audio',
|
|
86
|
+
CUSTOM: 'custom',
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const PostContentType = Object.freeze({
|
|
90
|
+
TEXT: 'text',
|
|
91
|
+
IMAGE: 'image',
|
|
92
|
+
FILE: 'file',
|
|
93
|
+
VIDEO: 'video',
|
|
94
|
+
LIVESTREAM: 'liveStream',
|
|
95
|
+
POLL: 'poll',
|
|
96
|
+
});
|
|
97
|
+
|
|
78
98
|
var _a$1;
|
|
79
99
|
/* eslint-disable no-undef */
|
|
80
100
|
const theGlobal =
|
|
@@ -350,6 +370,78 @@ const PAYLOAD2MODEL = {
|
|
|
350
370
|
followCounts: 'followCount',
|
|
351
371
|
};
|
|
352
372
|
|
|
373
|
+
// cache constants
|
|
374
|
+
const CACHE_KEY_GET = 'get';
|
|
375
|
+
const CACHE_KEY_TOMBSTONE = 'dead';
|
|
376
|
+
const CACHE_LIFESPAN = 1 * 60 * 1000; // 1 minute
|
|
377
|
+
const CACHE_LIFESPAN_TOMBSTONE = 3 * 60 * 1000; // 3 minutes
|
|
378
|
+
/**
|
|
379
|
+
* Shallow-clones an object and sort its keys
|
|
380
|
+
*
|
|
381
|
+
* @param source a plain object to clone
|
|
382
|
+
* @returns a clone of source, with keys sorted with default javascript sorting
|
|
383
|
+
*
|
|
384
|
+
* @category Cache
|
|
385
|
+
* @hidden
|
|
386
|
+
*/
|
|
387
|
+
const normalize = (source) => Object.keys(source)
|
|
388
|
+
.sort()
|
|
389
|
+
.reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: source[key] })), {});
|
|
390
|
+
/**
|
|
391
|
+
* Encodes a given {@link Amity.CacheKey} to a plain string
|
|
392
|
+
*
|
|
393
|
+
* @param key the key to encode
|
|
394
|
+
* @returns an encoded string
|
|
395
|
+
*
|
|
396
|
+
* @category Cache
|
|
397
|
+
* @hidden
|
|
398
|
+
*/
|
|
399
|
+
const encodeKey = (key) => JSON.stringify(key, (_, val) => (typeof val === 'object' ? normalize(val) : val));
|
|
400
|
+
/**
|
|
401
|
+
* Decodes a string back into a {@link Amity.CacheKey}
|
|
402
|
+
|
|
403
|
+
*
|
|
404
|
+
* @param key the string key to decode
|
|
405
|
+
* @returns a plain Amity.CacheKey object.
|
|
406
|
+
*
|
|
407
|
+
* @category Cache
|
|
408
|
+
* @hidden
|
|
409
|
+
*/
|
|
410
|
+
const decodeKey = (key) => JSON.parse(key);
|
|
411
|
+
/**
|
|
412
|
+
* Performs a recursive partial deep equal check on two objects.
|
|
413
|
+
*
|
|
414
|
+
* @param predicate the reference object containing the partial information
|
|
415
|
+
* @param candidate the object to check against
|
|
416
|
+
* @returns true if the candidate contains all the values of the predicate
|
|
417
|
+
*
|
|
418
|
+
* @category Cache
|
|
419
|
+
*/
|
|
420
|
+
const partialMatch = (predicate, candidate) => {
|
|
421
|
+
if (predicate === candidate)
|
|
422
|
+
return true;
|
|
423
|
+
// if one or the other is nullish, there can't be equality
|
|
424
|
+
if (!predicate || !candidate)
|
|
425
|
+
return false;
|
|
426
|
+
// we only perform recursive check on objects
|
|
427
|
+
if (typeof predicate !== 'object') {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
// recursively call for partial match based on the predicate
|
|
431
|
+
return Object.keys(predicate).every(key => partialMatch(predicate[key], candidate[key]));
|
|
432
|
+
};
|
|
433
|
+
/**
|
|
434
|
+
* checks if passed error code is included in
|
|
435
|
+
* Tombstone errors list
|
|
436
|
+
*
|
|
437
|
+
* @param errorCode as {@link Amity.ServerError}
|
|
438
|
+
* @returns success boolean if the given errorCode
|
|
439
|
+
* is included in Tombstone errors list
|
|
440
|
+
*
|
|
441
|
+
* @category Cache
|
|
442
|
+
*/
|
|
443
|
+
const checkIfShouldGoesToTombstone = (errorCode) => [400400 /* Amity.ServerError.ITEM_NOT_FOUND */, 400300 /* Amity.ServerError.FORBIDDEN */].includes(errorCode);
|
|
444
|
+
|
|
353
445
|
/* eslint-disable no-use-before-define */
|
|
354
446
|
/**
|
|
355
447
|
* Type guard to check and cast that a given async function is has the ".locally" property
|
|
@@ -408,7 +500,7 @@ const isLocal = (model) => {
|
|
|
408
500
|
*
|
|
409
501
|
* @hidden
|
|
410
502
|
*/
|
|
411
|
-
const isFresh = (model, lifeSpan =
|
|
503
|
+
const isFresh = (model, lifeSpan = CACHE_LIFESPAN) => {
|
|
412
504
|
var _a;
|
|
413
505
|
return Date.now() - ((_a = model === null || model === void 0 ? void 0 : model.cachedAt) !== null && _a !== void 0 ? _a : 0) <= lifeSpan;
|
|
414
506
|
};
|
|
@@ -442,12 +534,10 @@ const createQuery = (func, ...args) => ({ func, args });
|
|
|
442
534
|
*
|
|
443
535
|
* @category Query
|
|
444
536
|
*/
|
|
445
|
-
const queryOptions = (policy, lifeSpan =
|
|
537
|
+
const queryOptions = (policy, lifeSpan = CACHE_LIFESPAN) => {
|
|
446
538
|
if (policy === 'cache_only')
|
|
447
539
|
return { lifeSpan: Infinity };
|
|
448
|
-
|
|
449
|
-
return { lifeSpan: 0 };
|
|
450
|
-
return { lifeSpan };
|
|
540
|
+
return { lifeSpan: lifeSpan < CACHE_LIFESPAN ? CACHE_LIFESPAN : lifeSpan };
|
|
451
541
|
};
|
|
452
542
|
/**
|
|
453
543
|
* ```js
|
|
@@ -468,8 +558,9 @@ const queryOptions = (policy, lifeSpan = 2 * 60 * 1000) => {
|
|
|
468
558
|
*/
|
|
469
559
|
const runQuery = ({ func, args }, callback, options = queryOptions('cache_then_server')) => {
|
|
470
560
|
let local;
|
|
561
|
+
const { lifeSpan } = queryOptions('cache_then_server', options.lifeSpan);
|
|
471
562
|
// offline first
|
|
472
|
-
if (isOffline(func)
|
|
563
|
+
if (isOffline(func)) {
|
|
473
564
|
try {
|
|
474
565
|
local = isMutator(func) ? func.optimistically(...args) : func.locally(...args);
|
|
475
566
|
}
|
|
@@ -480,7 +571,7 @@ const runQuery = ({ func, args }, callback, options = queryOptions('cache_then_s
|
|
|
480
571
|
error,
|
|
481
572
|
}));
|
|
482
573
|
}
|
|
483
|
-
const shouldAbort = isCachable(local) && isFresh(local,
|
|
574
|
+
const shouldAbort = isCachable(local) && isFresh(local, lifeSpan);
|
|
484
575
|
callback === null || callback === void 0 ? void 0 : callback(createSnapshot(local, {
|
|
485
576
|
origin: 'local',
|
|
486
577
|
loading: !(isFetcher(func) && shouldAbort),
|
|
@@ -547,54 +638,6 @@ function createSnapshot(data, options) {
|
|
|
547
638
|
return Object.assign(Object.assign({}, options), { data });
|
|
548
639
|
}
|
|
549
640
|
|
|
550
|
-
// Note:
|
|
551
|
-
// this file should contain a suite of filtering utilities to help the
|
|
552
|
-
// local version of the query functions.
|
|
553
|
-
/**
|
|
554
|
-
* Filter a given collection with strict equality against a param
|
|
555
|
-
*
|
|
556
|
-
* @param collection the collection to filter
|
|
557
|
-
* @param key the key of the collection's items to challenge
|
|
558
|
-
* @param value the expected value
|
|
559
|
-
* @returns a filtered collection with items only matching the criteria
|
|
560
|
-
*
|
|
561
|
-
* @hidden
|
|
562
|
-
*/
|
|
563
|
-
const filterByPropEquality = (collection, key, value) => (value !== undefined ? collection.filter(item => item[key] === value) : collection);
|
|
564
|
-
const filterByPropInclusion = (collection, key, value) => (value !== undefined ? collection.filter(item => value.includes(item[key])) : collection);
|
|
565
|
-
|
|
566
|
-
// Note:
|
|
567
|
-
// this file should contain a suite of sorting utilities to help the
|
|
568
|
-
// local version of the query functions.
|
|
569
|
-
/**
|
|
570
|
-
* Alphabetic sorting of objects having a displayName
|
|
571
|
-
*/
|
|
572
|
-
const sortByDisplayName = ({ displayName: a }, { displayName: b }) => {
|
|
573
|
-
if (a === b)
|
|
574
|
-
return 0;
|
|
575
|
-
return a < b ? -1 : 1;
|
|
576
|
-
};
|
|
577
|
-
/**
|
|
578
|
-
* Sorting a collection by their apparition order (oldest first)
|
|
579
|
-
*/
|
|
580
|
-
const sortByChannelSegment = ({ channelSegment: a }, { channelSegment: b }) => a - b;
|
|
581
|
-
/**
|
|
582
|
-
* Sorting a collection by their apparition order (oldest first)
|
|
583
|
-
*/
|
|
584
|
-
const sortBySegmentNumber = ({ segmentNumber: a }, { segmentNumber: b }) => a - b;
|
|
585
|
-
/**
|
|
586
|
-
* Sorting a collection by its oldest items
|
|
587
|
-
*/
|
|
588
|
-
const sortByFirstCreated = ({ createdAt: a }, { createdAt: b }) => new Date(a).valueOf() - new Date(b).valueOf();
|
|
589
|
-
/**
|
|
590
|
-
* Sorting a collection by its newest items
|
|
591
|
-
*/
|
|
592
|
-
const sortByLastCreated = ({ createdAt: a }, { createdAt: b }) => new Date(b).valueOf() - new Date(a).valueOf();
|
|
593
|
-
/**
|
|
594
|
-
* Sorting a collection by the items with most recent activity
|
|
595
|
-
*/
|
|
596
|
-
const sortByLastActivity = ({ lastActivity: a }, { lastActivity: b }) => new Date(b).valueOf() - new Date(a).valueOf();
|
|
597
|
-
|
|
598
641
|
/* eslint-disable max-classes-per-file */
|
|
599
642
|
/**
|
|
600
643
|
* Generic ASC error
|
|
@@ -684,265 +727,70 @@ const setActiveClient = (client) => {
|
|
|
684
727
|
activeClient = client;
|
|
685
728
|
};
|
|
686
729
|
|
|
687
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
688
|
-
let tasks = [];
|
|
689
|
-
let timer;
|
|
690
730
|
/**
|
|
691
|
-
*
|
|
731
|
+
* ```js
|
|
732
|
+
* import { enableCache } from '@amityco/ts-sdk'
|
|
733
|
+
* enableCache()
|
|
734
|
+
* ```
|
|
692
735
|
*
|
|
693
|
-
*
|
|
736
|
+
* Adds a new {@link Amity.Cache} object to
|
|
737
|
+
* an {@link Amity.Client} instance
|
|
738
|
+
*
|
|
739
|
+
* @param prevState a previous state of cache instance (useful for SSR)
|
|
740
|
+
* @param persistIf a function to determine if an entry inserted in cache
|
|
741
|
+
* is destined to be also saved in the persistent storage when
|
|
742
|
+
* calling {@link backupCache}
|
|
743
|
+
*
|
|
744
|
+
* @category Cache API
|
|
694
745
|
*/
|
|
695
|
-
const
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
}, 0);
|
|
746
|
+
const enableCache = (prevState = {}, persistIf) => {
|
|
747
|
+
const client = getActiveClient();
|
|
748
|
+
if (client.cache)
|
|
749
|
+
return;
|
|
750
|
+
client.log('cache/api/enableCache');
|
|
751
|
+
client.cache = { data: prevState, persistIf };
|
|
702
752
|
};
|
|
703
753
|
|
|
704
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
705
|
-
// need to sync up the list
|
|
706
|
-
const WS_EVENTS = [
|
|
707
|
-
'disconnected',
|
|
708
|
-
'error',
|
|
709
|
-
'connect_error',
|
|
710
|
-
'reconnect_error',
|
|
711
|
-
'reconnect_failed',
|
|
712
|
-
'v3.channel.didCreate',
|
|
713
|
-
'v3.channel.didUpdate',
|
|
714
|
-
'v3.channel.didDelete',
|
|
715
|
-
'v3.channel.didJoin',
|
|
716
|
-
'v3.channel.didLeave',
|
|
717
|
-
'v3.channel.didAddUsers',
|
|
718
|
-
'v3.channel.didRemoveUsers',
|
|
719
|
-
'v3.channel.didBan',
|
|
720
|
-
'v3.channel.didUnban',
|
|
721
|
-
'v3.message.didCreate',
|
|
722
|
-
'v3.message.didUpdate',
|
|
723
|
-
'v3.message.didDelete',
|
|
724
|
-
];
|
|
725
|
-
const MQTT_EVENTS = [
|
|
726
|
-
'connect',
|
|
727
|
-
'message',
|
|
728
|
-
'disconnect',
|
|
729
|
-
'error',
|
|
730
|
-
'close',
|
|
731
|
-
'end',
|
|
732
|
-
'reconnect',
|
|
733
|
-
];
|
|
734
|
-
/** @hidden */
|
|
735
|
-
const createEventEmitter = () => {
|
|
736
|
-
return mitt__default["default"]();
|
|
737
|
-
};
|
|
738
754
|
/**
|
|
739
|
-
*
|
|
740
|
-
*
|
|
755
|
+
* ```js
|
|
756
|
+
* import { disableCache } from '@amityco/ts-sdk'
|
|
757
|
+
* disableCache()
|
|
758
|
+
* ```
|
|
741
759
|
*
|
|
742
|
-
*
|
|
743
|
-
* @
|
|
760
|
+
* Wipes the existing {@link Amity.Cache} object attached to
|
|
761
|
+
* an {@link Amity.Client} instance
|
|
744
762
|
*
|
|
745
|
-
* @category
|
|
746
|
-
* @hidden
|
|
763
|
+
* @category Cache API
|
|
747
764
|
*/
|
|
748
|
-
const
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
mqttClient.on('message', (topic, payload) => {
|
|
759
|
-
const message = JSON.parse(payload.toString());
|
|
760
|
-
emitter.emit(message.eventType, message.data);
|
|
761
|
-
});
|
|
762
|
-
};
|
|
765
|
+
const disableCache = () => {
|
|
766
|
+
const client = getActiveClient();
|
|
767
|
+
if (!client.cache)
|
|
768
|
+
return;
|
|
769
|
+
client.log('cache/api/disableCache');
|
|
770
|
+
// we do this so that testing if cache is enabled
|
|
771
|
+
// is only `if (client.cache)
|
|
772
|
+
delete client.cache;
|
|
773
|
+
};
|
|
774
|
+
|
|
763
775
|
/**
|
|
764
|
-
*
|
|
776
|
+
* ```js
|
|
777
|
+
* import { restoreCache } from '@amityco/ts-sdk'
|
|
778
|
+
* const success = await restoreCache()
|
|
779
|
+
* ```
|
|
765
780
|
*
|
|
766
|
-
*
|
|
767
|
-
*
|
|
768
|
-
* @param event The websocket event name
|
|
769
|
-
* @param fn A wrapper for the callback.
|
|
770
|
-
* @returns A dispose function to unsubscribe to the event
|
|
781
|
+
* Reads a previously saved {@link Amity.Cache} from a persistent storage,
|
|
782
|
+
* and inserts it into the current {@link Amity.Cache} instance.
|
|
771
783
|
*
|
|
772
|
-
*
|
|
773
|
-
* @
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
};
|
|
783
|
-
emitter.on(event, handler);
|
|
784
|
-
return () => {
|
|
785
|
-
log(`${namespace}(tmpid: ${timestamp}) > dispose`);
|
|
786
|
-
emitter.off(event, handler);
|
|
787
|
-
};
|
|
788
|
-
};
|
|
789
|
-
/**
|
|
790
|
-
* Wrapper around dispatch event
|
|
791
|
-
*
|
|
792
|
-
* @hidden
|
|
793
|
-
*/
|
|
794
|
-
const fireEvent = (event, payload) => {
|
|
795
|
-
const { emitter } = getActiveClient();
|
|
796
|
-
scheduleTask(() => {
|
|
797
|
-
emitter.emit(event, payload);
|
|
798
|
-
});
|
|
799
|
-
};
|
|
800
|
-
|
|
801
|
-
let activeUser = null;
|
|
802
|
-
/**
|
|
803
|
-
* for internal use
|
|
804
|
-
*/
|
|
805
|
-
const getActiveUser = () => {
|
|
806
|
-
if (!activeUser) {
|
|
807
|
-
throw new ASCError('Connect client first', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
|
|
808
|
-
}
|
|
809
|
-
return activeUser;
|
|
810
|
-
};
|
|
811
|
-
const setActiveUser = (user) => {
|
|
812
|
-
activeUser = {
|
|
813
|
-
_id: user._id,
|
|
814
|
-
userId: user.userId,
|
|
815
|
-
path: user.path,
|
|
816
|
-
};
|
|
817
|
-
};
|
|
818
|
-
|
|
819
|
-
exports.SubscriptionLevels = void 0;
|
|
820
|
-
(function (SubscriptionLevels) {
|
|
821
|
-
SubscriptionLevels["COMMUNITY"] = "community";
|
|
822
|
-
SubscriptionLevels["POST"] = "post";
|
|
823
|
-
SubscriptionLevels["COMMENT"] = "comment";
|
|
824
|
-
SubscriptionLevels["POST_AND_COMMENT"] = "post_and_comment";
|
|
825
|
-
SubscriptionLevels["USER"] = "user";
|
|
826
|
-
})(exports.SubscriptionLevels || (exports.SubscriptionLevels = {}));
|
|
827
|
-
const getCommunityUserTopic = (path, level) => {
|
|
828
|
-
switch (level) {
|
|
829
|
-
case 'post':
|
|
830
|
-
return `${path}/post/+`;
|
|
831
|
-
case 'comment':
|
|
832
|
-
return `${path}/post/+/comment/+`;
|
|
833
|
-
case 'post_and_comment':
|
|
834
|
-
return `${path}/post/#`;
|
|
835
|
-
default:
|
|
836
|
-
return path;
|
|
837
|
-
}
|
|
838
|
-
};
|
|
839
|
-
const getCommunityTopic = ({ path }, level = exports.SubscriptionLevels.COMMUNITY) => getCommunityUserTopic(path, level);
|
|
840
|
-
const getUserTopic = ({ path }, level = exports.SubscriptionLevels.USER) => getCommunityUserTopic(level === exports.SubscriptionLevels.USER ? path : path.replace(/^(\w*)/, '$1/social'), level);
|
|
841
|
-
const getPostTopic = ({ path }, level = exports.SubscriptionLevels.POST) => {
|
|
842
|
-
switch (level) {
|
|
843
|
-
case 'comment':
|
|
844
|
-
return `${path}/comment/+`;
|
|
845
|
-
default:
|
|
846
|
-
return path;
|
|
847
|
-
}
|
|
848
|
-
};
|
|
849
|
-
const getCommentTopic = ({ path }) => {
|
|
850
|
-
return path;
|
|
851
|
-
};
|
|
852
|
-
const getMyFollowersTopic = () => {
|
|
853
|
-
const user = getActiveUser();
|
|
854
|
-
const [networkId] = user.path.split('/user/');
|
|
855
|
-
return `${networkId}/membership/${user._id}/+/+`;
|
|
856
|
-
};
|
|
857
|
-
const getMyFollowingsTopic = () => {
|
|
858
|
-
const user = getActiveUser();
|
|
859
|
-
const [networkId] = user.path.split('/user/');
|
|
860
|
-
return `${networkId}/membership/+/${user._id}/+`;
|
|
861
|
-
};
|
|
862
|
-
/** @hidden */
|
|
863
|
-
const getNetworkTopic = () => {
|
|
864
|
-
const user = getActiveUser();
|
|
865
|
-
const [networkId] = user.path.split('/user/');
|
|
866
|
-
return networkId;
|
|
867
|
-
};
|
|
868
|
-
let mqttAccessToken;
|
|
869
|
-
let mqttUserId;
|
|
870
|
-
function subscribeTopic(topic, callback) {
|
|
871
|
-
const { mqtt, emitter, accessToken } = getActiveClient();
|
|
872
|
-
const user = getActiveUser();
|
|
873
|
-
if (mqttAccessToken !== accessToken || mqttUserId !== user._id) {
|
|
874
|
-
mqttAccessToken = accessToken;
|
|
875
|
-
mqttUserId = user._id;
|
|
876
|
-
mqtt.connect({ accessToken: mqttAccessToken, userId: mqttUserId });
|
|
877
|
-
proxyMqttEvents(mqtt, emitter);
|
|
878
|
-
}
|
|
879
|
-
return mqtt.subscribe(topic, callback);
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
/**
|
|
883
|
-
* ```js
|
|
884
|
-
* import { enableCache } from '@amityco/ts-sdk'
|
|
885
|
-
* enableCache()
|
|
886
|
-
* ```
|
|
887
|
-
*
|
|
888
|
-
* Adds a new {@link Amity.Cache} object to
|
|
889
|
-
* an {@link Amity.Client} instance
|
|
890
|
-
*
|
|
891
|
-
* @param prevState a previous state of cache instance (useful for SSR)
|
|
892
|
-
* @param persistIf a function to determine if an entry inserted in cache
|
|
893
|
-
* is destined to be also saved in the persistent storage when
|
|
894
|
-
* calling {@link backupCache}
|
|
895
|
-
*
|
|
896
|
-
* @category Cache API
|
|
897
|
-
*/
|
|
898
|
-
const enableCache = (prevState = {}, persistIf) => {
|
|
899
|
-
const client = getActiveClient();
|
|
900
|
-
if (client.cache)
|
|
901
|
-
return;
|
|
902
|
-
client.log('cache/api/enableCache');
|
|
903
|
-
client.cache = { data: prevState, persistIf };
|
|
904
|
-
};
|
|
905
|
-
|
|
906
|
-
/**
|
|
907
|
-
* ```js
|
|
908
|
-
* import { disableCache } from '@amityco/ts-sdk'
|
|
909
|
-
* disableCache()
|
|
910
|
-
* ```
|
|
911
|
-
*
|
|
912
|
-
* Wipes the existing {@link Amity.Cache} object attached to
|
|
913
|
-
* an {@link Amity.Client} instance
|
|
914
|
-
*
|
|
915
|
-
* @category Cache API
|
|
916
|
-
*/
|
|
917
|
-
const disableCache = () => {
|
|
918
|
-
const client = getActiveClient();
|
|
919
|
-
if (!client.cache)
|
|
920
|
-
return;
|
|
921
|
-
client.log('cache/api/disableCache');
|
|
922
|
-
// we do this so that testing if cache is enabled
|
|
923
|
-
// is only `if (client.cache)
|
|
924
|
-
delete client.cache;
|
|
925
|
-
};
|
|
926
|
-
|
|
927
|
-
/**
|
|
928
|
-
* ```js
|
|
929
|
-
* import { restoreCache } from '@amityco/ts-sdk'
|
|
930
|
-
* const success = await restoreCache()
|
|
931
|
-
* ```
|
|
932
|
-
*
|
|
933
|
-
* Reads a previously saved {@link Amity.Cache} from a persistent storage,
|
|
934
|
-
* and inserts it into the current {@link Amity.Cache} instance.
|
|
935
|
-
*
|
|
936
|
-
* The strategy for persistent storage will depend on the runtime,
|
|
937
|
-
* which is supported by @react-native-async-storage/async-storage.
|
|
938
|
-
*
|
|
939
|
-
* The current userId will be appended to the given storageKey to ensures
|
|
940
|
-
* the cached data concerns only the current user.
|
|
941
|
-
*
|
|
942
|
-
* @param storageKey the name of the persistent storage
|
|
943
|
-
* @returns a success boolean if the cache was dumped to persistent storage
|
|
944
|
-
*
|
|
945
|
-
* @category Cache API
|
|
784
|
+
* The strategy for persistent storage will depend on the runtime,
|
|
785
|
+
* which is supported by @react-native-async-storage/async-storage.
|
|
786
|
+
*
|
|
787
|
+
* The current userId will be appended to the given storageKey to ensures
|
|
788
|
+
* the cached data concerns only the current user.
|
|
789
|
+
*
|
|
790
|
+
* @param storageKey the name of the persistent storage
|
|
791
|
+
* @returns a success boolean if the cache was dumped to persistent storage
|
|
792
|
+
*
|
|
793
|
+
* @category Cache API
|
|
946
794
|
*/
|
|
947
795
|
const restoreCache = async (storageKey = 'amitySdk') => {
|
|
948
796
|
var _a;
|
|
@@ -963,7 +811,6 @@ const restoreCache = async (storageKey = 'amitySdk') => {
|
|
|
963
811
|
return true;
|
|
964
812
|
};
|
|
965
813
|
|
|
966
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
967
814
|
/**
|
|
968
815
|
* ```js
|
|
969
816
|
* import { backupCache } from '@amityco/ts-sdk'
|
|
@@ -1030,62 +877,6 @@ const wipeCache = async (storageKey = 'amitySdk') => {
|
|
|
1030
877
|
return true;
|
|
1031
878
|
};
|
|
1032
879
|
|
|
1033
|
-
/**
|
|
1034
|
-
* Shallow-clones an object and sort its keys
|
|
1035
|
-
*
|
|
1036
|
-
* @param source a plain object to clone
|
|
1037
|
-
* @returns a clone of source, with keys sorted with default javascript sorting
|
|
1038
|
-
*
|
|
1039
|
-
* @category Cache
|
|
1040
|
-
* @hidden
|
|
1041
|
-
*/
|
|
1042
|
-
const normalize = (source) => Object.keys(source)
|
|
1043
|
-
.sort()
|
|
1044
|
-
.reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [key]: source[key] })), {});
|
|
1045
|
-
/**
|
|
1046
|
-
* Encodes a given {@link Amity.CacheKey} to a plain string
|
|
1047
|
-
*
|
|
1048
|
-
* @param key the key to encode
|
|
1049
|
-
* @returns an encoded string
|
|
1050
|
-
*
|
|
1051
|
-
* @category Cache
|
|
1052
|
-
* @hidden
|
|
1053
|
-
*/
|
|
1054
|
-
const encodeKey = (key) => JSON.stringify(key, (_, val) => (typeof val === 'object' ? normalize(val) : val));
|
|
1055
|
-
/**
|
|
1056
|
-
* Decodes a string back into a {@link Amity.CacheKey}
|
|
1057
|
-
|
|
1058
|
-
*
|
|
1059
|
-
* @param key the string key to decode
|
|
1060
|
-
* @returns a plain Amity.CacheKey object.
|
|
1061
|
-
*
|
|
1062
|
-
* @category Cache
|
|
1063
|
-
* @hidden
|
|
1064
|
-
*/
|
|
1065
|
-
const decodeKey = (key) => JSON.parse(key);
|
|
1066
|
-
/**
|
|
1067
|
-
* Performs a recursive partial deep equal check on two objects.
|
|
1068
|
-
*
|
|
1069
|
-
* @param predicate the reference object containing the partial information
|
|
1070
|
-
* @param candidate the object to check against
|
|
1071
|
-
* @returns true if the candidate contains all the values of the predicate
|
|
1072
|
-
*
|
|
1073
|
-
* @category Cache
|
|
1074
|
-
*/
|
|
1075
|
-
const partialMatch = (predicate, candidate) => {
|
|
1076
|
-
if (predicate === candidate)
|
|
1077
|
-
return true;
|
|
1078
|
-
// if one or the other is nullish, there can't be equality
|
|
1079
|
-
if (!predicate || !candidate)
|
|
1080
|
-
return false;
|
|
1081
|
-
// we only perform recursive check on objects
|
|
1082
|
-
if (typeof predicate !== 'object') {
|
|
1083
|
-
return false;
|
|
1084
|
-
}
|
|
1085
|
-
// recursively call for partial match based on the predicate
|
|
1086
|
-
return Object.keys(predicate).every(key => partialMatch(predicate[key], candidate[key]));
|
|
1087
|
-
};
|
|
1088
|
-
|
|
1089
880
|
/**
|
|
1090
881
|
* ```js
|
|
1091
882
|
* import { queryCache } from '@amityco/ts-sdk'
|
|
@@ -1202,66 +993,348 @@ const mergeInCache = (key, mutation, options) => {
|
|
|
1202
993
|
};
|
|
1203
994
|
|
|
1204
995
|
/**
|
|
1205
|
-
* ```js
|
|
1206
|
-
* import { upsertInCache } from '@amityco/ts-sdk'
|
|
1207
|
-
* upsertInCache<Amity.User>(["user", "foobar"], user)
|
|
1208
|
-
* ```
|
|
1209
|
-
*
|
|
1210
|
-
* Insert or update any provided value as {@link Amity.CacheEntry} for
|
|
1211
|
-
* the matching {@link Amity.CacheKey}
|
|
1212
|
-
*
|
|
1213
|
-
* @param key the key to save the object to
|
|
1214
|
-
* @param data the object to save
|
|
1215
|
-
* @param options customisation object around cache behavior (default gives a 2mn lifespan)
|
|
1216
|
-
* @returns a success boolean if the object was saved in cache
|
|
996
|
+
* ```js
|
|
997
|
+
* import { upsertInCache } from '@amityco/ts-sdk'
|
|
998
|
+
* upsertInCache<Amity.User>(["user", "foobar"], user)
|
|
999
|
+
* ```
|
|
1000
|
+
*
|
|
1001
|
+
* Insert or update any provided value as {@link Amity.CacheEntry} for
|
|
1002
|
+
* the matching {@link Amity.CacheKey}
|
|
1003
|
+
*
|
|
1004
|
+
* @param key the key to save the object to
|
|
1005
|
+
* @param data the object to save
|
|
1006
|
+
* @param options customisation object around cache behavior (default gives a 2mn lifespan)
|
|
1007
|
+
* @returns a success boolean if the object was saved in cache
|
|
1008
|
+
*
|
|
1009
|
+
* @category Cache API
|
|
1010
|
+
* @hidden
|
|
1011
|
+
*/
|
|
1012
|
+
const upsertInCache = (key, data, options = { cachedAt: Date.now() }) => {
|
|
1013
|
+
const { log, cache } = getActiveClient();
|
|
1014
|
+
if (!cache)
|
|
1015
|
+
return false;
|
|
1016
|
+
log('cache/api/upsertInCache', { key, data, options });
|
|
1017
|
+
const cached = pullFromCache(key);
|
|
1018
|
+
return cached ? mergeInCache(key, data, options) : pushToCache(key, data, options);
|
|
1019
|
+
};
|
|
1020
|
+
|
|
1021
|
+
/**
|
|
1022
|
+
* ```js
|
|
1023
|
+
* import { dropFromCache } from '@amityco/ts-sdk'
|
|
1024
|
+
* const success = dropFromCache(['user', 'foobar'])
|
|
1025
|
+
* ```
|
|
1026
|
+
*
|
|
1027
|
+
* Removes an existing {@link Amity.CacheEntry} from the {@link Amity.Client}'s
|
|
1028
|
+
* {@link Amity.Cache} from a given {@link Amity.CacheKey}
|
|
1029
|
+
*
|
|
1030
|
+
* @param key The key of the object to delete
|
|
1031
|
+
* @param exact If false, the function will delete all keys satisfying the given key
|
|
1032
|
+
* @returns A success boolean if the object was deleted
|
|
1033
|
+
*
|
|
1034
|
+
* @category Cache API
|
|
1035
|
+
*/
|
|
1036
|
+
const dropFromCache = (key, exact = false) => {
|
|
1037
|
+
const { log, cache } = getActiveClient();
|
|
1038
|
+
if (!cache)
|
|
1039
|
+
return false;
|
|
1040
|
+
log('cache/api/dropFromCache', { key, exact });
|
|
1041
|
+
if (!exact) {
|
|
1042
|
+
return Object.keys(cache.data)
|
|
1043
|
+
.map(stringKey => decodeKey(stringKey))
|
|
1044
|
+
.filter(candidate => partialMatch(key, candidate))
|
|
1045
|
+
.map(filteredKey => dropFromCache(filteredKey, true))
|
|
1046
|
+
.every(returned => returned);
|
|
1047
|
+
}
|
|
1048
|
+
const encodedKey = encodeKey(key);
|
|
1049
|
+
if (encodedKey in cache.data) {
|
|
1050
|
+
delete cache.data[encodedKey];
|
|
1051
|
+
return true;
|
|
1052
|
+
}
|
|
1053
|
+
return false;
|
|
1054
|
+
};
|
|
1055
|
+
|
|
1056
|
+
// Note:
|
|
1057
|
+
// this file should contain a suite of filtering utilities to help the
|
|
1058
|
+
// local version of the query functions.
|
|
1059
|
+
/**
|
|
1060
|
+
* Filter a given collection with strict equality against a param
|
|
1061
|
+
*
|
|
1062
|
+
* @param collection the collection to filter
|
|
1063
|
+
* @param key the key of the collection's items to challenge
|
|
1064
|
+
* @param value the expected value
|
|
1065
|
+
* @returns a filtered collection with items only matching the criteria
|
|
1066
|
+
*
|
|
1067
|
+
* @hidden
|
|
1068
|
+
*/
|
|
1069
|
+
const filterByPropEquality = (collection, key, value) => (value !== undefined ? collection.filter(item => item[key] === value) : collection);
|
|
1070
|
+
const filterByPropInclusion = (collection, key, value) => (value !== undefined ? collection.filter(item => value.includes(item[key])) : collection);
|
|
1071
|
+
/**
|
|
1072
|
+
* Filter a channel collection by membership of the userId
|
|
1073
|
+
*
|
|
1074
|
+
* @param collection the channel collection to filter
|
|
1075
|
+
* @param membership the membership to be filtered by
|
|
1076
|
+
* @param userId user id to be filtered by
|
|
1077
|
+
* @returns a filtered collection with items only matching the criteria
|
|
1078
|
+
*
|
|
1079
|
+
* @hidden
|
|
1080
|
+
*/
|
|
1081
|
+
const filterByChannelMembership = (collection, membership, userId) => {
|
|
1082
|
+
if (membership === 'all') {
|
|
1083
|
+
return collection;
|
|
1084
|
+
}
|
|
1085
|
+
return collection.filter(c => {
|
|
1086
|
+
var _a;
|
|
1087
|
+
// get resolver for the channel by user
|
|
1088
|
+
const channelUserCacheKey = getResolver('channelUsers')({
|
|
1089
|
+
channelId: c.channelId,
|
|
1090
|
+
userId,
|
|
1091
|
+
});
|
|
1092
|
+
const channelUser = (_a = pullFromCache([
|
|
1093
|
+
'channelUsers',
|
|
1094
|
+
'get',
|
|
1095
|
+
channelUserCacheKey,
|
|
1096
|
+
])) === null || _a === void 0 ? void 0 : _a.data;
|
|
1097
|
+
// if channel user is defined for user, user is a member
|
|
1098
|
+
if (membership === 'member' && channelUser) {
|
|
1099
|
+
return true;
|
|
1100
|
+
}
|
|
1101
|
+
// if channel user by user id not found, user is not a member of that
|
|
1102
|
+
// channel
|
|
1103
|
+
if (membership === 'notMember' && !channelUser) {
|
|
1104
|
+
return true;
|
|
1105
|
+
}
|
|
1106
|
+
return false;
|
|
1107
|
+
});
|
|
1108
|
+
};
|
|
1109
|
+
|
|
1110
|
+
// Note:
|
|
1111
|
+
// this file should contain a suite of sorting utilities to help the
|
|
1112
|
+
// local version of the query functions.
|
|
1113
|
+
/**
|
|
1114
|
+
* Alphabetic sorting of objects having a displayName
|
|
1115
|
+
*/
|
|
1116
|
+
const sortByDisplayName = ({ displayName: a }, { displayName: b }) => {
|
|
1117
|
+
if (a === b)
|
|
1118
|
+
return 0;
|
|
1119
|
+
return a < b ? -1 : 1;
|
|
1120
|
+
};
|
|
1121
|
+
/**
|
|
1122
|
+
* Sorting a collection by their apparition order (oldest first)
|
|
1123
|
+
*/
|
|
1124
|
+
const sortByChannelSegment = ({ channelSegment: a }, { channelSegment: b }) => a - b;
|
|
1125
|
+
/**
|
|
1126
|
+
* Sorting a collection by their apparition order (oldest first)
|
|
1127
|
+
*/
|
|
1128
|
+
const sortBySegmentNumber = ({ segmentNumber: a }, { segmentNumber: b }) => a - b;
|
|
1129
|
+
/**
|
|
1130
|
+
* Sorting a collection by its oldest items
|
|
1131
|
+
*/
|
|
1132
|
+
const sortByFirstCreated = ({ createdAt: a }, { createdAt: b }) => new Date(a).valueOf() - new Date(b).valueOf();
|
|
1133
|
+
/**
|
|
1134
|
+
* Sorting a collection by its newest items
|
|
1135
|
+
*/
|
|
1136
|
+
const sortByLastCreated = ({ createdAt: a }, { createdAt: b }) => new Date(b).valueOf() - new Date(a).valueOf();
|
|
1137
|
+
/**
|
|
1138
|
+
* Sorting a collection by the items with most recent activity
|
|
1139
|
+
*/
|
|
1140
|
+
const sortByLastActivity = ({ lastActivity: a }, { lastActivity: b }) => new Date(b).valueOf() - new Date(a).valueOf();
|
|
1141
|
+
|
|
1142
|
+
/* eslint-disable @typescript-eslint/ban-types */
|
|
1143
|
+
let tasks = [];
|
|
1144
|
+
let timer;
|
|
1145
|
+
/**
|
|
1146
|
+
* Add a function to run just before the next tick
|
|
1147
|
+
*
|
|
1148
|
+
* @param task function to schedule for later execution
|
|
1149
|
+
*/
|
|
1150
|
+
const scheduleTask = (task) => {
|
|
1151
|
+
clearTimeout(timer);
|
|
1152
|
+
tasks.push(task);
|
|
1153
|
+
timer = setTimeout(() => {
|
|
1154
|
+
tasks.forEach(fn => fn());
|
|
1155
|
+
tasks = [];
|
|
1156
|
+
}, 0);
|
|
1157
|
+
};
|
|
1158
|
+
|
|
1159
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
1160
|
+
// need to sync up the list
|
|
1161
|
+
const WS_EVENTS = [
|
|
1162
|
+
'disconnected',
|
|
1163
|
+
'error',
|
|
1164
|
+
'connect_error',
|
|
1165
|
+
'reconnect_error',
|
|
1166
|
+
'reconnect_failed',
|
|
1167
|
+
'v3.channel.didCreate',
|
|
1168
|
+
'v3.channel.didUpdate',
|
|
1169
|
+
'v3.channel.didDelete',
|
|
1170
|
+
'v3.channel.didJoin',
|
|
1171
|
+
'v3.channel.didLeave',
|
|
1172
|
+
'v3.channel.didAddUsers',
|
|
1173
|
+
'v3.channel.didRemoveUsers',
|
|
1174
|
+
'v3.channel.didBan',
|
|
1175
|
+
'v3.channel.didUnban',
|
|
1176
|
+
'v3.message.didFetch',
|
|
1177
|
+
'v3.message.didCreate',
|
|
1178
|
+
'v3.message.didUpdate',
|
|
1179
|
+
'v3.message.didDelete',
|
|
1180
|
+
];
|
|
1181
|
+
const MQTT_EVENTS = [
|
|
1182
|
+
'connect',
|
|
1183
|
+
'message',
|
|
1184
|
+
'disconnect',
|
|
1185
|
+
'error',
|
|
1186
|
+
'close',
|
|
1187
|
+
'end',
|
|
1188
|
+
'reconnect',
|
|
1189
|
+
];
|
|
1190
|
+
/** @hidden */
|
|
1191
|
+
const createEventEmitter = () => {
|
|
1192
|
+
return mitt__default["default"]();
|
|
1193
|
+
};
|
|
1194
|
+
/**
|
|
1195
|
+
* Wraps the websocket events into the client's event emitter for
|
|
1196
|
+
* abstraction of transport.
|
|
1197
|
+
*
|
|
1198
|
+
* @param ws A websocket connection to listen from
|
|
1199
|
+
* @param emitter An event emitter to wire the events to
|
|
1200
|
+
*
|
|
1201
|
+
* @category Transport
|
|
1202
|
+
* @hidden
|
|
1203
|
+
*/
|
|
1204
|
+
const proxyWebsocketEvents = (ws, emitter) => {
|
|
1205
|
+
WS_EVENTS.forEach(event => {
|
|
1206
|
+
ws.on(event, (param) => emitter.emit(event, param));
|
|
1207
|
+
});
|
|
1208
|
+
};
|
|
1209
|
+
const proxyMqttEvents = (mqttClient, emitter) => {
|
|
1210
|
+
MQTT_EVENTS.forEach(event => {
|
|
1211
|
+
mqttClient.on(event, (...params) => emitter.emit(event, params.length === 1 ? params[0] : params));
|
|
1212
|
+
});
|
|
1213
|
+
// @ts-ignore
|
|
1214
|
+
mqttClient.on('message', (topic, payload) => {
|
|
1215
|
+
const message = JSON.parse(payload.toString());
|
|
1216
|
+
emitter.emit(message.eventType, message.data);
|
|
1217
|
+
});
|
|
1218
|
+
};
|
|
1219
|
+
/**
|
|
1220
|
+
* Standardize the subscription of SSE through web sockets
|
|
1221
|
+
*
|
|
1222
|
+
* @param client The current client for which to subscribe the event to
|
|
1223
|
+
* @param namespace A unique name for the logger
|
|
1224
|
+
* @param event The websocket event name
|
|
1225
|
+
* @param fn A wrapper for the callback.
|
|
1226
|
+
* @returns A dispose function to unsubscribe to the event
|
|
1227
|
+
*
|
|
1228
|
+
* @category Transport
|
|
1229
|
+
* @hidden
|
|
1230
|
+
*/
|
|
1231
|
+
const createEventSubscriber = (client, namespace, event, fn) => {
|
|
1232
|
+
const { log, emitter } = client;
|
|
1233
|
+
const timestamp = Date.now();
|
|
1234
|
+
log(`${namespace}(tmpid: ${timestamp}) > listen`);
|
|
1235
|
+
const handler = (...payload) => {
|
|
1236
|
+
log(`${namespace}(tmpid: ${timestamp}) > trigger`, payload);
|
|
1237
|
+
fn(...payload);
|
|
1238
|
+
};
|
|
1239
|
+
emitter.on(event, handler);
|
|
1240
|
+
return () => {
|
|
1241
|
+
log(`${namespace}(tmpid: ${timestamp}) > dispose`);
|
|
1242
|
+
emitter.off(event, handler);
|
|
1243
|
+
};
|
|
1244
|
+
};
|
|
1245
|
+
/**
|
|
1246
|
+
* Wrapper around dispatch event
|
|
1217
1247
|
*
|
|
1218
|
-
* @category Cache API
|
|
1219
1248
|
* @hidden
|
|
1220
1249
|
*/
|
|
1221
|
-
const
|
|
1222
|
-
const {
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
const cached = pullFromCache(key);
|
|
1227
|
-
return cached ? mergeInCache(key, data, options) : pushToCache(key, data, options);
|
|
1250
|
+
const fireEvent = (event, payload) => {
|
|
1251
|
+
const { emitter } = getActiveClient();
|
|
1252
|
+
scheduleTask(() => {
|
|
1253
|
+
emitter.emit(event, payload);
|
|
1254
|
+
});
|
|
1228
1255
|
};
|
|
1229
1256
|
|
|
1257
|
+
let activeUser = null;
|
|
1230
1258
|
/**
|
|
1231
|
-
*
|
|
1232
|
-
* import { dropFromCache } from '@amityco/ts-sdk'
|
|
1233
|
-
* const success = dropFromCache(['user', 'foobar'])
|
|
1234
|
-
* ```
|
|
1235
|
-
*
|
|
1236
|
-
* Removes an existing {@link Amity.CacheEntry} from the {@link Amity.Client}'s
|
|
1237
|
-
* {@link Amity.Cache} from a given {@link Amity.CacheKey}
|
|
1238
|
-
*
|
|
1239
|
-
* @param key The key of the object to delete
|
|
1240
|
-
* @param exact If false, the function will delete all keys satisfying the given key
|
|
1241
|
-
* @returns A success boolean if the object was deleted
|
|
1242
|
-
*
|
|
1243
|
-
* @category Cache API
|
|
1259
|
+
* for internal use
|
|
1244
1260
|
*/
|
|
1245
|
-
const
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
return false;
|
|
1249
|
-
log('cache/api/dropFromCache', { key, exact });
|
|
1250
|
-
if (!exact) {
|
|
1251
|
-
return Object.keys(cache.data)
|
|
1252
|
-
.map(stringKey => decodeKey(stringKey))
|
|
1253
|
-
.filter(candidate => partialMatch(key, candidate))
|
|
1254
|
-
.map(filteredKey => dropFromCache(filteredKey, true))
|
|
1255
|
-
.every(returned => returned);
|
|
1256
|
-
}
|
|
1257
|
-
const encodedKey = encodeKey(key);
|
|
1258
|
-
if (encodedKey in cache.data) {
|
|
1259
|
-
delete cache.data[encodedKey];
|
|
1260
|
-
return true;
|
|
1261
|
+
const getActiveUser = () => {
|
|
1262
|
+
if (!activeUser) {
|
|
1263
|
+
throw new ASCError('Connect client first', 800000 /* Amity.ClientError.UNKNOWN_ERROR */, "fatal" /* Amity.ErrorLevel.FATAL */);
|
|
1261
1264
|
}
|
|
1262
|
-
return
|
|
1265
|
+
return activeUser;
|
|
1266
|
+
};
|
|
1267
|
+
const setActiveUser = (user) => {
|
|
1268
|
+
activeUser = {
|
|
1269
|
+
_id: user._id,
|
|
1270
|
+
userId: user.userId,
|
|
1271
|
+
path: user.path,
|
|
1272
|
+
};
|
|
1263
1273
|
};
|
|
1264
1274
|
|
|
1275
|
+
exports.SubscriptionLevels = void 0;
|
|
1276
|
+
(function (SubscriptionLevels) {
|
|
1277
|
+
SubscriptionLevels["COMMUNITY"] = "community";
|
|
1278
|
+
SubscriptionLevels["POST"] = "post";
|
|
1279
|
+
SubscriptionLevels["COMMENT"] = "comment";
|
|
1280
|
+
SubscriptionLevels["POST_AND_COMMENT"] = "post_and_comment";
|
|
1281
|
+
SubscriptionLevels["USER"] = "user";
|
|
1282
|
+
})(exports.SubscriptionLevels || (exports.SubscriptionLevels = {}));
|
|
1283
|
+
const getCommunityUserTopic = (path, level) => {
|
|
1284
|
+
switch (level) {
|
|
1285
|
+
case 'post':
|
|
1286
|
+
return `${path}/post/+`;
|
|
1287
|
+
case 'comment':
|
|
1288
|
+
return `${path}/post/+/comment/+`;
|
|
1289
|
+
case 'post_and_comment':
|
|
1290
|
+
return `${path}/post/#`;
|
|
1291
|
+
default:
|
|
1292
|
+
return path;
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1295
|
+
const getCommunityTopic = ({ path }, level = exports.SubscriptionLevels.COMMUNITY) => getCommunityUserTopic(path, level);
|
|
1296
|
+
const getUserTopic = ({ path }, level = exports.SubscriptionLevels.USER) => getCommunityUserTopic(level === exports.SubscriptionLevels.USER ? path : path.replace(/^(\w*)/, '$1/social'), level);
|
|
1297
|
+
const getPostTopic = ({ path }, level = exports.SubscriptionLevels.POST) => {
|
|
1298
|
+
switch (level) {
|
|
1299
|
+
case 'comment':
|
|
1300
|
+
return `${path}/comment/+`;
|
|
1301
|
+
default:
|
|
1302
|
+
return path;
|
|
1303
|
+
}
|
|
1304
|
+
};
|
|
1305
|
+
const getCommentTopic = ({ path }) => {
|
|
1306
|
+
return path;
|
|
1307
|
+
};
|
|
1308
|
+
const getMyFollowersTopic = () => {
|
|
1309
|
+
const user = getActiveUser();
|
|
1310
|
+
const [networkId] = user.path.split('/user/');
|
|
1311
|
+
return `${networkId}/membership/${user._id}/+/+`;
|
|
1312
|
+
};
|
|
1313
|
+
const getMyFollowingsTopic = () => {
|
|
1314
|
+
const user = getActiveUser();
|
|
1315
|
+
const [networkId] = user.path.split('/user/');
|
|
1316
|
+
return `${networkId}/membership/+/${user._id}/+`;
|
|
1317
|
+
};
|
|
1318
|
+
/** @hidden */
|
|
1319
|
+
const getNetworkTopic = () => {
|
|
1320
|
+
const user = getActiveUser();
|
|
1321
|
+
const [networkId] = user.path.split('/user/');
|
|
1322
|
+
return networkId;
|
|
1323
|
+
};
|
|
1324
|
+
let mqttAccessToken;
|
|
1325
|
+
let mqttUserId;
|
|
1326
|
+
function subscribeTopic(topic, callback) {
|
|
1327
|
+
const { mqtt, emitter, accessToken } = getActiveClient();
|
|
1328
|
+
const user = getActiveUser();
|
|
1329
|
+
if (mqttAccessToken !== accessToken || mqttUserId !== user._id) {
|
|
1330
|
+
mqttAccessToken = accessToken;
|
|
1331
|
+
mqttUserId = user._id;
|
|
1332
|
+
mqtt.connect({ accessToken: mqttAccessToken, userId: mqttUserId });
|
|
1333
|
+
proxyMqttEvents(mqtt, emitter);
|
|
1334
|
+
}
|
|
1335
|
+
return mqtt.subscribe(topic, callback);
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1265
1338
|
/**
|
|
1266
1339
|
* Creates a pre-configured logger instance
|
|
1267
1340
|
*
|
|
@@ -1324,21 +1397,8 @@ const unwrapPayload = (response) => {
|
|
|
1324
1397
|
* Axios param serializer (for querystring)
|
|
1325
1398
|
* @hidden
|
|
1326
1399
|
*/
|
|
1327
|
-
const stringify = (params
|
|
1328
|
-
return
|
|
1329
|
-
.filter(([, value]) => value !== undefined)
|
|
1330
|
-
.map(([name, value]) => {
|
|
1331
|
-
const key = prefix ? `${prefix}[${name}]` : name;
|
|
1332
|
-
if (Array.isArray(value)) {
|
|
1333
|
-
return value.map(item => `${key}[]=${item}`).join('&');
|
|
1334
|
-
}
|
|
1335
|
-
if (typeof value !== 'object') {
|
|
1336
|
-
return `${key}=${value}`;
|
|
1337
|
-
}
|
|
1338
|
-
// @ts-ignore
|
|
1339
|
-
return stringify(value, prefix !== null && prefix !== void 0 ? prefix : name);
|
|
1340
|
-
})
|
|
1341
|
-
.join('&');
|
|
1400
|
+
const stringify = (params) => {
|
|
1401
|
+
return qs__default["default"].stringify(params, { arrayFormat: 'brackets' });
|
|
1342
1402
|
};
|
|
1343
1403
|
/**
|
|
1344
1404
|
* Creates a pre-configured axios instance
|
|
@@ -20578,6 +20638,61 @@ const isConnected = () => {
|
|
|
20578
20638
|
client.ws.connected);
|
|
20579
20639
|
};
|
|
20580
20640
|
|
|
20641
|
+
/**
|
|
20642
|
+
* ```js
|
|
20643
|
+
* import { isInTombstone } from '@amityco/ts-sdk'
|
|
20644
|
+
* const user = isInTombstone(["message", "messageId"])
|
|
20645
|
+
* ```
|
|
20646
|
+
*
|
|
20647
|
+
* Checks if the {@link Amity.TombstoneCacheOptions} exists
|
|
20648
|
+
* in cache and it's not expired means it's in tombstone
|
|
20649
|
+
* and we throw an Error
|
|
20650
|
+
*
|
|
20651
|
+
* @param model the model to check
|
|
20652
|
+
* @param modelId the object id to check
|
|
20653
|
+
* @returns the matching cache entry, or undefined.
|
|
20654
|
+
*
|
|
20655
|
+
* @category Cache API
|
|
20656
|
+
*/
|
|
20657
|
+
const isInTombstone = (model, modelId) => {
|
|
20658
|
+
const { log, cache } = getActiveClient();
|
|
20659
|
+
const key = [model, CACHE_KEY_TOMBSTONE, modelId];
|
|
20660
|
+
if (!cache)
|
|
20661
|
+
return;
|
|
20662
|
+
log('cache/api/isInTombstone', key);
|
|
20663
|
+
const isInTombstone = pullFromCache(key);
|
|
20664
|
+
const { lifeSpan } = queryOptions('cache_then_server', CACHE_LIFESPAN_TOMBSTONE);
|
|
20665
|
+
if (isInTombstone && isFresh(isInTombstone.data, lifeSpan)) {
|
|
20666
|
+
throw new ASCApiError('Item not found!', 400400 /* Amity.ServerError.ITEM_NOT_FOUND */, "error" /* Amity.ErrorLevel.ERROR */);
|
|
20667
|
+
}
|
|
20668
|
+
};
|
|
20669
|
+
|
|
20670
|
+
/**
|
|
20671
|
+
* ```js
|
|
20672
|
+
* import { pushToTombstone } from '@amityco/ts-sdk'
|
|
20673
|
+
* pushToTombstone(["message", "messageId"], { cachedAt: Date.now() })
|
|
20674
|
+
* ```
|
|
20675
|
+
*
|
|
20676
|
+
* Removes an existing {@link Amity.CacheEntry} from the {@link Amity.Client}'s
|
|
20677
|
+
* {@link Amity.Cache} from a given {@link Amity.CacheKey}
|
|
20678
|
+
*
|
|
20679
|
+
* @param model the model to remove and push to Tombstone
|
|
20680
|
+
* @param modelId the related model id
|
|
20681
|
+
*
|
|
20682
|
+
* @category Cache API
|
|
20683
|
+
* @hidden
|
|
20684
|
+
*/
|
|
20685
|
+
const pushToTombstone = (model, modelId) => {
|
|
20686
|
+
const { log, cache } = getActiveClient();
|
|
20687
|
+
const cacheKey = [model, CACHE_KEY_TOMBSTONE, modelId];
|
|
20688
|
+
const data = { cachedAt: Date.now() };
|
|
20689
|
+
if (!cache)
|
|
20690
|
+
return;
|
|
20691
|
+
log('cache/api/pushToTombstone', { cacheKey, data });
|
|
20692
|
+
dropFromCache([model, CACHE_KEY_GET, modelId], true);
|
|
20693
|
+
pushToCache(cacheKey, data);
|
|
20694
|
+
};
|
|
20695
|
+
|
|
20581
20696
|
/**
|
|
20582
20697
|
* ```js
|
|
20583
20698
|
* import { getUser } from '@amityco/ts-sdk'
|
|
@@ -20592,15 +20707,29 @@ const isConnected = () => {
|
|
|
20592
20707
|
* @category User API
|
|
20593
20708
|
* @async
|
|
20594
20709
|
*/
|
|
20595
|
-
const getUser = async (userId) => {
|
|
20710
|
+
const getUser = async (userId, isLive = false) => {
|
|
20596
20711
|
const client = getActiveClient();
|
|
20597
20712
|
client.log('user/getUser', userId);
|
|
20598
|
-
|
|
20599
|
-
|
|
20713
|
+
if (!isLive) {
|
|
20714
|
+
console.log('getUser will be deprecated on 25th November 2022, please use liveUser instead.');
|
|
20715
|
+
}
|
|
20716
|
+
isInTombstone('user', userId);
|
|
20717
|
+
let data;
|
|
20718
|
+
try {
|
|
20719
|
+
const response = await client.http.get(`/api/v3/users/${encodeURIComponent(userId)}`);
|
|
20720
|
+
data = response.data;
|
|
20721
|
+
}
|
|
20722
|
+
catch (error) {
|
|
20723
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
20724
|
+
pushToTombstone('user', userId);
|
|
20725
|
+
}
|
|
20726
|
+
throw error;
|
|
20727
|
+
}
|
|
20600
20728
|
const cachedAt = client.cache && Date.now();
|
|
20601
20729
|
if (client.cache)
|
|
20602
20730
|
ingestInCache(data, { cachedAt });
|
|
20603
20731
|
const { users } = data;
|
|
20732
|
+
fireEvent('user.fetched', data);
|
|
20604
20733
|
return {
|
|
20605
20734
|
data: users.find(user => user.userId === userId),
|
|
20606
20735
|
cachedAt,
|
|
@@ -20650,6 +20779,7 @@ const getUsers = async (userIds) => {
|
|
|
20650
20779
|
const cachedAt = client.cache && Date.now();
|
|
20651
20780
|
if (client.cache)
|
|
20652
20781
|
ingestInCache(data, { cachedAt });
|
|
20782
|
+
fireEvent('user.fetched', data);
|
|
20653
20783
|
return {
|
|
20654
20784
|
data: data.users,
|
|
20655
20785
|
cachedAt,
|
|
@@ -20732,8 +20862,7 @@ function __rest(s, e) {
|
|
|
20732
20862
|
const queryUsers = async (query = {}) => {
|
|
20733
20863
|
const client = getActiveClient();
|
|
20734
20864
|
client.log('user/queryUsers', query);
|
|
20735
|
-
const { page, displayName, filter = 'all', sortBy = 'displayName' } = query, params = __rest(query, ["page", "displayName", "filter", "sortBy"]);
|
|
20736
|
-
// API-FIX: parameters should be querystring.
|
|
20865
|
+
const { page = { limit: 10 }, displayName, filter = 'all', sortBy = 'displayName' } = query, params = __rest(query, ["page", "displayName", "filter", "sortBy"]);
|
|
20737
20866
|
const { data } = await client.http.get(`/api/v3/users`, {
|
|
20738
20867
|
params: Object.assign(Object.assign({}, params), { keyword: displayName, filter,
|
|
20739
20868
|
sortBy, options: {
|
|
@@ -20746,9 +20875,14 @@ const queryUsers = async (query = {}) => {
|
|
|
20746
20875
|
const cachedAt = client.cache && Date.now();
|
|
20747
20876
|
if (client.cache) {
|
|
20748
20877
|
ingestInCache(payload, { cachedAt });
|
|
20749
|
-
|
|
20878
|
+
/*
|
|
20879
|
+
* using query as cache key over params because if the keyword, filter, sort
|
|
20880
|
+
* change the API will NOT cache results, when it should
|
|
20881
|
+
*/
|
|
20882
|
+
const cacheKey = ['user', 'query', Object.assign(Object.assign({}, query), { options: Object.assign({}, page) })];
|
|
20750
20883
|
pushToCache(cacheKey, { users: users.map(getResolver('user')), paging });
|
|
20751
20884
|
}
|
|
20885
|
+
fireEvent('user.fetched', data);
|
|
20752
20886
|
const prevPage = toPage(paging.previous);
|
|
20753
20887
|
const nextPage = toPage(paging.next);
|
|
20754
20888
|
return { data: users, cachedAt, prevPage, nextPage };
|
|
@@ -20773,8 +20907,13 @@ queryUsers.locally = (query = {}) => {
|
|
|
20773
20907
|
client.log('user/queryUsers.locally', query);
|
|
20774
20908
|
if (!client.cache)
|
|
20775
20909
|
return;
|
|
20776
|
-
const
|
|
20777
|
-
const
|
|
20910
|
+
const { page = { limit: 10 } } = query !== null && query !== void 0 ? query : {};
|
|
20911
|
+
const cacheKey = [
|
|
20912
|
+
'user',
|
|
20913
|
+
'query',
|
|
20914
|
+
Object.assign(Object.assign({}, query), { options: Object.assign({}, page) }),
|
|
20915
|
+
];
|
|
20916
|
+
const { data, cachedAt } = (_a = pullFromCache(cacheKey)) !== null && _a !== void 0 ? _a : {};
|
|
20778
20917
|
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 : [];
|
|
20779
20918
|
const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
|
|
20780
20919
|
const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
|
|
@@ -20812,12 +20951,30 @@ const updateUser = async (userId, patch) => {
|
|
|
20812
20951
|
if (client.cache)
|
|
20813
20952
|
ingestInCache(data, { cachedAt });
|
|
20814
20953
|
const { users } = data;
|
|
20954
|
+
fireEvent('user.updated', data);
|
|
20815
20955
|
return {
|
|
20816
20956
|
data: users.find(user => user.userId === userId),
|
|
20817
20957
|
cachedAt,
|
|
20818
20958
|
};
|
|
20819
20959
|
};
|
|
20820
20960
|
|
|
20961
|
+
/**
|
|
20962
|
+
* ```js
|
|
20963
|
+
* import { onUserFetched } from '@amityco/ts-sdk'
|
|
20964
|
+
* const dispose = onUserFetched(user => {
|
|
20965
|
+
* // ...
|
|
20966
|
+
* })
|
|
20967
|
+
* ```
|
|
20968
|
+
*
|
|
20969
|
+
* Fired when a {@link Amity.User} has been fetched
|
|
20970
|
+
*
|
|
20971
|
+
* @param callback The function to call when the event was fired
|
|
20972
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
20973
|
+
*
|
|
20974
|
+
* @category User Events
|
|
20975
|
+
*/
|
|
20976
|
+
const onUserFetched = (callback) => createUserEventSubscriber('user.fetched', callback);
|
|
20977
|
+
|
|
20821
20978
|
/**
|
|
20822
20979
|
* ```js
|
|
20823
20980
|
* import { onUserUpdated } from '@amityco/ts-sdk'
|
|
@@ -20886,6 +21043,68 @@ const onUserUnflagged = (callback) => createUserEventSubscriber('user.unflagged'
|
|
|
20886
21043
|
*/
|
|
20887
21044
|
const onUserFlagCleared = (callback) => createUserEventSubscriber('user.flagCleared', callback);
|
|
20888
21045
|
|
|
21046
|
+
const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
|
|
21047
|
+
const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
|
|
21048
|
+
const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
|
|
21049
|
+
const LIVE_OBJECT_ENABLE_CACHE_MESSAGE = 'For using Live Object feature you need to enable Cache!';
|
|
21050
|
+
const UNSYNCED_OBJECT_CACHED_AT_MESSAGE = 'Observing unsynced object is not supported by Live Object.';
|
|
21051
|
+
const UNSYNCED_OBJECT_CACHED_AT_VALUE = -5;
|
|
21052
|
+
|
|
21053
|
+
/**
|
|
21054
|
+
* ```js
|
|
21055
|
+
* import { liveUser } from '@amityco/ts-sdk'
|
|
21056
|
+
*
|
|
21057
|
+
* let users = []
|
|
21058
|
+
* const unsub = liveUser(userId, response => merge(users, response.data))
|
|
21059
|
+
* ```
|
|
21060
|
+
*
|
|
21061
|
+
* Observe all mutation on a given {@link Amity.User}
|
|
21062
|
+
*
|
|
21063
|
+
* @param userId the ID of the user to observe
|
|
21064
|
+
* @param callback the function to call when new data are available
|
|
21065
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the users
|
|
21066
|
+
*
|
|
21067
|
+
* @category Message Live Object
|
|
21068
|
+
*/
|
|
21069
|
+
const liveUser = (userId, callback) => {
|
|
21070
|
+
const { log, cache } = getActiveClient();
|
|
21071
|
+
let user;
|
|
21072
|
+
if (!cache) {
|
|
21073
|
+
console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
|
|
21074
|
+
}
|
|
21075
|
+
const timestamp = Date.now();
|
|
21076
|
+
log(`liveUser(tmpid: ${timestamp}) > listen`);
|
|
21077
|
+
const disposers = [];
|
|
21078
|
+
const dispatcher = (data) => {
|
|
21079
|
+
var _a;
|
|
21080
|
+
// we check updatedAt to see if the current snapshot is new so
|
|
21081
|
+
// we won't send old data back, only fresh new data
|
|
21082
|
+
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')
|
|
21083
|
+
return;
|
|
21084
|
+
callback(data);
|
|
21085
|
+
user = data.data;
|
|
21086
|
+
};
|
|
21087
|
+
const realtimeRouter = (user, action) => {
|
|
21088
|
+
dispatcher({ loading: false, data: user, origin: 'event' });
|
|
21089
|
+
};
|
|
21090
|
+
const onFetch = () => {
|
|
21091
|
+
const query = createQuery(getUser, userId, true);
|
|
21092
|
+
runQuery(query, ({ loading, data, error, origin }) => {
|
|
21093
|
+
dispatcher({ loading, data, origin, error });
|
|
21094
|
+
if (error) {
|
|
21095
|
+
// Terminate observe functionality on error
|
|
21096
|
+
disposers.forEach(fn => fn());
|
|
21097
|
+
}
|
|
21098
|
+
});
|
|
21099
|
+
};
|
|
21100
|
+
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)));
|
|
21101
|
+
onFetch();
|
|
21102
|
+
return () => {
|
|
21103
|
+
log(`liveUser(tmpid: ${timestamp}) > dispose`);
|
|
21104
|
+
disposers.forEach(fn => fn());
|
|
21105
|
+
};
|
|
21106
|
+
};
|
|
21107
|
+
|
|
20889
21108
|
/**
|
|
20890
21109
|
* ```js
|
|
20891
21110
|
* import { observeUser } from '@amityco/ts-sdk'
|
|
@@ -20905,6 +21124,7 @@ const observeUser = (userId, callback) => {
|
|
|
20905
21124
|
const { log } = getActiveClient();
|
|
20906
21125
|
const timestamp = Date.now();
|
|
20907
21126
|
log(`observeUser(tmpid: ${timestamp}) > listen`);
|
|
21127
|
+
console.log('observeUser will be deprecated on 25th November 2022, please use liveUser instead.');
|
|
20908
21128
|
// wrapper function to make sure
|
|
20909
21129
|
const router = (result, action) => {
|
|
20910
21130
|
var _a, _b, _c;
|
|
@@ -21314,15 +21534,30 @@ const dispatchReactable = (referenceType, model) => {
|
|
|
21314
21534
|
* @category Message API
|
|
21315
21535
|
* @async
|
|
21316
21536
|
*/
|
|
21317
|
-
const getMessage = async (messageId) => {
|
|
21537
|
+
const getMessage = async (messageId, isLive = false) => {
|
|
21318
21538
|
const client = getActiveClient();
|
|
21319
21539
|
client.log('message/getMessage', messageId);
|
|
21320
|
-
|
|
21321
|
-
|
|
21540
|
+
if (!isLive) {
|
|
21541
|
+
console.log('getMessage will be deprecated on 15th November 2022, please use liveMessage instead.');
|
|
21542
|
+
}
|
|
21543
|
+
isInTombstone('message', messageId);
|
|
21544
|
+
let data;
|
|
21545
|
+
try {
|
|
21546
|
+
// API-FIX: endpoint should not be /list, parameters should be querystring.
|
|
21547
|
+
const response = await client.http.get(`/api/v3/messages/${encodeURIComponent(messageId)}`);
|
|
21548
|
+
data = response.data;
|
|
21549
|
+
}
|
|
21550
|
+
catch (error) {
|
|
21551
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
21552
|
+
pushToTombstone('message', messageId);
|
|
21553
|
+
}
|
|
21554
|
+
throw error;
|
|
21555
|
+
}
|
|
21322
21556
|
const cachedAt = client.cache && Date.now();
|
|
21323
21557
|
if (client.cache)
|
|
21324
21558
|
ingestInCache(data, { cachedAt });
|
|
21325
21559
|
const { messages } = data;
|
|
21560
|
+
fireEvent('v3.message.didFetch', { messages });
|
|
21326
21561
|
return {
|
|
21327
21562
|
data: messages.find(message => message.messageId === messageId),
|
|
21328
21563
|
cachedAt,
|
|
@@ -21379,8 +21614,10 @@ const getMessages = async (messageIds) => {
|
|
|
21379
21614
|
const cachedAt = client.cache && Date.now();
|
|
21380
21615
|
if (client.cache)
|
|
21381
21616
|
ingestInCache(data, { cachedAt });
|
|
21617
|
+
const { messages } = data;
|
|
21618
|
+
fireEvent('v3.message.didFetch', { messages });
|
|
21382
21619
|
return {
|
|
21383
|
-
data:
|
|
21620
|
+
data: messages,
|
|
21384
21621
|
cachedAt,
|
|
21385
21622
|
};
|
|
21386
21623
|
};
|
|
@@ -21457,6 +21694,7 @@ const queryMessages = async (query) => {
|
|
|
21457
21694
|
];
|
|
21458
21695
|
pushToCache(cacheKey, { messages: messages.map(getResolver('message')), paging });
|
|
21459
21696
|
}
|
|
21697
|
+
fireEvent('v3.message.didFetch', { messages });
|
|
21460
21698
|
const nextPage = toPage(paging.next);
|
|
21461
21699
|
const prevPage = toPage(paging.previous);
|
|
21462
21700
|
return { data: messages, cachedAt, prevPage, nextPage };
|
|
@@ -21522,8 +21760,8 @@ const createMessage = async (bundle) => {
|
|
|
21522
21760
|
const cachedAt = client.cache && Date.now();
|
|
21523
21761
|
if (client.cache)
|
|
21524
21762
|
ingestInCache(data, { cachedAt });
|
|
21525
|
-
// no need for event, fired by server
|
|
21526
21763
|
const { messages } = data;
|
|
21764
|
+
fireEvent('v3.message.didCreate', { messages });
|
|
21527
21765
|
return {
|
|
21528
21766
|
data: messages[0],
|
|
21529
21767
|
cachedAt,
|
|
@@ -21565,11 +21803,12 @@ createMessage.optimistically = (bundle) => {
|
|
|
21565
21803
|
// as reused to update created and updated time, which should be the same
|
|
21566
21804
|
const createdTime = new Date().toISOString();
|
|
21567
21805
|
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);
|
|
21568
|
-
|
|
21806
|
+
const cachedAt = UNSYNCED_OBJECT_CACHED_AT_VALUE;
|
|
21807
|
+
pushToCache(['message', 'get', message.messageId], message, { cachedAt });
|
|
21569
21808
|
fireEvent('v3.message.didCreate', { messages: [message] });
|
|
21570
21809
|
return {
|
|
21810
|
+
cachedAt,
|
|
21571
21811
|
data: message,
|
|
21572
|
-
cachedAt: -1,
|
|
21573
21812
|
};
|
|
21574
21813
|
};
|
|
21575
21814
|
|
|
@@ -21598,6 +21837,7 @@ const updateMessage = async (messageId, patch) => {
|
|
|
21598
21837
|
if (client.cache)
|
|
21599
21838
|
ingestInCache(data, { cachedAt });
|
|
21600
21839
|
const { messages } = data;
|
|
21840
|
+
fireEvent('v3.message.didUpdate', { messages });
|
|
21601
21841
|
return {
|
|
21602
21842
|
data: messages.find(message => message.messageId === messageId),
|
|
21603
21843
|
cachedAt,
|
|
@@ -21657,7 +21897,7 @@ const deleteMessage = async (messageId) => {
|
|
|
21657
21897
|
// API-FIX: This endpoint has not been implemented yet.
|
|
21658
21898
|
await client.http.delete(`/api/v3/messages/${encodeURIComponent(messageId)}`);
|
|
21659
21899
|
const deleted = await getMessage(messageId);
|
|
21660
|
-
|
|
21900
|
+
fireEvent('v3.message.didDelete', { messages: [deleted.data] });
|
|
21661
21901
|
return deleted.data;
|
|
21662
21902
|
};
|
|
21663
21903
|
/**
|
|
@@ -21844,6 +22084,7 @@ getPosts.locally = (postIds) => {
|
|
|
21844
22084
|
const getPost = async (postId) => {
|
|
21845
22085
|
const client = getActiveClient();
|
|
21846
22086
|
client.log('post/getPost', postId);
|
|
22087
|
+
isInTombstone('post', postId);
|
|
21847
22088
|
let data;
|
|
21848
22089
|
try {
|
|
21849
22090
|
// API-FIX: endpoint should not be /list, parameters should be querystring.
|
|
@@ -21851,8 +22092,8 @@ const getPost = async (postId) => {
|
|
|
21851
22092
|
data = response.data;
|
|
21852
22093
|
}
|
|
21853
22094
|
catch (error) {
|
|
21854
|
-
if ((error === null || error === void 0 ? void 0 : error.code)
|
|
21855
|
-
|
|
22095
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
22096
|
+
pushToTombstone('post', postId);
|
|
21856
22097
|
}
|
|
21857
22098
|
throw error;
|
|
21858
22099
|
}
|
|
@@ -22632,7 +22873,7 @@ const deletePost = async (postId, permanent = false) => {
|
|
|
22632
22873
|
fireEvent('post.deleted', { posts: [deleted] });
|
|
22633
22874
|
if (permanent) {
|
|
22634
22875
|
setTimeout(() => {
|
|
22635
|
-
|
|
22876
|
+
pushToTombstone('post', postId);
|
|
22636
22877
|
}, 0);
|
|
22637
22878
|
}
|
|
22638
22879
|
else {
|
|
@@ -23028,17 +23269,6 @@ const deleteComment = async (commentId, permanent = false) => {
|
|
|
23028
23269
|
return deleted;
|
|
23029
23270
|
};
|
|
23030
23271
|
|
|
23031
|
-
/** @hidden */
|
|
23032
|
-
const fetchReference = async (referenceType, referenceId) => {
|
|
23033
|
-
if (referenceType === 'message')
|
|
23034
|
-
return getMessage(referenceId);
|
|
23035
|
-
if (referenceType === 'post')
|
|
23036
|
-
return getPost(referenceId);
|
|
23037
|
-
if (referenceType === 'comment')
|
|
23038
|
-
return getComment(referenceId);
|
|
23039
|
-
throw new Error(`Incorrect referenceType: ${referenceType}`);
|
|
23040
|
-
};
|
|
23041
|
-
|
|
23042
23272
|
/** @hidden */
|
|
23043
23273
|
const preparePayloadForCache = (event, payload) => {
|
|
23044
23274
|
var _a, _b;
|
|
@@ -23126,7 +23356,6 @@ const prepareMessagePayloadForCache = (payload) => {
|
|
|
23126
23356
|
* @async
|
|
23127
23357
|
* */
|
|
23128
23358
|
const addReaction = async (referenceType, referenceId, reactionName) => {
|
|
23129
|
-
var _a, _b;
|
|
23130
23359
|
const client = getActiveClient();
|
|
23131
23360
|
client.log('reaction/createReaction', {
|
|
23132
23361
|
referenceId,
|
|
@@ -23138,9 +23367,7 @@ const addReaction = async (referenceType, referenceId, reactionName) => {
|
|
|
23138
23367
|
referenceType,
|
|
23139
23368
|
reactionName,
|
|
23140
23369
|
});
|
|
23141
|
-
|
|
23142
|
-
dispatchReactable(referenceType, model.data);
|
|
23143
|
-
return (_b = (_a = model.data.myReactions) === null || _a === void 0 ? void 0 : _a.includes(reactionName)) !== null && _b !== void 0 ? _b : false;
|
|
23370
|
+
return true;
|
|
23144
23371
|
};
|
|
23145
23372
|
/**
|
|
23146
23373
|
* ```js
|
|
@@ -23197,7 +23424,6 @@ addReaction.optimistically = (referenceType, referenceId, reactionName) => {
|
|
|
23197
23424
|
* @async
|
|
23198
23425
|
* */
|
|
23199
23426
|
const removeReaction = async (referenceType, referenceId, reactionName) => {
|
|
23200
|
-
var _a, _b;
|
|
23201
23427
|
const client = getActiveClient();
|
|
23202
23428
|
client.log('reaction/removeReaction', {
|
|
23203
23429
|
referenceId,
|
|
@@ -23207,9 +23433,7 @@ const removeReaction = async (referenceType, referenceId, reactionName) => {
|
|
|
23207
23433
|
await client.http.delete(`/api/v2/reactions`, {
|
|
23208
23434
|
data: { referenceId, referenceType, reactionName },
|
|
23209
23435
|
});
|
|
23210
|
-
|
|
23211
|
-
dispatchReactable(referenceType, model.data);
|
|
23212
|
-
return (_b = !((_a = model.data.myReactions) === null || _a === void 0 ? void 0 : _a.includes(reactionName))) !== null && _b !== void 0 ? _b : false;
|
|
23436
|
+
return true;
|
|
23213
23437
|
};
|
|
23214
23438
|
/**
|
|
23215
23439
|
* ```js
|
|
@@ -23886,10 +24110,6 @@ const onReactorRemoved = (referenceType, referenceId, callback) => {
|
|
|
23886
24110
|
return createEventSubscriber(client, 'comment.removeReaction', 'comment.removeReaction', filter);
|
|
23887
24111
|
};
|
|
23888
24112
|
|
|
23889
|
-
const COLLECTION_DEFAULT_PAGINATION_LIMIT = 5;
|
|
23890
|
-
const COLLECTION_DEFAULT_CACHING_POLICY = 'cache_then_server';
|
|
23891
|
-
const ENABLE_CACHE_MESSAGE = 'For using Live Collection feature you need to enable Cache!';
|
|
23892
|
-
|
|
23893
24113
|
/**
|
|
23894
24114
|
* ```js
|
|
23895
24115
|
* import { liveReactions } from '@amityco/ts-sdk'
|
|
@@ -24166,9 +24386,24 @@ const queryChannels = async (query) => {
|
|
|
24166
24386
|
* @category Channel API
|
|
24167
24387
|
*/
|
|
24168
24388
|
queryChannels.locally = (query) => {
|
|
24389
|
+
var _a, _b;
|
|
24169
24390
|
const client = getActiveClient();
|
|
24170
24391
|
client.log('channel/queryChannels.locally', query);
|
|
24171
|
-
|
|
24392
|
+
const _c = query !== null && query !== void 0 ? query : {}, { page = { limit: 10 } } = _c, params = __rest(_c, ["page"]);
|
|
24393
|
+
const cacheKey = ['channel', 'query', Object.assign(Object.assign({}, params), { options: Object.assign({}, page) })];
|
|
24394
|
+
const { data, cachedAt } = (_a = pullFromCache(cacheKey)) !== null && _a !== void 0 ? _a : {};
|
|
24395
|
+
if (!(data === null || data === void 0 ? void 0 : data.channels.length))
|
|
24396
|
+
return;
|
|
24397
|
+
const channels = data.channels
|
|
24398
|
+
// ck -> cacheKey, abbrevated to avoid confusion from the above cache key
|
|
24399
|
+
.map(ck => pullFromCache(['channel', 'get', ck]))
|
|
24400
|
+
.filter(Boolean)
|
|
24401
|
+
.map(({ data }) => data);
|
|
24402
|
+
const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
|
|
24403
|
+
const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
|
|
24404
|
+
return channels.length === ((_b = data === null || data === void 0 ? void 0 : data.channels) === null || _b === void 0 ? void 0 : _b.length)
|
|
24405
|
+
? { data: channels, cachedAt, prevPage, nextPage }
|
|
24406
|
+
: undefined;
|
|
24172
24407
|
};
|
|
24173
24408
|
|
|
24174
24409
|
/**
|
|
@@ -24251,9 +24486,18 @@ getChannels.locally = (channelIds) => {
|
|
|
24251
24486
|
const getChannel = async (channelId) => {
|
|
24252
24487
|
const client = getActiveClient();
|
|
24253
24488
|
client.log('channel/getChannel', channelId);
|
|
24254
|
-
|
|
24255
|
-
|
|
24256
|
-
|
|
24489
|
+
isInTombstone('channel', channelId);
|
|
24490
|
+
let data;
|
|
24491
|
+
try {
|
|
24492
|
+
const { data: payload } = await client.http.get(`/api/v3/channels/${encodeURIComponent(channelId)}`);
|
|
24493
|
+
data = prepareChannelPayload(payload);
|
|
24494
|
+
}
|
|
24495
|
+
catch (error) {
|
|
24496
|
+
if (checkIfShouldGoesToTombstone(error === null || error === void 0 ? void 0 : error.code)) {
|
|
24497
|
+
pushToTombstone('channel', channelId);
|
|
24498
|
+
}
|
|
24499
|
+
throw error;
|
|
24500
|
+
}
|
|
24257
24501
|
const cachedAt = client.cache && Date.now();
|
|
24258
24502
|
if (client.cache)
|
|
24259
24503
|
ingestInCache(data, { cachedAt });
|
|
@@ -24445,8 +24689,8 @@ const leaveChannel = async (channelId) => {
|
|
|
24445
24689
|
const queryChannelMembers = async (query) => {
|
|
24446
24690
|
const client = getActiveClient();
|
|
24447
24691
|
client.log('channel/queryChannelMembers', query);
|
|
24448
|
-
const _a = query !== null && query !== void 0 ? query : {}, { page
|
|
24449
|
-
const { data: queryPayload } = await client.http.get(`/api/v4/channels/${encodeURIComponent(channelId)}/users`, {
|
|
24692
|
+
const _a = query !== null && query !== void 0 ? query : {}, { page = { limit: 10 } } = _a, params = __rest(_a, ["page"]);
|
|
24693
|
+
const { data: queryPayload } = await client.http.get(`/api/v4/channels/${encodeURIComponent(params.channelId)}/users`, {
|
|
24450
24694
|
params: Object.assign(Object.assign({}, params), { options: {
|
|
24451
24695
|
token: toToken(page, 'skiplimit'),
|
|
24452
24696
|
} }),
|
|
@@ -24457,6 +24701,15 @@ const queryChannelMembers = async (query) => {
|
|
|
24457
24701
|
const cachedAt = client.cache && Date.now();
|
|
24458
24702
|
if (client.cache) {
|
|
24459
24703
|
ingestInCache(data);
|
|
24704
|
+
const cacheKey = [
|
|
24705
|
+
'channelUsers',
|
|
24706
|
+
'query',
|
|
24707
|
+
Object.assign(Object.assign({}, params), { options: Object.assign({}, page) }),
|
|
24708
|
+
];
|
|
24709
|
+
pushToCache(cacheKey, {
|
|
24710
|
+
channelUsers: channelUsers.map(({ channelId, userId }) => getResolver('channelUsers')({ channelId, userId })),
|
|
24711
|
+
paging,
|
|
24712
|
+
});
|
|
24460
24713
|
}
|
|
24461
24714
|
const nextPage = toPage(paging.next);
|
|
24462
24715
|
const prevPage = toPage(paging.previous);
|
|
@@ -24476,9 +24729,30 @@ const queryChannelMembers = async (query) => {
|
|
|
24476
24729
|
* @category Post API
|
|
24477
24730
|
*/
|
|
24478
24731
|
queryChannelMembers.locally = (query) => {
|
|
24732
|
+
var _a, _b;
|
|
24479
24733
|
const client = getActiveClient();
|
|
24480
|
-
client.log('channel/queryChannelMembers', query);
|
|
24481
|
-
|
|
24734
|
+
client.log('channel/queryChannelMembers.locally', query);
|
|
24735
|
+
if (!client.cache)
|
|
24736
|
+
return;
|
|
24737
|
+
const { page = { limit: 10 } } = query, params = __rest(query, ["page"]);
|
|
24738
|
+
const cacheKey = [
|
|
24739
|
+
'channelUsers',
|
|
24740
|
+
'query',
|
|
24741
|
+
Object.assign(Object.assign({}, params), { options: Object.assign({}, page) }),
|
|
24742
|
+
];
|
|
24743
|
+
const { data, cachedAt } = (_a = pullFromCache(cacheKey)) !== null && _a !== void 0 ? _a : {};
|
|
24744
|
+
if (!(data === null || data === void 0 ? void 0 : data.channelUsers.length))
|
|
24745
|
+
return;
|
|
24746
|
+
const channelUsers = data.channelUsers
|
|
24747
|
+
// ck -> cacheKey, abbrevated to avoid confusion from the above cache key
|
|
24748
|
+
.map(ck => pullFromCache(['channelUsers', 'get', ck]))
|
|
24749
|
+
.filter(Boolean)
|
|
24750
|
+
.map(({ data }) => data);
|
|
24751
|
+
const prevPage = toPage(data === null || data === void 0 ? void 0 : data.paging.previous);
|
|
24752
|
+
const nextPage = toPage(data === null || data === void 0 ? void 0 : data.paging.next);
|
|
24753
|
+
return channelUsers.length === ((_b = data === null || data === void 0 ? void 0 : data.channelUsers) === null || _b === void 0 ? void 0 : _b.length)
|
|
24754
|
+
? { data: channelUsers, cachedAt, prevPage, nextPage }
|
|
24755
|
+
: undefined;
|
|
24482
24756
|
};
|
|
24483
24757
|
|
|
24484
24758
|
/**
|
|
@@ -24503,7 +24777,10 @@ const addChannelMembers = async (channelId, userIds) => {
|
|
|
24503
24777
|
const data = prepareChannelPayload(payload);
|
|
24504
24778
|
if (client.cache)
|
|
24505
24779
|
ingestInCache(data);
|
|
24506
|
-
|
|
24780
|
+
/*
|
|
24781
|
+
* should fire event for each user that was added
|
|
24782
|
+
*/
|
|
24783
|
+
userIds.forEach(id => fireEvent('v3.channel.didAddUsers', Object.assign(Object.assign({}, data), { channelUsers: data.channelUsers.filter(u => u.userId === id) })));
|
|
24507
24784
|
const { channelUsers } = data;
|
|
24508
24785
|
return !!channelUsers.find(channelUser => channelUser.channelId === channelId && channelUser.membership === 'member');
|
|
24509
24786
|
};
|
|
@@ -24826,6 +25103,56 @@ const onChannelMemberRemoved = (callback) => {
|
|
|
24826
25103
|
return createEventSubscriber(client, 'onChannelMemberRemoved', 'v3.channel.didRemoveUsers', filter);
|
|
24827
25104
|
};
|
|
24828
25105
|
|
|
25106
|
+
/**
|
|
25107
|
+
* ```js
|
|
25108
|
+
* import { onChannelMemberBanned } from '@amityco/ts-sdk'
|
|
25109
|
+
* const dispose = onChannelMemberBanned((channel, member) => {
|
|
25110
|
+
* // ...
|
|
25111
|
+
* })
|
|
25112
|
+
* ```
|
|
25113
|
+
*
|
|
25114
|
+
* Fired when any {@link Amity.User} has been banned from any {@link Amity.Channel}
|
|
25115
|
+
*
|
|
25116
|
+
* @param callback The function to call when the event was fired
|
|
25117
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
25118
|
+
*
|
|
25119
|
+
* @category Channel Events
|
|
25120
|
+
*/
|
|
25121
|
+
const onChannelMemberBanned = (callback) => {
|
|
25122
|
+
const client = getActiveClient();
|
|
25123
|
+
const filter = (payload) => {
|
|
25124
|
+
const data = prepareChannelPayload(payload);
|
|
25125
|
+
ingestInCache(data);
|
|
25126
|
+
callback(data.channels[0], data.channelUsers.find(cu => cu.membership === 'banned'));
|
|
25127
|
+
};
|
|
25128
|
+
return createEventSubscriber(client, 'onChannelMemberBanned', 'v3.channel.didBan', filter);
|
|
25129
|
+
};
|
|
25130
|
+
|
|
25131
|
+
/**
|
|
25132
|
+
* ```js
|
|
25133
|
+
* import { onChannelMemberUnbanned } from '@amityco/ts-sdk'
|
|
25134
|
+
* const dispose = onChannelMemberUnbanned((channel, member) => {
|
|
25135
|
+
* // ...
|
|
25136
|
+
* })
|
|
25137
|
+
* ```
|
|
25138
|
+
*
|
|
25139
|
+
* Fired when any {@link Amity.User} has been unbanned from any {@link Amity.Channel}
|
|
25140
|
+
*
|
|
25141
|
+
* @param callback The function to call when the event was fired
|
|
25142
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
25143
|
+
*
|
|
25144
|
+
* @category Channel Events
|
|
25145
|
+
*/
|
|
25146
|
+
const onChannelMemberUnbanned = (callback) => {
|
|
25147
|
+
const client = getActiveClient();
|
|
25148
|
+
const filter = (payload) => {
|
|
25149
|
+
const data = prepareChannelPayload(payload);
|
|
25150
|
+
ingestInCache(data);
|
|
25151
|
+
callback(data.channels[0], data.channelUsers.find(cu => cu.membership === 'none'));
|
|
25152
|
+
};
|
|
25153
|
+
return createEventSubscriber(client, 'onChannelMemberBanned', 'v3.channel.didUnban', filter);
|
|
25154
|
+
};
|
|
25155
|
+
|
|
24829
25156
|
/**
|
|
24830
25157
|
* ```js
|
|
24831
25158
|
* import { observeChannel } from '@amityco/ts-sdk'
|
|
@@ -24920,7 +25247,7 @@ const observeChannels = (callback) => {
|
|
|
24920
25247
|
* @category Channel Live Collection
|
|
24921
25248
|
*/
|
|
24922
25249
|
const liveChannels = (params, callback, config) => {
|
|
24923
|
-
const { log, cache } = getActiveClient();
|
|
25250
|
+
const { log, cache, userId } = getActiveClient();
|
|
24924
25251
|
if (!cache) {
|
|
24925
25252
|
console.log(ENABLE_CACHE_MESSAGE);
|
|
24926
25253
|
}
|
|
@@ -24948,6 +25275,10 @@ const liveChannels = (params, callback, config) => {
|
|
|
24948
25275
|
if (params.excludeTags) {
|
|
24949
25276
|
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); })); });
|
|
24950
25277
|
}
|
|
25278
|
+
// userId is required to be able to filter channel by current active user
|
|
25279
|
+
if (params.membership && userId) {
|
|
25280
|
+
channels = filterByChannelMembership(channels, params.membership, userId);
|
|
25281
|
+
}
|
|
24951
25282
|
const sortBy = params.sortBy || 'lastCreated';
|
|
24952
25283
|
if (sortBy === 'lastCreated' || sortBy === 'firstCreated') {
|
|
24953
25284
|
channels = channels.sort(sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated);
|
|
@@ -25057,7 +25388,20 @@ const liveChannelMembers = (params, callback, config) => {
|
|
|
25057
25388
|
.filter(Boolean)
|
|
25058
25389
|
.map(({ data }) => data)) !== null && _a !== void 0 ? _a : [];
|
|
25059
25390
|
channelMembers = filterByPropEquality(channelMembers, 'roles', params.roles);
|
|
25060
|
-
|
|
25391
|
+
if (params.memberships) {
|
|
25392
|
+
/*
|
|
25393
|
+
* even though membership includes muted as a possible value
|
|
25394
|
+
* when querying the server.
|
|
25395
|
+
* Muted is specified under seperarte property namely isMuted
|
|
25396
|
+
* Hence why I've seperately checked for it's equality
|
|
25397
|
+
*/
|
|
25398
|
+
if (params.memberships.some(m => ['member', 'banned'].includes(m))) {
|
|
25399
|
+
channelMembers = filterByPropInclusion(channelMembers, 'membership', params.memberships);
|
|
25400
|
+
}
|
|
25401
|
+
if (params.memberships.includes('muted')) {
|
|
25402
|
+
channelMembers = filterByPropEquality(channelMembers, 'isMuted', true);
|
|
25403
|
+
}
|
|
25404
|
+
}
|
|
25061
25405
|
if (params.search) {
|
|
25062
25406
|
const containsMatcher = new RegExp(params.search);
|
|
25063
25407
|
channelMembers = channelMembers.filter(m => m.userId.match(containsMatcher));
|
|
@@ -25085,7 +25429,7 @@ const liveChannelMembers = (params, callback, config) => {
|
|
|
25085
25429
|
if (action === 'onMemberAdded') {
|
|
25086
25430
|
collection.data = [...new Set([channelMemberCacheId, ...collection.data])];
|
|
25087
25431
|
}
|
|
25088
|
-
|
|
25432
|
+
if (action === 'onMemberRemoved') {
|
|
25089
25433
|
collection.data = collection.data.filter(m => m !== channelMemberCacheId);
|
|
25090
25434
|
}
|
|
25091
25435
|
pushToCache(cacheKey, collection);
|
|
@@ -25112,7 +25456,7 @@ const liveChannelMembers = (params, callback, config) => {
|
|
|
25112
25456
|
responder(data);
|
|
25113
25457
|
}, queryOptions(policy));
|
|
25114
25458
|
};
|
|
25115
|
-
disposers.push(onChannelMemberAdded((_, member) => realtimeRouter(member, 'onMemberAdded')), onChannelMemberRemoved((_, member) => realtimeRouter(member, 'onMemberRemoved')));
|
|
25459
|
+
disposers.push(onChannelMemberAdded((_, member) => realtimeRouter(member, 'onMemberAdded')), onChannelMemberRemoved((_, member) => realtimeRouter(member, 'onMemberRemoved')), onChannelMemberBanned((_, member) => realtimeRouter(member, 'onChannelMemberBanned')), onChannelMemberUnbanned((_, member) => realtimeRouter(member, 'onChannelMemberUnbanned')));
|
|
25116
25460
|
onFetch();
|
|
25117
25461
|
return () => {
|
|
25118
25462
|
log(`liveChannelMembers(tmpid: ${timestamp}) > dispose`);
|
|
@@ -25199,82 +25543,92 @@ const onMessageDeleted = (callback) => {
|
|
|
25199
25543
|
|
|
25200
25544
|
/**
|
|
25201
25545
|
* ```js
|
|
25202
|
-
* import {
|
|
25203
|
-
*
|
|
25204
|
-
*
|
|
25205
|
-
*
|
|
25546
|
+
* import { onMessageFetched } from '@amityco/ts-sdk'
|
|
25547
|
+
* const dispose = onMessageFetched(message => {
|
|
25548
|
+
* // ...
|
|
25549
|
+
* })
|
|
25206
25550
|
* ```
|
|
25207
25551
|
*
|
|
25208
|
-
*
|
|
25552
|
+
* Fired when an {@link Amity.Message} has been fetched
|
|
25209
25553
|
*
|
|
25210
|
-
* @param
|
|
25211
|
-
* @
|
|
25212
|
-
* @param callback the function to call when new data are available
|
|
25213
|
-
* @param policy a query policy option for this observer
|
|
25214
|
-
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the message
|
|
25554
|
+
* @param callback The function to call when the event was fired
|
|
25555
|
+
* @returns an {@link Amity.Unsubscriber} function to stop listening
|
|
25215
25556
|
*
|
|
25216
|
-
* @category Message
|
|
25557
|
+
* @category Message Events
|
|
25217
25558
|
*/
|
|
25218
|
-
const
|
|
25219
|
-
const
|
|
25220
|
-
const
|
|
25221
|
-
|
|
25222
|
-
|
|
25223
|
-
const router = (result, action) => {
|
|
25224
|
-
var _a, _b, _c;
|
|
25225
|
-
// filter function
|
|
25226
|
-
if (((_a = result.data) === null || _a === void 0 ? void 0 : _a.messageId) !== messageId)
|
|
25227
|
-
return;
|
|
25228
|
-
if (callback instanceof Function)
|
|
25229
|
-
return callback(result);
|
|
25230
|
-
if (action !== 'onFetch')
|
|
25231
|
-
(_b = callback.onEvent) === null || _b === void 0 ? void 0 : _b.call(callback, action, result);
|
|
25232
|
-
(_c = callback[action]) === null || _c === void 0 ? void 0 : _c.call(callback, result);
|
|
25233
|
-
};
|
|
25234
|
-
const disposers = [];
|
|
25235
|
-
disposers.push(onMessageUpdated(data => router({ data, loading: false, origin: 'event' }, 'onUpdate')), onMessageDeleted(data => router({ data, loading: false, origin: 'event' }, 'onDelete')));
|
|
25236
|
-
if (policy !== 'no_fetch') {
|
|
25237
|
-
runQuery(createQuery(getMessage, messageId), result => result.data && router(result, 'onFetch'), queryOptions(policy));
|
|
25238
|
-
}
|
|
25239
|
-
return () => {
|
|
25240
|
-
log(`observeMessages(tmpid: ${timestamp}) > dispose`);
|
|
25241
|
-
disposers.forEach(fn => fn());
|
|
25559
|
+
const onMessageFetched = (callback) => {
|
|
25560
|
+
const client = getActiveClient();
|
|
25561
|
+
const filter = (payload) => {
|
|
25562
|
+
ingestInCache(payload);
|
|
25563
|
+
callback(payload.messages[0]);
|
|
25242
25564
|
};
|
|
25565
|
+
return createEventSubscriber(client, 'message/onMessageFetched', 'v3.message.didFetch', filter);
|
|
25243
25566
|
};
|
|
25244
25567
|
|
|
25245
25568
|
/**
|
|
25246
25569
|
* ```js
|
|
25247
|
-
* import {
|
|
25570
|
+
* import { liveMessage } from '@amityco/ts-sdk'
|
|
25248
25571
|
*
|
|
25249
25572
|
* let messages = []
|
|
25250
|
-
* const unsub =
|
|
25573
|
+
* const unsub = liveMessage(messageId, response => merge(messages, response.data))
|
|
25251
25574
|
* ```
|
|
25252
25575
|
*
|
|
25253
|
-
* Observe all
|
|
25576
|
+
* Observe all mutation on a given {@link Amity.Message}
|
|
25254
25577
|
*
|
|
25255
|
-
* @param
|
|
25578
|
+
* @param messageId the ID of the message to observe
|
|
25256
25579
|
* @param callback the function to call when new data are available
|
|
25257
25580
|
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
|
|
25258
25581
|
*
|
|
25259
|
-
* @category Message
|
|
25582
|
+
* @category Message Live Object
|
|
25260
25583
|
*/
|
|
25261
|
-
const
|
|
25262
|
-
const { log } = getActiveClient();
|
|
25584
|
+
const liveMessage = (messageId, callback) => {
|
|
25585
|
+
const { log, cache } = getActiveClient();
|
|
25586
|
+
let message;
|
|
25587
|
+
let isUnsyncedObject = false;
|
|
25588
|
+
if (!cache) {
|
|
25589
|
+
console.log(LIVE_OBJECT_ENABLE_CACHE_MESSAGE);
|
|
25590
|
+
}
|
|
25263
25591
|
const timestamp = Date.now();
|
|
25264
|
-
log(`
|
|
25592
|
+
log(`liveMessage(tmpid: ${timestamp}) > listen`);
|
|
25265
25593
|
const disposers = [];
|
|
25266
|
-
const
|
|
25267
|
-
var _a
|
|
25268
|
-
|
|
25594
|
+
const dispatcher = (data) => {
|
|
25595
|
+
var _a;
|
|
25596
|
+
// we check updatedAt to see if the current snapshot is new so
|
|
25597
|
+
// we won't send old data back, only fresh new data
|
|
25598
|
+
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')
|
|
25269
25599
|
return;
|
|
25270
|
-
|
|
25271
|
-
|
|
25272
|
-
(_b = callback.onEvent) === null || _b === void 0 ? void 0 : _b.call(callback, action, message);
|
|
25273
|
-
(_c = callback[action]) === null || _c === void 0 ? void 0 : _c.call(callback, message);
|
|
25600
|
+
callback(data);
|
|
25601
|
+
message = data.data;
|
|
25274
25602
|
};
|
|
25275
|
-
|
|
25603
|
+
const realtimeRouter = (message, action) => {
|
|
25604
|
+
dispatcher({ loading: false, data: message, origin: 'event' });
|
|
25605
|
+
};
|
|
25606
|
+
const onFetch = () => {
|
|
25607
|
+
const query = createQuery(getMessage, messageId, true);
|
|
25608
|
+
runQuery(query, ({ loading, data, error, origin, cachedAt }) => {
|
|
25609
|
+
if (cachedAt === UNSYNCED_OBJECT_CACHED_AT_VALUE) {
|
|
25610
|
+
dispatcher({
|
|
25611
|
+
data,
|
|
25612
|
+
origin,
|
|
25613
|
+
loading: false,
|
|
25614
|
+
error: new ASCApiError(UNSYNCED_OBJECT_CACHED_AT_MESSAGE, 800800 /* Amity.ClientError.DISALOOW_UNSYNCED_OBJECT */, "error" /* Amity.ErrorLevel.ERROR */),
|
|
25615
|
+
});
|
|
25616
|
+
isUnsyncedObject = true;
|
|
25617
|
+
disposers.forEach(fn => fn());
|
|
25618
|
+
}
|
|
25619
|
+
else if (!isUnsyncedObject) {
|
|
25620
|
+
dispatcher({ loading, data, origin, error });
|
|
25621
|
+
}
|
|
25622
|
+
if (error) {
|
|
25623
|
+
// Terminate observe functionality on error
|
|
25624
|
+
disposers.forEach(fn => fn());
|
|
25625
|
+
}
|
|
25626
|
+
});
|
|
25627
|
+
};
|
|
25628
|
+
disposers.push(onMessageFetched(message => realtimeRouter(message)), onMessageUpdated(message => realtimeRouter(message)), onMessageDeleted(message => realtimeRouter(message)));
|
|
25629
|
+
onFetch();
|
|
25276
25630
|
return () => {
|
|
25277
|
-
log(`
|
|
25631
|
+
log(`liveMessage(tmpid: ${timestamp}) > dispose`);
|
|
25278
25632
|
disposers.forEach(fn => fn());
|
|
25279
25633
|
};
|
|
25280
25634
|
};
|
|
@@ -25363,7 +25717,7 @@ const liveMessages = (params, callback, config) => {
|
|
|
25363
25717
|
responder(data);
|
|
25364
25718
|
}, queryOptions(policy));
|
|
25365
25719
|
};
|
|
25366
|
-
disposers.push(onMessageCreated(message => realtimeRouter(message, 'onCreate')), onMessageDeleted(message => realtimeRouter(message, 'onDelete')), onMessageUpdated(message => realtimeRouter(message, 'onUpdate')));
|
|
25720
|
+
disposers.push(onMessageFetched(message => realtimeRouter(message, 'onFetch')), onMessageCreated(message => realtimeRouter(message, 'onCreate')), onMessageDeleted(message => realtimeRouter(message, 'onDelete')), onMessageUpdated(message => realtimeRouter(message, 'onUpdate')));
|
|
25367
25721
|
onFetch();
|
|
25368
25722
|
return () => {
|
|
25369
25723
|
log(`liveMessages(tmpid: ${timestamp}) > dispose`);
|
|
@@ -25371,6 +25725,89 @@ const liveMessages = (params, callback, config) => {
|
|
|
25371
25725
|
};
|
|
25372
25726
|
};
|
|
25373
25727
|
|
|
25728
|
+
/**
|
|
25729
|
+
* ```js
|
|
25730
|
+
* import { observeMessage } from '@amityco/ts-sdk'
|
|
25731
|
+
*
|
|
25732
|
+
* let message = {}
|
|
25733
|
+
* const unsub = observeMessage(messageId, updated => message = updated)
|
|
25734
|
+
* ```
|
|
25735
|
+
*
|
|
25736
|
+
* Observe all mutations on a {@link Amity.Message} given a single messageId
|
|
25737
|
+
*
|
|
25738
|
+
* @param client the client to observe the message with
|
|
25739
|
+
* @param messageId the ID of the message to observe
|
|
25740
|
+
* @param callback the function to call when new data are available
|
|
25741
|
+
* @param policy a query policy option for this observer
|
|
25742
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the message
|
|
25743
|
+
*
|
|
25744
|
+
* @category Message Observer
|
|
25745
|
+
*/
|
|
25746
|
+
const observeMessage = (messageId, callback, policy = 'cache_then_server') => {
|
|
25747
|
+
const { log } = getActiveClient();
|
|
25748
|
+
const timestamp = Date.now();
|
|
25749
|
+
log(`observeMessage(tmpid: ${timestamp}) > listen`);
|
|
25750
|
+
console.log('observeMessage will be deprecated on 15th November 2022, please use liveMessage instead.');
|
|
25751
|
+
// wrapper function to make sure
|
|
25752
|
+
const router = (result, action) => {
|
|
25753
|
+
var _a, _b, _c;
|
|
25754
|
+
// filter function
|
|
25755
|
+
if (((_a = result.data) === null || _a === void 0 ? void 0 : _a.messageId) !== messageId)
|
|
25756
|
+
return;
|
|
25757
|
+
if (callback instanceof Function)
|
|
25758
|
+
return callback(result);
|
|
25759
|
+
if (action !== 'onFetch')
|
|
25760
|
+
(_b = callback.onEvent) === null || _b === void 0 ? void 0 : _b.call(callback, action, result);
|
|
25761
|
+
(_c = callback[action]) === null || _c === void 0 ? void 0 : _c.call(callback, result);
|
|
25762
|
+
};
|
|
25763
|
+
const disposers = [];
|
|
25764
|
+
disposers.push(onMessageUpdated(data => router({ data, loading: false, origin: 'event' }, 'onUpdate')), onMessageDeleted(data => router({ data, loading: false, origin: 'event' }, 'onDelete')));
|
|
25765
|
+
if (policy !== 'no_fetch') {
|
|
25766
|
+
runQuery(createQuery(getMessage, messageId), result => result.data && router(result, 'onFetch'), queryOptions(policy));
|
|
25767
|
+
}
|
|
25768
|
+
return () => {
|
|
25769
|
+
log(`observeMessages(tmpid: ${timestamp}) > dispose`);
|
|
25770
|
+
disposers.forEach(fn => fn());
|
|
25771
|
+
};
|
|
25772
|
+
};
|
|
25773
|
+
|
|
25774
|
+
/**
|
|
25775
|
+
* ```js
|
|
25776
|
+
* import { observeMessages } from '@amityco/ts-sdk'
|
|
25777
|
+
*
|
|
25778
|
+
* let messages = []
|
|
25779
|
+
* const unsub = observeMessages(channelId, message => merge(messages, message))
|
|
25780
|
+
* ```
|
|
25781
|
+
*
|
|
25782
|
+
* Observe all mutations on a list of {@link Amity.Message} for a given {@link Amity.Channel} object
|
|
25783
|
+
*
|
|
25784
|
+
* @param channelId the ID of the channel where to observe the messages
|
|
25785
|
+
* @param callback the function to call when new data are available
|
|
25786
|
+
* @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the messages
|
|
25787
|
+
*
|
|
25788
|
+
* @category Message Observer
|
|
25789
|
+
*/
|
|
25790
|
+
const observeMessages = (channelId, callback) => {
|
|
25791
|
+
const { log } = getActiveClient();
|
|
25792
|
+
const timestamp = Date.now();
|
|
25793
|
+
log(`observeMessages(tmpid: ${timestamp}) > listen`);
|
|
25794
|
+
const disposers = [];
|
|
25795
|
+
const router = (message, action) => {
|
|
25796
|
+
var _a, _b, _c;
|
|
25797
|
+
if (((_a = message.data) === null || _a === void 0 ? void 0 : _a.channelId) !== channelId)
|
|
25798
|
+
return;
|
|
25799
|
+
if (callback instanceof Function)
|
|
25800
|
+
return callback(message);
|
|
25801
|
+
(_b = callback.onEvent) === null || _b === void 0 ? void 0 : _b.call(callback, action, message);
|
|
25802
|
+
(_c = callback[action]) === null || _c === void 0 ? void 0 : _c.call(callback, message);
|
|
25803
|
+
};
|
|
25804
|
+
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')));
|
|
25805
|
+
return () => {
|
|
25806
|
+
log(`observeMessages(tmpid: ${timestamp}) > dispose`);
|
|
25807
|
+
disposers.forEach(fn => fn());
|
|
25808
|
+
};
|
|
25809
|
+
};
|
|
25810
|
+
|
|
25374
25811
|
const createCommunityEventSubscriber = (event, callback) => {
|
|
25375
25812
|
const client = getActiveClient();
|
|
25376
25813
|
const filter = (payload) => {
|
|
@@ -27559,6 +27996,8 @@ exports.CommunityPostSettings = CommunityPostSettings;
|
|
|
27559
27996
|
exports.ContentFeedType = ContentFeedType;
|
|
27560
27997
|
exports.DefaultCommunityPostSetting = DefaultCommunityPostSetting;
|
|
27561
27998
|
exports.FileType = FileType;
|
|
27999
|
+
exports.MessageContentType = MessageContentType;
|
|
28000
|
+
exports.PostContentType = PostContentType;
|
|
27562
28001
|
exports.VERSION = VERSION$1;
|
|
27563
28002
|
exports.VideoResolution = VideoResolution;
|
|
27564
28003
|
exports.VideoSize = VideoSize;
|
|
@@ -27605,6 +28044,7 @@ exports.disposeStream = disposeStream;
|
|
|
27605
28044
|
exports.dropFromCache = dropFromCache;
|
|
27606
28045
|
exports.enableCache = enableCache;
|
|
27607
28046
|
exports.fileUrlWithSize = fileUrlWithSize;
|
|
28047
|
+
exports.filterByChannelMembership = filterByChannelMembership;
|
|
27608
28048
|
exports.filterByPropEquality = filterByPropEquality;
|
|
27609
28049
|
exports.filterByPropInclusion = filterByPropInclusion;
|
|
27610
28050
|
exports.follow = follow;
|
|
@@ -27658,9 +28098,11 @@ exports.liveChannels = liveChannels;
|
|
|
27658
28098
|
exports.liveComments = liveComments;
|
|
27659
28099
|
exports.liveFollowers = liveFollowers;
|
|
27660
28100
|
exports.liveFollowings = liveFollowings;
|
|
28101
|
+
exports.liveMessage = liveMessage;
|
|
27661
28102
|
exports.liveMessages = liveMessages;
|
|
27662
28103
|
exports.livePosts = livePosts;
|
|
27663
28104
|
exports.liveReactions = liveReactions;
|
|
28105
|
+
exports.liveUser = liveUser;
|
|
27664
28106
|
exports.mergeInCache = mergeInCache;
|
|
27665
28107
|
exports.observeChannel = observeChannel;
|
|
27666
28108
|
exports.observeChannels = observeChannels;
|
|
@@ -27682,7 +28124,9 @@ exports.onChannelDeleted = onChannelDeleted;
|
|
|
27682
28124
|
exports.onChannelJoined = onChannelJoined;
|
|
27683
28125
|
exports.onChannelLeft = onChannelLeft;
|
|
27684
28126
|
exports.onChannelMemberAdded = onChannelMemberAdded;
|
|
28127
|
+
exports.onChannelMemberBanned = onChannelMemberBanned;
|
|
27685
28128
|
exports.onChannelMemberRemoved = onChannelMemberRemoved;
|
|
28129
|
+
exports.onChannelMemberUnbanned = onChannelMemberUnbanned;
|
|
27686
28130
|
exports.onChannelUpdated = onChannelUpdated;
|
|
27687
28131
|
exports.onClientBanned = onClientBanned;
|
|
27688
28132
|
exports.onClientDisconnected = onClientDisconnected;
|
|
@@ -27711,6 +28155,7 @@ exports.onFollowerDeleted = onFollowerDeleted;
|
|
|
27711
28155
|
exports.onFollowerRequested = onFollowerRequested;
|
|
27712
28156
|
exports.onMessageCreated = onMessageCreated;
|
|
27713
28157
|
exports.onMessageDeleted = onMessageDeleted;
|
|
28158
|
+
exports.onMessageFetched = onMessageFetched;
|
|
27714
28159
|
exports.onMessageUpdated = onMessageUpdated;
|
|
27715
28160
|
exports.onPollDeleted = onPollDeleted;
|
|
27716
28161
|
exports.onPollUpdated = onPollUpdated;
|
|
@@ -27731,6 +28176,7 @@ exports.onStreamRecorded = onStreamRecorded;
|
|
|
27731
28176
|
exports.onStreamStarted = onStreamStarted;
|
|
27732
28177
|
exports.onStreamStopped = onStreamStopped;
|
|
27733
28178
|
exports.onUserDeleted = onUserDeleted;
|
|
28179
|
+
exports.onUserFetched = onUserFetched;
|
|
27734
28180
|
exports.onUserFlagCleared = onUserFlagCleared;
|
|
27735
28181
|
exports.onUserFlagged = onUserFlagged;
|
|
27736
28182
|
exports.onUserFollowed = onUserFollowed;
|