import { O } from 'ts-toolbelt' ; import { createCollectionWithContext , CollectionInstance } from './Collection' ; import { GlobalConfig , ModuleConfig , defaultsGlobalConfig } from './types/config' ; import { createDocWithContext , DocInstance } from './Doc' ; import { FetchPromises } from './types/actions' ; import { throwIfInvalidModulePath } from './helpers/throwFns' ; import { getCollectionPathDocIdEntry } from './helpers/pathHelpers' ; import { getPathFilterIdentifier , PathFilterIdentifier , MODULE_IDENTIFIER_SPLIT , } from './helpers/moduleHelpers' ; export { isDocModule , isCollectionModule } from './helpers/pathHelpers' ; /**
 * This is the global Magnetar instance that is returned when instantiating with Magnetar()
 */ export interface MagnetarInstance { globalConfig : O . Compulsory < GlobalConfig > ; see CollectionFn collection : CollectionFn ; see DocFn doc : DocFn ; } /**
 * The write lock promise that is resolved x seconds after the final write action has resolved
 */ export type WriteLock = { /** To be resolved after the countdown after the last write action finishes */ promise : null | Promise < void > ; /** Resolves the `WriteLock['promise']` */ resolve : ( ) => any ; /** To be started after every write action & To be reset when a new write action occurs */ countdown : null | ReturnType < typeof setTimeout > ; } ; see CollectionInstance export type CollectionFn < DocDataTypeInherited extends Record < string , any > = Record < string , any > > = < DocDataType extends Record < string , any > = DocDataTypeInherited > ( idOrPath : string , moduleConfig ? : ModuleConfig ) => CollectionInstance < DocDataType > ; see DocInstance export type DocFn < DocDataTypeInherited extends Record < string , any > = Record < string , any > > = < DocDataType extends Record < string , any > = DocDataTypeInherited > ( idOrPath : string , moduleConfig ? : ModuleConfig ) => DocInstance < DocDataType > ; see GlobalConfig see MagnetarInstance export function Magnetar ( magnetarConfig ) { const globalConfig = defaultsGlobalConfig ( magnetarConfig ) ; see WriteLock const writeLockMap = new Map ( ) ; /**
     * the global storage for closeStream functions
     */ const closeStreamFnMap = new Map ( ) ; /**
     * the global storage for open stream promises
     */ const streamingPromiseMap = new Map ( ) ; /**
     * the global storage for fetch promises
     */ const fetchPromiseMap = new Map ( ) ; function getModuleInstance ( modulePath , moduleConfig = { } , moduleType , docFn , collectionFn ) { throwIfInvalidModulePath ( modulePath , moduleType ) ; const [ collectionPath , docId ] = getCollectionPathDocIdEntry ( modulePath ) ; const pathFilterIdentifier = getPathFilterIdentifier ( modulePath , moduleConfig ) ; if ( ! writeLockMap . has ( modulePath ) ) { writeLockMap . set ( modulePath , { promise : null , resolve : ( ) => { } , countdown : null } ) ; } if ( ! fetchPromiseMap . has ( pathFilterIdentifier ) ) { fetchPromiseMap . set ( pathFilterIdentifier , new Map ( ) ) ; } const fetchPromises = fetchPromiseMap . get ( pathFilterIdentifier ) ! ; if ( ! closeStreamFnMap . has ( pathFilterIdentifier ) ) { closeStreamFnMap . set ( pathFilterIdentifier , ( ) => { } ) ; } if ( ! streamingPromiseMap . has ( pathFilterIdentifier ) ) { streamingPromiseMap . set ( pathFilterIdentifier , null ) ; } function cacheStream ( closeStreamFn , streamingPromise ) { closeStreamFnMap . set ( pathFilterIdentifier , closeStreamFn ) ; streamingPromiseMap . set ( pathFilterIdentifier , streamingPromise ) ; } function streaming ( ) { return streamingPromiseMap . get ( pathFilterIdentifier ) || null ; } function closeStream ( ) { const closeStreamFn = closeStreamFnMap . get ( pathFilterIdentifier ) ; if ( closeStreamFn ) closeStreamFn ( ) ; } function closeAllStreams ( ) { for ( const [ identifier , closeStreamFn ] of closeStreamFnMap ) { const _modulePath = identifier . split ( MODULE_IDENTIFIER_SPLIT ) [ 0 ] ; if ( _modulePath === modulePath ) closeStreamFn ( ) ; } } const streamAndFetchPromises = { writeLockMap , fetchPromises , cacheStream , streaming , closeStream , closeAllStreams , } ; if ( moduleType === 'doc' ) { return createDocWithContext ( [ collectionPath , docId ] , moduleConfig , globalConfig , docFn , collectionFn , streamAndFetchPromises ) ; } return createCollectionWithContext ( [ collectionPath , docId ] , moduleConfig , globalConfig , docFn , collectionFn , streamAndFetchPromises ) ; } function collection ( modulePath , moduleConfig = { } ) { return getModuleInstance ( modulePath , moduleConfig , 'collection' , doc as DocFn , collection as CollectionFn ) as CollectionInstance ; } function doc ( modulePath , moduleConfig = { } ) { return getModuleInstance ( modulePath , moduleConfig , 'doc' , doc as DocFn , collection as CollectionFn ) as DocInstance ; } const instance = { globalConfig , collection : collection as CollectionFn , doc : doc as DocFn , } ; return instance ; }