@amityco/ts-sdk 0.0.1-beta.13 → 0.0.1-beta.16
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/README.md +3 -3
- package/dist/@types/core/cache.d.ts +2 -2
- package/dist/@types/core/cache.d.ts.map +1 -1
- package/dist/@types/core/events.d.ts +12 -3
- package/dist/@types/core/events.d.ts.map +1 -1
- package/dist/@types/core/model.d.ts +4 -0
- package/dist/@types/core/model.d.ts.map +1 -1
- package/dist/@types/core/paging.d.ts +22 -41
- package/dist/@types/core/paging.d.ts.map +1 -1
- package/dist/@types/core/payload.d.ts +10 -0
- package/dist/@types/core/payload.d.ts.map +1 -1
- package/dist/@types/core/query.d.ts +13 -4
- package/dist/@types/core/query.d.ts.map +1 -1
- package/dist/@types/domains/client.d.ts +0 -1
- package/dist/@types/domains/client.d.ts.map +1 -1
- package/dist/@types/domains/comment.d.ts +1 -2
- package/dist/@types/domains/comment.d.ts.map +1 -1
- package/dist/@types/domains/follow.d.ts +20 -0
- package/dist/@types/domains/follow.d.ts.map +1 -0
- package/dist/@types/domains/mention.d.ts +23 -0
- package/dist/@types/domains/mention.d.ts.map +1 -0
- package/dist/@types/domains/message.d.ts +1 -1
- package/dist/@types/domains/message.d.ts.map +1 -1
- package/dist/@types/domains/partials.d.ts +0 -10
- package/dist/@types/domains/partials.d.ts.map +1 -1
- package/dist/@types/domains/post.d.ts +1 -2
- package/dist/@types/domains/post.d.ts.map +1 -1
- package/dist/@types/index.d.ts +2 -0
- package/dist/@types/index.d.ts.map +1 -1
- package/dist/category/api/queryCategories.d.ts +2 -2
- package/dist/channel/api/createChannel.d.ts +1 -1
- package/dist/channel/api/queryChannelMembers.d.ts.map +1 -1
- package/dist/client/api/activeUser.d.ts +6 -0
- package/dist/client/api/activeUser.d.ts.map +1 -0
- package/dist/client/api/connectClient.d.ts.map +1 -1
- package/dist/client/api/createClient.d.ts +3 -3
- package/dist/client/api/createClient.d.ts.map +1 -1
- package/dist/client/utils/endpoints.d.ts +12 -0
- package/dist/client/utils/endpoints.d.ts.map +1 -0
- package/dist/community/api/getRecommendedCommunities.d.ts +32 -0
- package/dist/community/api/getRecommendedCommunities.d.ts.map +1 -0
- package/dist/community/api/getTopTrendingCommunities.d.ts +32 -0
- package/dist/community/api/getTopTrendingCommunities.d.ts.map +1 -0
- package/dist/community/api/index.d.ts +2 -0
- package/dist/community/api/index.d.ts.map +1 -1
- package/dist/core/debug.d.ts.map +1 -1
- package/dist/core/device.d.ts.map +1 -1
- package/dist/core/events.d.ts +3 -3
- package/dist/core/events.d.ts.map +1 -1
- package/dist/core/microtasks.d.ts +13 -0
- package/dist/core/microtasks.d.ts.map +1 -0
- package/dist/core/model/idResolvers.d.ts.map +1 -1
- package/dist/core/model/identifyModel.d.ts.map +1 -1
- package/dist/core/model/index.d.ts.map +1 -1
- package/dist/core/query/paging.d.ts +5 -16
- package/dist/core/query/paging.d.ts.map +1 -1
- package/dist/core/query/query.d.ts +1 -1
- package/dist/core/query/query.d.ts.map +1 -1
- package/dist/core/subscription.d.ts +2 -0
- package/dist/core/subscription.d.ts.map +1 -1
- package/dist/feed/api/queryGlobalFeed.d.ts +22 -4
- package/dist/feed/api/queryGlobalFeed.d.ts.map +1 -1
- package/dist/follow/api/acceptFollower.d.ts +16 -0
- package/dist/follow/api/acceptFollower.d.ts.map +1 -0
- package/dist/follow/api/declineFollower.d.ts +16 -0
- package/dist/follow/api/declineFollower.d.ts.map +1 -0
- package/dist/follow/api/follow.d.ts +16 -0
- package/dist/follow/api/follow.d.ts.map +1 -0
- package/dist/follow/api/getFollowInfo.d.ts +32 -0
- package/dist/follow/api/getFollowInfo.d.ts.map +1 -0
- package/dist/follow/api/index.d.ts +8 -0
- package/dist/follow/api/index.d.ts.map +1 -0
- package/dist/follow/api/queryFollowers.d.ts +36 -0
- package/dist/follow/api/queryFollowers.d.ts.map +1 -0
- package/dist/follow/api/queryFollowings.d.ts +36 -0
- package/dist/follow/api/queryFollowings.d.ts.map +1 -0
- package/dist/follow/api/unfollow.d.ts +16 -0
- package/dist/follow/api/unfollow.d.ts.map +1 -0
- package/dist/follow/api/utils.d.ts +9 -0
- package/dist/follow/api/utils.d.ts.map +1 -0
- package/dist/follow/events/index.d.ts +9 -0
- package/dist/follow/events/index.d.ts.map +1 -0
- package/dist/follow/events/onFollowInfoUpdated.d.ts +17 -0
- package/dist/follow/events/onFollowInfoUpdated.d.ts.map +1 -0
- package/dist/follow/events/onFollowRequestAccepted.d.ts +17 -0
- package/dist/follow/events/onFollowRequestAccepted.d.ts.map +1 -0
- package/dist/follow/events/onFollowRequestCanceled.d.ts +17 -0
- package/dist/follow/events/onFollowRequestCanceled.d.ts.map +1 -0
- package/dist/follow/events/onFollowRequestDeclined.d.ts +17 -0
- package/dist/follow/events/onFollowRequestDeclined.d.ts.map +1 -0
- package/dist/follow/events/onFollowerDeleted.d.ts +17 -0
- package/dist/follow/events/onFollowerDeleted.d.ts.map +1 -0
- package/dist/follow/events/onFollowerRequested.d.ts +17 -0
- package/dist/follow/events/onFollowerRequested.d.ts.map +1 -0
- package/dist/follow/events/onUserFollowed.d.ts +17 -0
- package/dist/follow/events/onUserFollowed.d.ts.map +1 -0
- package/dist/follow/events/onUserUnfollowed.d.ts +17 -0
- package/dist/follow/events/onUserUnfollowed.d.ts.map +1 -0
- package/dist/follow/events/utils.d.ts +2 -0
- package/dist/follow/events/utils.d.ts.map +1 -0
- package/dist/follow/observers/index.d.ts +4 -0
- package/dist/follow/observers/index.d.ts.map +1 -0
- package/dist/follow/observers/observeFollowInfo.d.ts +18 -0
- package/dist/follow/observers/observeFollowInfo.d.ts.map +1 -0
- package/dist/follow/observers/observeFollowers.d.ts +18 -0
- package/dist/follow/observers/observeFollowers.d.ts.map +1 -0
- package/dist/follow/observers/observeFollowings.d.ts +18 -0
- package/dist/follow/observers/observeFollowings.d.ts.map +1 -0
- package/dist/index.cjs.js +845 -74
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +823 -74
- package/dist/index.umd.js +5 -5
- package/dist/message/api/createMessage.d.ts +2 -2
- package/dist/message/api/createMessage.d.ts.map +1 -1
- package/dist/message/api/updateMessage.d.ts +2 -2
- package/dist/message/api/updateMessage.d.ts.map +1 -1
- package/dist/post/api/queryPosts.d.ts +3 -3
- package/dist/post/api/queryPosts.d.ts.map +1 -1
- package/dist/utils/env.d.ts +5 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/version.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/@types/core/cache.ts +2 -2
- package/src/@types/core/events.ts +12 -1
- package/src/@types/core/model.ts +6 -0
- package/src/@types/core/paging.ts +31 -46
- package/src/@types/core/payload.ts +14 -0
- package/src/@types/core/query.ts +11 -3
- package/src/@types/domains/client.ts +0 -1
- package/src/@types/domains/comment.ts +1 -3
- package/src/@types/domains/follow.ts +25 -0
- package/src/@types/domains/mention.ts +26 -0
- package/src/@types/domains/message.ts +1 -0
- package/src/@types/domains/partials.ts +0 -8
- package/src/@types/domains/post.ts +1 -3
- package/src/@types/index.ts +3 -0
- package/src/channel/api/createChannel.ts +1 -1
- package/src/channel/api/queryChannelMembers.ts +2 -1
- package/src/client/api/activeUser.ts +26 -0
- package/src/client/api/connectClient.ts +3 -1
- package/src/client/api/createClient.ts +7 -7
- package/src/client/utils/endpoints.ts +14 -0
- package/src/community/api/getRecommendedCommunities.ts +86 -0
- package/src/community/api/getTopTrendingCommunities.ts +86 -0
- package/src/community/api/index.ts +3 -0
- package/src/community/api/queryCommunityMembers.ts +1 -1
- package/src/core/debug.ts +3 -1
- package/src/core/device.ts +3 -2
- package/src/core/events.ts +3 -1
- package/src/core/microtasks.ts +27 -0
- package/src/core/model/idResolvers.ts +3 -0
- package/src/core/model/identifyModel.ts +2 -0
- package/src/core/model/index.ts +3 -0
- package/src/core/query/paging.ts +16 -51
- package/src/core/query/query.ts +5 -5
- package/src/core/subscription.ts +21 -3
- package/src/feed/api/queryGlobalFeed.ts +58 -5
- package/src/follow/api/acceptFollower.ts +32 -0
- package/src/follow/api/declineFollower.ts +32 -0
- package/src/follow/api/follow.ts +40 -0
- package/src/follow/api/getFollowInfo.ts +75 -0
- package/src/follow/api/index.ts +8 -0
- package/src/follow/api/queryFollowers.ts +42 -0
- package/src/follow/api/queryFollowings.ts +42 -0
- package/src/follow/api/unfollow.ts +32 -0
- package/src/follow/api/utils.ts +77 -0
- package/src/follow/events/index.ts +10 -0
- package/src/follow/events/onFollowInfoUpdated.ts +43 -0
- package/src/follow/events/onFollowRequestAccepted.ts +19 -0
- package/src/follow/events/onFollowRequestCanceled.ts +19 -0
- package/src/follow/events/onFollowRequestDeclined.ts +19 -0
- package/src/follow/events/onFollowerDeleted.ts +19 -0
- package/src/follow/events/onFollowerRequested.ts +19 -0
- package/src/follow/events/onUserFollowed.ts +19 -0
- package/src/follow/events/onUserUnfollowed.ts +19 -0
- package/src/follow/events/utils.ts +38 -0
- package/src/follow/observers/index.ts +3 -0
- package/src/follow/observers/observeFollowInfo.ts +68 -0
- package/src/follow/observers/observeFollowers.ts +78 -0
- package/src/follow/observers/observeFollowings.ts +78 -0
- package/src/index.ts +5 -0
- package/src/message/api/createMessage.ts +2 -2
- package/src/message/api/updateMessage.ts +2 -2
- package/src/post/api/queryPosts.ts +5 -5
- package/src/utils/env.ts +7 -0
- package/src/version.ts +3 -1
- package/dist/core/network.d.ts +0 -11
- package/dist/core/network.d.ts.map +0 -1
- package/src/core/network.ts +0 -14
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { getActiveClient } from '~/client/api'
|
|
2
|
+
|
|
3
|
+
import { getResolver } from '~/core/model'
|
|
4
|
+
import { pullFromCache, pushToCache } from '~/cache/api'
|
|
5
|
+
import { ingestInCache } from '~/cache/api/ingestInCache'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* ```js
|
|
9
|
+
* import { getTopTrendingCommunities } from '@amityco/ts-sdk'
|
|
10
|
+
* const trendingCommunities = await getTopTrendingCommunities()
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Gets a list of top trending {@link Amity.Community} objects
|
|
14
|
+
*
|
|
15
|
+
* @param query The query parameters
|
|
16
|
+
* @returns A list of {@link Amity.Community} objects
|
|
17
|
+
*
|
|
18
|
+
* @category Community API
|
|
19
|
+
* @async
|
|
20
|
+
*/
|
|
21
|
+
export const getTopTrendingCommunities = async (
|
|
22
|
+
query?: Partial<Amity.PageLimit>
|
|
23
|
+
): Promise<Amity.Cached<Amity.Community[]>> => {
|
|
24
|
+
const client = getActiveClient()
|
|
25
|
+
client.log('channel/getTopTrendingCommunities', query)
|
|
26
|
+
|
|
27
|
+
const { limit = 5 } = query ?? {}
|
|
28
|
+
|
|
29
|
+
// API-FIX: backend doesnt answer Amity.Response
|
|
30
|
+
// const { data } = await client.http.get<Amity.Response<CommunityPayload>>(
|
|
31
|
+
const { data } = await client.http.get<Amity.CommunityPayload>(
|
|
32
|
+
`/api/v3/communities/top-trending`, { params: { options: { limit }}}
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
const { communities } = data
|
|
36
|
+
|
|
37
|
+
const cachedAt = client.cache && Date.now()
|
|
38
|
+
|
|
39
|
+
if (client.cache) {
|
|
40
|
+
ingestInCache(data, { cachedAt })
|
|
41
|
+
|
|
42
|
+
const cacheKey = ['community', 'top-trending', { params: { options: { limit }} }]
|
|
43
|
+
pushToCache(cacheKey, { communities: communities.map(getResolver('community')) })
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return { data: communities, cachedAt }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* ```js
|
|
51
|
+
* import { getTopTrendingCommunities } from '@amityco/ts-sdk'
|
|
52
|
+
* const communities = getTopTrendingCommunities.locally()
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* Gets a list of top trending {@link Amity.Community} objects from cache
|
|
56
|
+
*
|
|
57
|
+
* @param query The query parameters
|
|
58
|
+
* @returns communities
|
|
59
|
+
*
|
|
60
|
+
* @category Community API
|
|
61
|
+
*/
|
|
62
|
+
getTopTrendingCommunities.locally = (
|
|
63
|
+
query: Parameters<typeof getTopTrendingCommunities>[0],
|
|
64
|
+
): Amity.Cached<Amity.Community[]> | undefined => {
|
|
65
|
+
const client = getActiveClient()
|
|
66
|
+
client.log('community/getTopTrendingCommunities.locally', query)
|
|
67
|
+
|
|
68
|
+
if (!client.cache) return
|
|
69
|
+
|
|
70
|
+
const { limit = 5 } = query ?? {}
|
|
71
|
+
|
|
72
|
+
const queryKey = ['community', 'top-trending', { params: { options: { limit }} }];
|
|
73
|
+
const { data, cachedAt } = pullFromCache<{communities: Pick<Amity.Community, 'communityId'>[]}>(queryKey) ?? {}
|
|
74
|
+
|
|
75
|
+
if (!data?.communities.length)
|
|
76
|
+
return
|
|
77
|
+
|
|
78
|
+
const communities: Amity.Community[] = data.communities
|
|
79
|
+
.map(communityId => pullFromCache<Amity.Community>(['community', 'get', communityId])!)
|
|
80
|
+
.filter(Boolean)
|
|
81
|
+
.map(({ data }) => data)
|
|
82
|
+
|
|
83
|
+
return communities.length === data?.communities?.length
|
|
84
|
+
? { data: communities, cachedAt }
|
|
85
|
+
: undefined
|
|
86
|
+
}
|
|
@@ -51,7 +51,7 @@ export const queryCommunityMembers = async (query: {
|
|
|
51
51
|
const nextPage = toPage(paging.next)
|
|
52
52
|
const prevPage = toPage(paging.previous)
|
|
53
53
|
|
|
54
|
-
return { data: communityUsers, nextPage, prevPage }
|
|
54
|
+
return { data: communityUsers, cachedAt, nextPage, prevPage }
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/**
|
package/src/core/debug.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import debug from 'debug'
|
|
2
2
|
|
|
3
|
+
import { isProduction } from '~/utils/env'
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Creates a pre-configured logger instance
|
|
5
7
|
*
|
|
@@ -12,7 +14,7 @@ import debug from 'debug'
|
|
|
12
14
|
export const createLogger = (session?: string) => {
|
|
13
15
|
const active = (
|
|
14
16
|
`${session?.trim()}`.length > 0
|
|
15
|
-
&&
|
|
17
|
+
&& !isProduction
|
|
16
18
|
)
|
|
17
19
|
|
|
18
20
|
const logger = debug(session!)
|
package/src/core/device.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// TODO: find a way to uniquely identify the device
|
|
2
2
|
// import { getStorage } from './storage'
|
|
3
|
+
import { safeProcess } from '~/utils/env'
|
|
3
4
|
|
|
4
5
|
/** @hidden */
|
|
5
6
|
const VERSION = '11.0.0'
|
|
@@ -16,8 +17,8 @@ export const getDeviceId = () => {
|
|
|
16
17
|
|
|
17
18
|
/** @hidden */
|
|
18
19
|
export const getDeviceModel = () => {
|
|
19
|
-
if (
|
|
20
|
-
return
|
|
20
|
+
if (safeProcess.versions?.node)
|
|
21
|
+
return safeProcess.versions.node
|
|
21
22
|
|
|
22
23
|
if (navigator)
|
|
23
24
|
return `${navigator.product.toLowerCase()}#${navigator.userAgent ?? 'unknown_agent'}`
|
package/src/core/events.ts
CHANGED
|
@@ -2,6 +2,8 @@ import mitt from 'mitt'
|
|
|
2
2
|
|
|
3
3
|
import { getActiveClient } from '~/client/api/activeClient'
|
|
4
4
|
|
|
5
|
+
import { scheduleTask } from './microtasks'
|
|
6
|
+
|
|
5
7
|
// need to sync up the list
|
|
6
8
|
const WS_EVENTS = [
|
|
7
9
|
'disconnected',
|
|
@@ -134,5 +136,5 @@ export const fireEvent = <T extends keyof Amity.Events>(
|
|
|
134
136
|
payload: Amity.Events[T],
|
|
135
137
|
) => {
|
|
136
138
|
const { emitter } = getActiveClient()
|
|
137
|
-
|
|
139
|
+
scheduleTask(() => { emitter.emit(event, payload) })
|
|
138
140
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
let tasks: Function[] = []
|
|
2
|
+
let timer: NodeJS.Timeout
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Add a function to run just before the next tick
|
|
6
|
+
*
|
|
7
|
+
* @param task function to schedule for later execution
|
|
8
|
+
*/
|
|
9
|
+
export const scheduleTask = (task: Function) => {
|
|
10
|
+
clearTimeout(timer)
|
|
11
|
+
tasks.push(task)
|
|
12
|
+
|
|
13
|
+
timer = setTimeout(() => {
|
|
14
|
+
tasks.forEach(fn => fn())
|
|
15
|
+
tasks = []
|
|
16
|
+
}, 0)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Cancel the scheduling operation
|
|
21
|
+
*
|
|
22
|
+
* @param task function to be removed from later execution
|
|
23
|
+
*/
|
|
24
|
+
export const cancelTask = (task: Function) => {
|
|
25
|
+
tasks = tasks.filter(fn => fn !== task)
|
|
26
|
+
if (!tasks.length) clearTimeout(timer)
|
|
27
|
+
}
|
package/src/core/model/index.ts
CHANGED
package/src/core/query/paging.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-ignore
|
|
2
1
|
import { encode, decode } from 'js-base64'
|
|
3
2
|
|
|
4
3
|
/**
|
|
@@ -22,7 +21,7 @@ export const isSkipLimit = (json: Object): json is Amity.SkipLimitPagination =>
|
|
|
22
21
|
* @hidden
|
|
23
22
|
*/
|
|
24
23
|
export const isAfterBefore = (json: Object): json is Amity.AfterBeforePagination => (
|
|
25
|
-
['after', 'before', 'first', 'last'].some(prop => prop in json)
|
|
24
|
+
['after', 'before', 'first', 'last', 'limit'].some(prop => prop in json)
|
|
26
25
|
)
|
|
27
26
|
|
|
28
27
|
/**
|
|
@@ -34,7 +33,7 @@ export const isAfterBefore = (json: Object): json is Amity.AfterBeforePagination
|
|
|
34
33
|
* @hidden
|
|
35
34
|
*/
|
|
36
35
|
export const isAfterBeforeRaw = (json: Object): json is Amity.AfterBeforeRawPagination => (
|
|
37
|
-
|
|
36
|
+
'limit' in json
|
|
38
37
|
)
|
|
39
38
|
|
|
40
39
|
/**
|
|
@@ -45,7 +44,7 @@ export const isAfterBeforeRaw = (json: Object): json is Amity.AfterBeforeRawPagi
|
|
|
45
44
|
*
|
|
46
45
|
* @hidden
|
|
47
46
|
*/
|
|
48
|
-
export const isPaged = <T extends unknown>(payload: any): payload is Amity.Paged<T> => {
|
|
47
|
+
export const isPaged = <T extends unknown>(payload: any): payload is Amity.Paged<T, any> => {
|
|
49
48
|
return (
|
|
50
49
|
payload?.hasOwnProperty('data')
|
|
51
50
|
&& payload?.hasOwnProperty('nextPage')
|
|
@@ -63,9 +62,8 @@ export const isPaged = <T extends unknown>(payload: any): payload is Amity.Paged
|
|
|
63
62
|
* @hidden
|
|
64
63
|
*/
|
|
65
64
|
export const toToken = (
|
|
66
|
-
paging: Amity.Page | undefined,
|
|
67
|
-
style:
|
|
68
|
-
|
|
65
|
+
paging: Amity.Page | Amity.PageRaw | undefined,
|
|
66
|
+
style: Amity.PaginationStyles,
|
|
69
67
|
): Amity.Token | undefined => {
|
|
70
68
|
if (!paging || !Object.keys(paging).length)
|
|
71
69
|
return
|
|
@@ -79,7 +77,7 @@ export const toToken = (
|
|
|
79
77
|
limit: paging.limit,
|
|
80
78
|
}
|
|
81
79
|
}
|
|
82
|
-
else if (style === 'afterbefore') {
|
|
80
|
+
else if (style === 'afterbefore' && isAfterBefore(paging)) {
|
|
83
81
|
/*
|
|
84
82
|
Caution: this testing style is only valid because
|
|
85
83
|
our backend expects nothing else than a number as
|
|
@@ -114,6 +112,7 @@ export const toToken = (
|
|
|
114
112
|
return encode(JSON.stringify(payload))
|
|
115
113
|
}
|
|
116
114
|
|
|
115
|
+
|
|
117
116
|
/**
|
|
118
117
|
* Converts a b64 string token into a paging object
|
|
119
118
|
*
|
|
@@ -122,8 +121,8 @@ export const toToken = (
|
|
|
122
121
|
*
|
|
123
122
|
* @hidden
|
|
124
123
|
*/
|
|
125
|
-
export const toPage = (token?: Amity.Token): Amity.Page |
|
|
126
|
-
if (!token) return
|
|
124
|
+
export const toPage = (token?: Amity.Token): Amity.Page | undefined => {
|
|
125
|
+
if (!token) return undefined
|
|
127
126
|
|
|
128
127
|
// don't try catch, let it throw
|
|
129
128
|
const json = JSON.parse(decode(token))
|
|
@@ -132,22 +131,22 @@ export const toPage = (token?: Amity.Token): Amity.Page | null => {
|
|
|
132
131
|
return {
|
|
133
132
|
after: json.skip,
|
|
134
133
|
limit: json.limit!,
|
|
135
|
-
} as Amity.NextPage
|
|
134
|
+
} as Amity.NextPage<number>
|
|
136
135
|
} else if (isAfterBefore(json)) {
|
|
137
136
|
if ('before' in json) {
|
|
138
137
|
return {
|
|
139
138
|
before: json.before,
|
|
140
139
|
limit: json.last,
|
|
141
|
-
} as Amity.PrevPage
|
|
140
|
+
} as Amity.PrevPage<number>
|
|
142
141
|
} else if ('after' in json) {
|
|
143
142
|
return {
|
|
144
143
|
after: json.after,
|
|
145
144
|
limit: json.first,
|
|
146
|
-
} as Amity.NextPage
|
|
145
|
+
} as Amity.NextPage<number>
|
|
147
146
|
}
|
|
148
147
|
}
|
|
149
148
|
|
|
150
|
-
return
|
|
149
|
+
return undefined
|
|
151
150
|
}
|
|
152
151
|
|
|
153
152
|
/**
|
|
@@ -158,8 +157,8 @@ export const toPage = (token?: Amity.Token): Amity.Page | null => {
|
|
|
158
157
|
*
|
|
159
158
|
* @hidden
|
|
160
159
|
*/
|
|
161
|
-
export const toPageRaw = (token?: Amity.Token): Amity.PageRaw |
|
|
162
|
-
if (!token) return
|
|
160
|
+
export const toPageRaw = (token?: Amity.Token): Amity.PageRaw | undefined => {
|
|
161
|
+
if (!token) return undefined
|
|
163
162
|
|
|
164
163
|
// don't try catch, let it throw
|
|
165
164
|
const json = JSON.parse(decode(token))
|
|
@@ -168,39 +167,5 @@ export const toPageRaw = (token?: Amity.Token): Amity.PageRaw | null => {
|
|
|
168
167
|
return json as Amity.PageRaw
|
|
169
168
|
}
|
|
170
169
|
|
|
171
|
-
return
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Slices a collection according to its paging
|
|
176
|
-
*
|
|
177
|
-
* @param type the type of collection (for unique id identification with after/before)
|
|
178
|
-
* @param collection the collection to slice
|
|
179
|
-
* @param paging the paging object
|
|
180
|
-
* @returns the sliced collection according to the paging definition
|
|
181
|
-
*
|
|
182
|
-
* @hidden
|
|
183
|
-
*/
|
|
184
|
-
export const sliceByPaging = <K extends Amity.Domain, T extends Amity.Model[K]>(
|
|
185
|
-
type: K, collection: T[], page?: Amity.Page
|
|
186
|
-
) => {
|
|
187
|
-
console.log('slice by paging', page)
|
|
188
|
-
if (!page) return collection.slice()
|
|
189
|
-
|
|
190
|
-
let start: number | undefined = 0
|
|
191
|
-
let end: number | undefined = undefined
|
|
192
|
-
|
|
193
|
-
// next page behavior
|
|
194
|
-
if (page.after) {
|
|
195
|
-
start = page.after
|
|
196
|
-
end = start + page.limit
|
|
197
|
-
// prev page behavior
|
|
198
|
-
} else if (page.before) {
|
|
199
|
-
end = page.before + 1
|
|
200
|
-
start = end > page.limit ? end - page.limit : 0
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const paged = collection.slice(start, end)
|
|
204
|
-
|
|
205
|
-
return paged.length === page.limit ? paged : undefined
|
|
170
|
+
return undefined
|
|
206
171
|
}
|
package/src/core/query/query.ts
CHANGED
|
@@ -170,7 +170,7 @@ const isEmpty = (local: any) => {
|
|
|
170
170
|
*/
|
|
171
171
|
export const runQuery = <Args extends any[], Returned extends any>(
|
|
172
172
|
{ func, args }: Amity.Query<Args, Returned>,
|
|
173
|
-
callback?: (args: Amity.Snapshot<Returned
|
|
173
|
+
callback?: (args: Amity.Snapshot<Returned>) => void,
|
|
174
174
|
options: Amity.QueryOptions = queryOptions('cache_then_server')
|
|
175
175
|
) => {
|
|
176
176
|
let local: Returned | undefined
|
|
@@ -193,7 +193,7 @@ export const runQuery = <Args extends any[], Returned extends any>(
|
|
|
193
193
|
|
|
194
194
|
const shouldAbort = isCachable(local) && isFresh(local, options.lifeSpan)
|
|
195
195
|
|
|
196
|
-
callback?.(createSnapshot(local , {
|
|
196
|
+
callback?.(createSnapshot<Returned>(local , {
|
|
197
197
|
origin: 'local',
|
|
198
198
|
loading: !(isFetcher(func) && shouldAbort)
|
|
199
199
|
}))
|
|
@@ -201,7 +201,7 @@ export const runQuery = <Args extends any[], Returned extends any>(
|
|
|
201
201
|
if (shouldAbort)
|
|
202
202
|
return
|
|
203
203
|
} else {
|
|
204
|
-
callback?.(createSnapshot(undefined, {
|
|
204
|
+
callback?.(createSnapshot<Returned>(undefined, {
|
|
205
205
|
origin: 'local',
|
|
206
206
|
loading: true
|
|
207
207
|
}))
|
|
@@ -213,7 +213,7 @@ export const runQuery = <Args extends any[], Returned extends any>(
|
|
|
213
213
|
// isLocal(local) && syncInCache(local, fresh)
|
|
214
214
|
|
|
215
215
|
callback?.(
|
|
216
|
-
createSnapshot(fresh, {
|
|
216
|
+
createSnapshot<Returned>(fresh, {
|
|
217
217
|
origin: 'server',
|
|
218
218
|
loading: false,
|
|
219
219
|
})
|
|
@@ -221,7 +221,7 @@ export const runQuery = <Args extends any[], Returned extends any>(
|
|
|
221
221
|
})
|
|
222
222
|
.catch(error => {
|
|
223
223
|
callback?.(
|
|
224
|
-
createSnapshot(undefined, {
|
|
224
|
+
createSnapshot<Returned>(undefined, {
|
|
225
225
|
origin: 'server',
|
|
226
226
|
loading: false,
|
|
227
227
|
error,
|
package/src/core/subscription.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getActiveClient } from '~/client/api'
|
|
2
2
|
import { ASCError } from '~/core/errors'
|
|
3
3
|
import { proxyMqttEvents } from '~/core/events'
|
|
4
|
+
import { getActiveUser } from '~/client/api/activeUser'
|
|
4
5
|
|
|
5
6
|
export enum SubscriptionLevels {
|
|
6
7
|
COMMUNITY = 'community',
|
|
@@ -54,6 +55,22 @@ export const getCommentTopic = ({ path }: Amity.Subscribable): string => {
|
|
|
54
55
|
return path;
|
|
55
56
|
};
|
|
56
57
|
|
|
58
|
+
export const getMyFollowersTopic = (): string => {
|
|
59
|
+
const user = getActiveUser()
|
|
60
|
+
|
|
61
|
+
const [networkId] = user.path.split('/user/');
|
|
62
|
+
|
|
63
|
+
return `${networkId}/membership/${user._id}/+/+`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const getMyFollowingsTopic = (): string => {
|
|
67
|
+
const user = getActiveUser()
|
|
68
|
+
|
|
69
|
+
const [networkId] = user.path.split('/user/');
|
|
70
|
+
|
|
71
|
+
return `${networkId}/membership/+/${user._id}/+`;
|
|
72
|
+
}
|
|
73
|
+
|
|
57
74
|
let mqttAccessToken: string;
|
|
58
75
|
let mqttUserId: string;
|
|
59
76
|
|
|
@@ -61,11 +78,12 @@ export function subscribeTopic(
|
|
|
61
78
|
topic: string,
|
|
62
79
|
callback?: Amity.Listener<ASCError | void>
|
|
63
80
|
): Amity.Unsubscriber {
|
|
64
|
-
const { mqtt, emitter, accessToken
|
|
81
|
+
const { mqtt, emitter, accessToken } = getActiveClient()
|
|
82
|
+
const user = getActiveUser();
|
|
65
83
|
|
|
66
|
-
if (mqttAccessToken !== accessToken || mqttUserId !==
|
|
84
|
+
if (mqttAccessToken !== accessToken || mqttUserId !== user._id) {
|
|
67
85
|
mqttAccessToken = accessToken!
|
|
68
|
-
mqttUserId =
|
|
86
|
+
mqttUserId = user._id!
|
|
69
87
|
|
|
70
88
|
mqtt.connect({ accessToken: mqttAccessToken, userId: mqttUserId })
|
|
71
89
|
proxyMqttEvents(mqtt, emitter)
|
|
@@ -2,6 +2,8 @@ import { getActiveClient } from '~/client/api/activeClient'
|
|
|
2
2
|
|
|
3
3
|
import { toPage, toToken } from '~/core/query'
|
|
4
4
|
import { ingestInCache } from '~/cache/api/ingestInCache'
|
|
5
|
+
import { pullFromCache, pushToCache } from '~/cache/api'
|
|
6
|
+
import { getResolver } from '~/core/model'
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* ```js
|
|
@@ -19,15 +21,16 @@ import { ingestInCache } from '~/cache/api/ingestInCache'
|
|
|
19
21
|
**/
|
|
20
22
|
export const queryGlobalFeed = async (query?: {
|
|
21
23
|
dataTypes?: ('video' | 'image' | 'file' | 'liveStream')[]
|
|
24
|
+
useCustomRanking?: boolean
|
|
22
25
|
page?: Amity.Page
|
|
23
|
-
}): Promise<Amity.Paged<Amity.Post
|
|
26
|
+
}): Promise<Amity.Cached<Amity.Paged<Amity.Post>>> => {
|
|
24
27
|
const client = getActiveClient()
|
|
25
28
|
client.log('feed/queryGlobalFeed', query)
|
|
26
29
|
|
|
27
|
-
const { page, ...params } = query ?? {}
|
|
30
|
+
const { useCustomRanking, page, ...params } = query ?? {}
|
|
28
31
|
|
|
29
32
|
const { data } = await client.http.get<Amity.PostPayload & Amity.Pagination>(
|
|
30
|
-
`/api/v4/me/global-feeds`, { params: {
|
|
33
|
+
useCustomRanking ? `/api/v5/me/global-feeds` : `/api/v4/me/global-feeds`, { params: {
|
|
31
34
|
...params,
|
|
32
35
|
options: {
|
|
33
36
|
token: toToken(page, 'skiplimit')
|
|
@@ -38,10 +41,60 @@ export const queryGlobalFeed = async (query?: {
|
|
|
38
41
|
const { paging, ...payload } = data
|
|
39
42
|
const { posts } = payload
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
const cachedAt = client.cache && Date.now()
|
|
45
|
+
|
|
46
|
+
if (client.cache) {
|
|
47
|
+
ingestInCache(payload as Amity.PostPayload)
|
|
48
|
+
|
|
49
|
+
const cacheKey = ['globalFeed', 'query', { ...params, useCustomRanking, options: { ...page } } as Amity.Serializable]
|
|
50
|
+
pushToCache(cacheKey, { posts: posts.map(getResolver('post')), paging })
|
|
51
|
+
}
|
|
42
52
|
|
|
43
53
|
const nextPage = toPage(paging.next)
|
|
44
54
|
const prevPage = toPage(paging.previous)
|
|
45
55
|
|
|
46
|
-
return { data: posts, prevPage, nextPage }
|
|
56
|
+
return { data: posts, cachedAt, prevPage, nextPage }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* ```js
|
|
61
|
+
* import { queryGlobalFeed } from '@amityco/ts-sdk'
|
|
62
|
+
* const posts = await queryGlobalFeed.locally()
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* Queries a paginable list of {@link Amity.Post} objects from cache
|
|
66
|
+
*
|
|
67
|
+
* @param query The query parameters
|
|
68
|
+
* @returns A page of {@link Amity.Post} objects
|
|
69
|
+
*
|
|
70
|
+
* @category Feed API
|
|
71
|
+
* @async
|
|
72
|
+
**/
|
|
73
|
+
queryGlobalFeed.locally = (
|
|
74
|
+
query: Parameters<typeof queryGlobalFeed>[0],
|
|
75
|
+
): Amity.Cached<Amity.Paged<Amity.Post>> | undefined => {
|
|
76
|
+
const client = getActiveClient()
|
|
77
|
+
client.log('post/queryGlobalFeed.locally', query)
|
|
78
|
+
|
|
79
|
+
if (!client.cache) return
|
|
80
|
+
|
|
81
|
+
const { useCustomRanking, page, ...params } = query ?? {}
|
|
82
|
+
|
|
83
|
+
const queryKey = ['globalFeed', 'query', { ...params, useCustomRanking, options: { ...page }} as Amity.Serializable];
|
|
84
|
+
const { data, cachedAt } = pullFromCache<{ posts: string[] } & Amity.Pagination>(queryKey) ?? {}
|
|
85
|
+
|
|
86
|
+
if (!data?.posts.length)
|
|
87
|
+
return
|
|
88
|
+
|
|
89
|
+
const posts: Amity.Post[] = data.posts
|
|
90
|
+
.map(postId => pullFromCache<Amity.Post>(['post', 'get', postId])!)
|
|
91
|
+
.filter(Boolean)
|
|
92
|
+
.map(({ data }) => data)
|
|
93
|
+
|
|
94
|
+
const prevPage = toPage(data?.paging.previous)
|
|
95
|
+
const nextPage = toPage(data?.paging.next)
|
|
96
|
+
|
|
97
|
+
return posts.length === data?.posts?.length
|
|
98
|
+
? { data: posts, cachedAt, prevPage, nextPage }
|
|
99
|
+
: undefined
|
|
47
100
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getActiveClient } from '~/client/api'
|
|
2
|
+
import { ingestInCache } from '~/cache/api/ingestInCache'
|
|
3
|
+
import { fireEvent } from '~/core/events'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ```js
|
|
7
|
+
* import { acceptFollower } from '@amityco/ts-sdk'
|
|
8
|
+
* await acceptFollower('foobar')
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* Accept the follow request
|
|
12
|
+
*
|
|
13
|
+
* @param userId the ID of the {@link Amity.User} follower
|
|
14
|
+
* @returns A success boolean if the follow request was accepted
|
|
15
|
+
*
|
|
16
|
+
* @category Follow API
|
|
17
|
+
* @async
|
|
18
|
+
*/
|
|
19
|
+
export const acceptFollower = async (userId: Amity.User['userId']): Promise<boolean> => {
|
|
20
|
+
const client = getActiveClient()
|
|
21
|
+
client.log('follow/acceptFollower', userId)
|
|
22
|
+
|
|
23
|
+
const { data } = await client.http.post<Amity.FollowStatusPayload>(`/api/v4/me/followers/${userId}`)
|
|
24
|
+
|
|
25
|
+
if (client.cache) {
|
|
26
|
+
ingestInCache(data)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
fireEvent('follow.accepted', data.follows[0])
|
|
30
|
+
|
|
31
|
+
return true
|
|
32
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getActiveClient } from '~/client/api'
|
|
2
|
+
import { ingestInCache } from '~/cache/api/ingestInCache'
|
|
3
|
+
import { fireEvent } from '~/core/events'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ```js
|
|
7
|
+
* import { declineFollower } from '@amityco/ts-sdk'
|
|
8
|
+
* await declineFollower('foobar')
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* Decline the follow request or delete the follower
|
|
12
|
+
*
|
|
13
|
+
* @param userId the ID of the {@link Amity.User} follower
|
|
14
|
+
* @returns A success boolean if the follow request was decline
|
|
15
|
+
*
|
|
16
|
+
* @category Follow API
|
|
17
|
+
* @async
|
|
18
|
+
*/
|
|
19
|
+
export const declineFollower = async (userId: Amity.User['userId']): Promise<boolean> => {
|
|
20
|
+
const client = getActiveClient()
|
|
21
|
+
client.log('follow/declineFollower', userId)
|
|
22
|
+
|
|
23
|
+
const { data } = await client.http.delete<{ follows: Amity.FollowStatus[] }>(`/api/v4/me/followers/${userId}`)
|
|
24
|
+
|
|
25
|
+
if (client.cache) {
|
|
26
|
+
ingestInCache(data)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
fireEvent('follow.requestDeclined', data.follows[0])
|
|
30
|
+
|
|
31
|
+
return true
|
|
32
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getActiveClient } from '~/client/api'
|
|
2
|
+
import { ingestInCache } from '~/cache/api/ingestInCache'
|
|
3
|
+
import { fireEvent } from '~/core/events'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ```js
|
|
7
|
+
* import { follow } from '@amityco/ts-sdk'
|
|
8
|
+
* const status = await follow('foobar')
|
|
9
|
+
* ```
|
|
10
|
+
*
|
|
11
|
+
* Follow the user
|
|
12
|
+
*
|
|
13
|
+
* @param userId the ID of the {@link Amity.User}
|
|
14
|
+
* @returns the status {@link Amity.FollowStatus}
|
|
15
|
+
*
|
|
16
|
+
* @category Follow API
|
|
17
|
+
* @async
|
|
18
|
+
*/
|
|
19
|
+
export const follow = async (userId: Amity.User['userId']): Promise<Amity.Cached<Amity.FollowStatus>> => {
|
|
20
|
+
const client = getActiveClient()
|
|
21
|
+
client.log('follow/follow', userId)
|
|
22
|
+
|
|
23
|
+
const { data } = await client.http.post<Amity.FollowStatusPayload>(`/api/v4/me/following/${userId}`)
|
|
24
|
+
|
|
25
|
+
const cachedAt = client.cache && Date.now()
|
|
26
|
+
|
|
27
|
+
if (client.cache) {
|
|
28
|
+
ingestInCache(data, { cachedAt })
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fireEvent(
|
|
32
|
+
data.follows[0].status === 'accepted' ? 'follow.created' : 'follow.requested',
|
|
33
|
+
data.follows[0],
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
data: data.follows[0],
|
|
38
|
+
cachedAt,
|
|
39
|
+
}
|
|
40
|
+
}
|