import { pick } from 'filter-anything' ; import { PluginWriteAction , PluginDeleteAction , PluginStreamAction , StreamResponse , DoOnStream , PluginFetchAction , PluginRevertAction , PluginDeletePropAction , PluginInsertAction , DoOnFetch , FetchResponse , PluginStreamActionPayload , PluginRevertActionPayload , PluginFetchActionPayload , PluginDeleteActionPayload , PluginDeletePropActionPayload , PluginInsertActionPayload , PluginWriteActionPayload , Clauses , } from '../../../core/src' ; import { StorePluginModuleConfig , RemoteStoreOptions } from './index' ; import { throwIfEmulatedError , waitMs , pokedexMap , generateRandomId } from '../helpers' ; import { filterDataPerClauses } from './helpers' ; import { isFullArray , isPromise } from 'is-what' ; export function writeActionFactory ( storePluginOptions , actionName ) { return async function ( { payload , collectionPath , docId , pluginModuleConfig , } ) : Promise < void > { throwIfEmulatedError ( payload , storePluginOptions ) ; await waitMs ( 1 ) ; if ( ! docId ) throw new Error ( 'An non-existent action was triggered on a collection' ) ; } ; } export function insertActionFactory ( storePluginOptions ) { return async function ( { payload , collectionPath , docId , pluginModuleConfig , } ) : Promise < string > { throwIfEmulatedError ( payload , storePluginOptions ) ; await waitMs ( 1 ) ; if ( ! docId ) { const id = generateRandomId ( ) ; return id ; } return docId ; } ; } export function deletePropActionFactory ( storePluginOptions ) { return async function ( { payload , collectionPath , docId , pluginModuleConfig , } ) : Promise < void > { throwIfEmulatedError ( payload , storePluginOptions ) ; await waitMs ( 1 ) ; if ( ! docId ) throw new Error ( 'An non-existent action was triggered on a collection' ) ; } ; } export function deleteActionFactory ( storePluginOptions ) { return async function ( { payload , collectionPath , docId , pluginModuleConfig , } ) : Promise < void > { throwIfEmulatedError ( payload , storePluginOptions ) ; await waitMs ( 1 ) ; } ; } function mockDataRetrieval ( collectionPath , docId , pluginModuleConfig ) { if ( docId === 'trainer' ) return [ { name : 'Luca' , age : 10 , dream : 'job' } ] ; if ( collectionPath === 'pokedex' ) { const _pokedexMap = pokedexMap ( ) ; if ( docId ) { const result = _pokedexMap . get ( docId ) ; return ( result ) ? [ result ] : [ ] ; } const clauses = pick ( pluginModuleConfig , [ 'where' , 'orderBy' , 'limit' ] ) ; const filteredMap = filterDataPerClauses ( _pokedexMap , clauses ) ; return [ ... filteredMap . values ( ) ] ; } return [ ] ; } export function fetchActionFactory ( storePluginOptions ) { return async function ( { payload , collectionPath , docId , pluginModuleConfig , } ) : Promise < DoOnFetch | FetchResponse > { throwIfEmulatedError ( payload , storePluginOptions ) ; return new Promise ( ( resolve , reject ) => { setTimeout ( ( ) => { const dataRetrieved = mockDataRetrieval ( collectionPath , docId , pluginModuleConfig ) ; const results = dataRetrieved . map ( ( _data ) => { const _metaData = { data : _data , exists : true , id : _data . id || docId } ; return _metaData ; } ) ; resolve ( { docs : results } ) ; } , 1 ) ; } ) ; } ; } export function streamActionFactory ( storePluginOptions ) { return async function ( { payload , collectionPath , docId , pluginModuleConfig , mustExecuteOnRead , } ) : Promise < StreamResponse | DoOnStream > { const dataRetrieved = ! docId ? mockDataRetrieval ( collectionPath , docId , pluginModuleConfig ) : [ { name : 'Luca' , age : 10 } , { name : 'Luca' , age : 10 } , { name : 'Luca' , age : 10 , dream : 'job' } , { name : 'Luca' , age : 10 , dream : 'job' , colour : 'blue' } , ] ; const stopStreaming = { stopped : false , stop : ( ) => { } , } ; dataRetrieved . forEach ( ( data , i ) => { const metaData = { data , id : data . id || docId , exists : true } ; if ( isFullArray ( payload ) && payload . every ( isPromise ) ) { const promise = payload [ i ] ; if ( ! promise ) return ; promise . then ( ( ) => { mustExecuteOnRead . added ( data , metaData ) ; } ) ; return ; } const waitTime = 10 + i * 200 ; setTimeout ( ( ) => { if ( stopStreaming . stopped ) return ; mustExecuteOnRead . added ( data , metaData ) ; } , waitTime ) ; } ) ; const streaming = new Promise ( ( resolve , reject ) : void => { stopStreaming . stop = resolve ; setTimeout ( ( ) => { throwIfEmulatedError ( payload , storePluginOptions ) ; } , 1 ) ; } ) ; function stop ( ) { stopStreaming . stopped = true ; stopStreaming . stop ( ) ; } return { streaming , stop } ; } ; } export function revertActionFactory ( storePluginOptions ) { return async function ( { payload , collectionPath , docId , pluginModuleConfig , actionName , } ) : Promise < void > { const isReadAction = [ 'fetch' , 'stream' ] . includes ( actionName ) ; if ( isReadAction ) return ; await waitMs ( 1 ) ; } ; }