UNPKG

@amityco/ts-sdk-react-native

Version:

Amity Social Cloud Typescript SDK

153 lines (125 loc) 4.27 kB
/* eslint-disable no-use-before-define */ import { getResolver } from '~/core/model'; import { pullFromCache, pushToCache } from '~/cache/api'; import { getActiveClient } from '~/client/api'; import { createQuery, filterByPropEquality, queryOptions, runQuery, sortByFirstCreated, sortByLastCreated, } from '~/core/query'; import { COLLECTION_DEFAULT_CACHING_POLICY, COLLECTION_DEFAULT_PAGINATION_LIMIT, ENABLE_CACHE_MESSAGE, } from '~/utils/constants'; import { queryStreams as _queryStreams } from '../internalApi/queryStreams'; import { onStreamRecorded, onStreamStarted, onStreamStopped } from '../events'; /* begin_public_function id: stream.query */ /** * ```js * import { StreamRepository } from '@amityco/ts-sdk-react-native' * const streams = await StreamRepository.getStreams() * ``` * * Observe all mutations on a list of {@link Amity.Stream}s * * @param params for querying streams * @param callback the function to call when new data are available * @param config * @returns An {@link Amity.Unsubscriber} function to run when willing to stop observing the streams * * @category Stream Live Collection */ export const getStreams = ( params: Amity.StreamLiveCollection, callback: Amity.LiveCollectionCallback<Amity.Stream>, config?: Amity.LiveCollectionConfig, ) => { const { log, cache } = getActiveClient(); if (!cache) { console.log(ENABLE_CACHE_MESSAGE); } const timestamp = Date.now(); log(`getStreams(tmpid: ${timestamp}) > listen`); const { limit: queryLimit, ...queryParams } = params; const limit = queryLimit ?? COLLECTION_DEFAULT_PAGINATION_LIMIT; const { policy = COLLECTION_DEFAULT_CACHING_POLICY } = config ?? {}; const disposers: Amity.Unsubscriber[] = []; const cacheKey = ['streams', 'collection', params]; const applyFilter = (data: Amity.Stream[]): Amity.Stream[] => { let streams = filterByPropEquality(data, 'isDeleted', params.isDeleted); streams = streams.sort( params.sortBy === 'lastCreated' ? sortByLastCreated : sortByFirstCreated, ); return streams; }; const responder = (data: Amity.StreamLiveCollectionCache, isEventModel = false) => { const streams: Amity.Stream[] = data.data .map(streamId => { return pullFromCache<Amity.Stream>(['stream', 'get', streamId])!; }) .filter(Boolean) .map(({ data }) => data) ?? []; callback({ onNextPage: onFetch, /* * Only apply filter to RTE Model */ data: isEventModel ? applyFilter(streams) : streams, hasNextPage: !!data.params?.page, loading: data.loading, error: data.error, }); }; const realtimeRouter = (_: Amity.StreamActionType) => (stream: Amity.Stream) => { const collection = pullFromCache<Amity.StreamLiveCollectionCache>(cacheKey)?.data; if (!collection) return; collection.data = [...new Set([stream.streamId, ...collection.data])]; pushToCache(cacheKey, collection); responder(collection, true); }; const onFetch = (initial = false) => { const collection = pullFromCache<Amity.StreamLiveCollectionCache>(cacheKey)?.data; const streams = collection?.data ?? []; if (!initial && streams.length > 0 && !collection?.params.page) return; const query = createQuery(_queryStreams, { ...queryParams, limit: initial ? limit : undefined, page: !initial ? collection?.params.page : undefined, }); runQuery( query, ({ data: result, error, loading, paging }) => { const data = { loading, error, params: { page: paging?.next }, data: streams, }; if (result) { data.data = [...new Set([...streams, ...result.map(getResolver('stream'))])]; } pushToCache(cacheKey, data); responder(data); }, queryOptions(policy), ); }; disposers.push( onStreamRecorded(realtimeRouter('onStreamRecorded')), onStreamStarted(realtimeRouter('onStreamStarted')), onStreamStopped(realtimeRouter('onStreamStopped')), ); onFetch(true); return () => { log(`getStreams(tmpid: ${timestamp}) > dispose`); disposers.forEach(fn => fn()); }; }; /* end_public_function */