@lomray/react-mobx-manager 4.2.1 → 4.3.0-beta.2
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 +15 -515
- package/index.d.ts +1 -0
- package/index.js +1 -1
- package/make-fetching.d.ts +11 -7
- package/make-fetching.js +1 -1
- package/make-fetching.js.map +1 -1
- package/manager.d.ts +14 -0
- package/manager.js +1 -1
- package/manager.js.map +1 -1
- package/package.json +23 -21
- package/parent-store.d.ts +9 -0
- package/parent-store.js +2 -0
- package/parent-store.js.map +1 -0
- package/plugins/dev-extension/hmr/adapters.d.ts +9 -0
- package/plugins/dev-extension/hmr/adapters.js +2 -0
- package/plugins/dev-extension/hmr/adapters.js.map +1 -0
- package/plugins/dev-extension/hmr/index.d.ts +3 -0
- package/plugins/dev-extension/hmr/index.js +2 -0
- package/plugins/dev-extension/hmr/index.js.map +1 -0
- package/plugins/dev-extension/hmr/service.d.ts +71 -0
- package/plugins/dev-extension/hmr/service.js +2 -0
- package/plugins/dev-extension/hmr/service.js.map +1 -0
- package/plugins/dev-extension/hmr/types.d.ts +14 -0
- package/plugins/dev-extension/hmr/types.js +2 -0
- package/plugins/dev-extension/hmr/types.js.map +1 -0
- package/storages/combined-storage.d.ts +1 -1
- package/storages/combined-storage.js +1 -1
- package/storages/combined-storage.js.map +1 -1
- package/storages/cookie-storage.js +1 -1
- package/storages/cookie-storage.js.map +1 -1
- package/storages/local-storage.js +1 -1
- package/storages/local-storage.js.map +1 -1
- package/suspense-query.js +1 -1
- package/suspense-query.js.map +1 -1
- package/types.d.ts +8 -3
- package/with-stores.js +1 -1
- package/with-stores.js.map +1 -1
package/manager.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sources":["../src/manager.ts"],"sourcesContent":["import EventManager from '@lomray/event-manager';\nimport { isObservableProp, toJS } from 'mobx';\nimport { ROOT_CONTEXT_ID } from './constants';\nimport deepMerge from './deep-merge';\nimport Events from './events';\nimport Logger from './logger';\nimport {\n isPropExcludedFromExport,\n isPropObservableExported,\n isPropSimpleExported,\n} from './make-exported';\nimport onChangeListener from './on-change-listener';\nimport CombinedStorage from './storages/combined-storage';\nimport StoreStatus from './store-status';\nimport type {\n IConstructableStore,\n IGroupedStores,\n IManagerOptions,\n IManagerParams,\n IPersistOptions,\n IStoreParams,\n IStorePersisted,\n TAnyStore,\n TInitStore,\n TStoreDefinition,\n TStores,\n} from './types';\nimport wakeup from './wakeup';\n\n/**\n * Mobx stores manager\n */\nclass Manager {\n /**\n * Manger instance\n */\n protected static instance: Manager;\n\n /**\n * Created stores\n */\n protected readonly stores = new Map<string, TInitStore>();\n\n /**\n * Relations between stores\n */\n protected readonly storesRelations = new Map<\n string, // contextId\n { ids: Set<string>; parentId: string | null; componentName?: string }\n >();\n\n /**\n * Save persisted stores identities\n */\n protected static readonly persistedStores = new Set<string>();\n\n /**\n * Initial stores state (local storage, custom etc.)\n */\n protected readonly initState: Record<string, any>;\n\n /**\n * Storage for persisted stores\n */\n public readonly storage?: CombinedStorage;\n\n /**\n * Additional store's constructor params\n */\n protected readonly storesParams: IManagerParams['storesParams'];\n\n /**\n * Manager options\n */\n public readonly options: IManagerOptions = {\n shouldDisablePersist: false,\n shouldRemoveInitState: true,\n failedCreationStrategy: 'empty',\n };\n\n /**\n * Suspense stores relations\n * @see withStores\n */\n protected suspenseRelations: Map<string, Set<string>> = new Map();\n\n /**\n * Mobx manager logger\n */\n protected readonly logger: Logger;\n\n /**\n * @constructor\n */\n public constructor({ initState, storesParams, storage, options, logger }: IManagerParams = {}) {\n this.initState = initState || {};\n this.storesParams = storesParams || {};\n this.logger =\n logger && 'log' in logger\n ? logger\n : new Logger({ level: 3, ...(logger ?? {}), manager: this });\n this.storage =\n storage instanceof CombinedStorage\n ? storage\n : storage\n ? new CombinedStorage({ default: storage })\n : undefined;\n\n Object.assign(this.options, options || {});\n\n Manager.instance = this;\n\n // only client side\n if (typeof window !== 'undefined') {\n const state = window.mbxM;\n\n window.mbxM = { push: this.pushInitState };\n\n (Array.isArray(state) ? state : []).forEach(this.pushInitState);\n }\n }\n\n /**\n * Init store manager\n */\n public async init(): Promise<Manager> {\n try {\n if (this.storage) {\n await this.storage.get();\n }\n } catch (e) {\n this.logger.err('Failed initialized store manager: ', e);\n }\n\n return this;\n }\n\n /**\n * Get manager instance\n */\n public static get(): Manager {\n if (!Manager.instance) {\n throw new Error('Store manager is not initialized.');\n }\n\n return Manager.instance;\n }\n\n /**\n * Get all stores\n */\n public getStores(): Manager['stores'] {\n return this.stores;\n }\n\n /**\n * Get stores relations\n */\n public getStoresRelations(): Manager['storesRelations'] {\n return this.storesRelations;\n }\n\n /**\n * Get suspense relations with stores\n */\n public getSuspenseRelations(): Manager['suspenseRelations'] {\n return this.suspenseRelations;\n }\n\n /**\n * Get persisted stores ids\n */\n public static getPersistedStoresIds(): Set<string> {\n return Manager.persistedStores;\n }\n\n /**\n * Push initial state dynamically\n * E.g. when stream html\n */\n public pushInitState = (storesState: Record<string, any> = {}): void => {\n for (const [storeId, state] of Object.entries(storesState)) {\n this.initState[storeId] = state;\n }\n };\n\n /**\n * Get store identity\n */\n protected getStoreId<T extends TAnyStore>(\n store: IConstructableStore<T> | TInitStore,\n params: IStoreParams = {},\n ): string {\n const { id, contextId, key } = params;\n\n if (id) {\n return id;\n }\n\n if (store.libStoreId) {\n return store.libStoreId;\n }\n\n let storeId = (store['id'] as string) || (store['name'] as string) || store.constructor.name;\n\n if (store.isGlobal) {\n return storeId;\n }\n\n storeId = `${storeId}--${contextId!}`;\n\n return key ? `${storeId}--${key}` : storeId;\n }\n\n /**\n * Get exist store\n */\n public getStore<T>(store: IConstructableStore<T>, params: IStoreParams = {}): T | undefined {\n const storeId = this.getStoreId(store, params);\n\n // full match\n if (this.stores.has(storeId)) {\n return this.stores.get(storeId) as T;\n }\n\n // in case with global store (create if not exist)\n if (store.isGlobal) {\n return this.createStore(store, {\n id: storeId,\n contextId: 'global',\n parentId: ROOT_CONTEXT_ID,\n suspenseId: '',\n componentName: 'root-app',\n componentProps: {},\n });\n }\n\n // try to look up store in current or parent context\n return this.lookupStore(storeId, params) as T;\n }\n\n /**\n * Lookup store\n */\n protected lookupStore(id: string, params: IStoreParams): TInitStore<TAnyStore> | undefined {\n const { contextId, parentId: defaultParentId } = params;\n const clearId = id.split('--')?.[0];\n const { ids, parentId } = this.storesRelations.get(contextId!) ?? {\n ids: new Set(),\n parentId: defaultParentId,\n };\n\n const matchedIds = [...ids].filter((storeId) => storeId.startsWith(`${clearId}--`));\n\n if (matchedIds.length === 1) {\n return this.stores.get(matchedIds[0]);\n } else if (matchedIds.length > 1) {\n this.logger.err(\n 'Parent context has multiple stores with the same id, please pass key to getStore function.',\n );\n\n return undefined;\n }\n\n if (!parentId || parentId === ROOT_CONTEXT_ID) {\n return undefined;\n }\n\n return this.lookupStore(id, { contextId: this.getBiggerContext(parentId, defaultParentId) });\n }\n\n /**\n * Get bigger context from two\n */\n protected getBiggerContext(ctx1?: string, ctx2?: string): string | undefined {\n if (!ctx1) {\n return ctx2;\n } else if (!ctx2) {\n return ctx1;\n }\n\n const regexp = /[^a-zA-Z]/g;\n\n return ctx1.replace(regexp, '') > ctx2.replace(regexp, '') ? ctx1 : ctx2;\n }\n\n /**\n * Create new store instance\n */\n protected createStore<T>(\n store: IConstructableStore<T>,\n params: Omit<Required<IStoreParams>, 'key'>,\n ): T {\n const { id, contextId, parentId, suspenseId, componentName, componentProps } = params;\n\n // only for global store\n if (this.stores.has(id)) {\n return this.stores.get(id) as T;\n }\n\n const newStore = new store({\n ...this.storesParams,\n storeManager: this,\n getStore: <TS>(\n targetStore: IConstructableStore<TS>,\n targetParams = { contextId, parentId },\n ) => this.getStore(targetStore, targetParams),\n componentProps,\n initState: this.initState[id],\n });\n\n // assign params to new store\n newStore.libStoreId = id;\n newStore.isGlobal = store.isGlobal;\n newStore.libStoreContextId = store.isGlobal ? 'global' : contextId;\n newStore.libStoreParentId =\n store.isGlobal || !parentId || parentId === contextId ? ROOT_CONTEXT_ID : parentId;\n newStore.libStoreSuspenseId = suspenseId;\n newStore.libStoreComponentName = componentName;\n\n this.setStoreStatus(newStore, store.isGlobal ? StoreStatus.inUse : StoreStatus.init);\n this.prepareStore(newStore);\n EventManager.publish(Events.CREATE_STORE, { store });\n\n return newStore as T;\n }\n\n /**\n * Create stores for component\n *\n * NOTE: use only inside withStores wrapper\n */\n public createStores(\n map: [string, TStoreDefinition][],\n parentId: string,\n contextId: string,\n suspenseId: string,\n componentName: string,\n componentProps: Record<string, any> = {},\n ): IGroupedStores {\n const { failedCreationStrategy } = this.options;\n\n const result = map.reduce(\n (res, [key, store]) => {\n const {\n id,\n store: s,\n isParent = false,\n } = 'store' in store ? store : { store, id: undefined, isParent: false };\n let storeId =\n id ||\n (isParent\n ? (this.getStore(s, { contextId, parentId })?.libStoreId as string)\n : this.getStoreId(s, { key, contextId }));\n\n if (!storeId) {\n const msg = `Cannot find or create store '${key}': '${this.getStoreId(s)}'`;\n\n this.logger.warn(msg);\n this.logger.debug(\n msg,\n { contextId, parentId, suspenseId, componentName, isParent },\n true,\n );\n\n if (failedCreationStrategy === 'dummy') {\n // try to force create store\n storeId = this.getStoreId(s, { key, contextId });\n } else {\n if (failedCreationStrategy === 'empty') {\n res.hasCreationFailure = true;\n }\n\n return res;\n }\n }\n\n const storeInstance = this.createStore(s, {\n id: storeId,\n contextId,\n parentId,\n suspenseId,\n componentName,\n componentProps,\n });\n\n if (isParent) {\n res.parentStores[key] = storeInstance;\n } else if (storeInstance.isGlobal) {\n res.globalStores[key] = storeInstance;\n } else {\n res.relativeStores[key] = storeInstance;\n }\n\n return res;\n },\n { relativeStores: {}, parentStores: {}, globalStores: {}, hasCreationFailure: false },\n );\n\n // need create context relation in case when component doesn't include relative stores\n this.createRelationContext(contextId, parentId, componentName);\n\n return result;\n }\n\n /**\n * Create empty relation context\n */\n protected createRelationContext(\n contextId: string,\n parentId?: string,\n componentName?: string,\n ): void {\n if (this.storesRelations.has(contextId)) {\n return;\n }\n\n this.storesRelations.set(contextId, {\n ids: new Set(),\n parentId: !parentId || parentId === contextId ? ROOT_CONTEXT_ID : parentId,\n componentName,\n });\n }\n\n /**\n * Delete relation context id\n */\n protected removeRelationContext(contextId: string): void {\n const storesRelations = this.storesRelations.get(contextId);\n\n if (!storesRelations || contextId === ROOT_CONTEXT_ID || storesRelations.ids.size > 0) {\n return;\n }\n\n this.storesRelations.delete(contextId);\n }\n\n /**\n * Prepare store before usage\n */\n protected prepareStore(store: TStores[string]): void {\n const storeId = store.libStoreId!;\n const contextId = store.libStoreContextId!;\n const suspenseId = store.libStoreSuspenseId!;\n\n if (this.stores.has(storeId)) {\n return;\n }\n\n // restore initial state from server\n const initState = this.initState[storeId];\n\n if (initState) {\n deepMerge(store, initState);\n }\n\n // restore persisted state\n if ('wakeup' in store && Manager.persistedStores.has(storeId)) {\n store.wakeup?.({\n initState,\n persistedState: this.storage?.getStoreData(store),\n manager: this,\n });\n }\n\n // track changes in persisted store\n if (Manager.persistedStores.has(storeId) && 'addOnChangeListener' in store) {\n const onDestroyDefault = store.onDestroy?.bind(store);\n const removeListener = store.addOnChangeListener!(store, this);\n\n store.onDestroy = () => {\n removeListener?.();\n onDestroyDefault?.();\n };\n }\n\n store.init?.();\n this.createRelationContext(contextId, store.libStoreParentId, store.libStoreComponentName);\n\n if (!this.suspenseRelations.has(suspenseId)) {\n this.suspenseRelations.set(suspenseId, new Set());\n }\n\n const { ids } = this.storesRelations.get(contextId)!;\n\n // add store to manager\n this.stores.set(storeId, store);\n ids.add(storeId);\n // add store relation with suspense\n this.suspenseRelations.get(suspenseId)!.add(storeId);\n }\n\n /**\n * Remove store\n */\n protected removeStore(store: TStores[string]): void {\n const storeId = store.libStoreId!;\n const suspenseId = store.libStoreSuspenseId!;\n const { ids } = this.storesRelations.get(store.libStoreContextId!) ?? { ids: new Set() };\n\n if (!this.stores.has(storeId)) {\n return;\n }\n\n this.stores.delete(storeId);\n ids.delete(storeId);\n\n if (suspenseId && this.suspenseRelations.get(suspenseId)?.has(storeId)) {\n this.suspenseRelations.get(suspenseId)!.delete(storeId);\n }\n\n this.removeRelationContext(store.libStoreContextId!);\n\n if ('onDestroy' in store) {\n store.onDestroy?.();\n }\n\n EventManager.publish(Events.DELETE_STORE, { store });\n }\n\n /**\n * Mount stores to component\n *\n * NOTE: use only inside withStores wrapper\n */\n public mountStores(\n contextId: string,\n { globalStores = {}, relativeStores = {} }: Partial<IGroupedStores>,\n ): () => void {\n const { shouldRemoveInitState } = this.options;\n const touchableStores = { ...globalStores, ...relativeStores };\n\n Object.values(touchableStores).forEach((store) => {\n const storeId = store.libStoreId!;\n\n // cleanup init state\n if (shouldRemoveInitState && this.initState[storeId]) {\n delete this.initState[storeId];\n }\n\n this.setStoreStatus(store, StoreStatus.inUse);\n EventManager.publish(Events.MOUNT_STORE, { store });\n });\n\n return () => {\n Object.values(touchableStores).forEach((store) => {\n if (store.isGlobal) {\n return;\n }\n\n this.setStoreStatus(store, StoreStatus.unused);\n EventManager.publish(Events.UNMOUNT_STORE, { store });\n });\n\n this.removeRelationContext(contextId);\n };\n }\n\n /**\n * Change the stores status to touched\n */\n public touchedStores(stores: TStores): void {\n Object.values(stores).forEach((store) => {\n if (store.libStoreStatus !== StoreStatus.init || store.isGlobal) {\n return;\n }\n\n this.setStoreStatus(store, StoreStatus.touched);\n });\n }\n\n /**\n * Change store status\n */\n protected setStoreStatus(store: TStores[string], status: StoreStatus): void {\n const { destroyTimers: { init = 500, touched = 10000, unused = 1000 } = {} } = this.options;\n\n store.libStoreStatus = status;\n\n clearTimeout(store.libDestroyTimer);\n\n let destroyTime = 0;\n\n switch (status) {\n case StoreStatus.init:\n destroyTime = init;\n break;\n\n case StoreStatus.touched:\n destroyTime = touched;\n break;\n\n case StoreStatus.unused:\n destroyTime = unused;\n break;\n }\n\n if (!destroyTime) {\n return;\n }\n\n store.libDestroyTimer = setTimeout(() => this.removeStore(store), destroyTime);\n }\n\n /**\n * Get store state\n */\n public getStoreState(store: TAnyStore, withNotExported = false): Record<string, any> {\n return store.toJSON?.() ?? Manager.getObservableProps(store, withNotExported);\n }\n\n /**\n * Get store's state\n */\n public toJSON(ids?: string[], isIncludeExported = false): Record<string, any> {\n const result = {};\n const stores = Array.isArray(ids)\n ? ids.reduce((res, id) => {\n if (this.stores.has(id)) {\n res.set(id, this.stores.get(id)!);\n }\n\n return res;\n }, new Map<string, TInitStore>())\n : this.stores;\n\n for (const [storeId, store] of stores.entries()) {\n result[storeId] = this.getStoreState(store, isIncludeExported);\n }\n\n return result;\n }\n\n /**\n * Save persisted store state to provided storage\n */\n public async savePersistedStore(store: IStorePersisted): Promise<boolean> {\n if (this.options.shouldDisablePersist || !this.storage) {\n return false;\n }\n\n try {\n await this.storage.saveStoreData(store, this.getStoreState(store, true));\n\n return true;\n } catch (e) {\n this.logger.err('Failed to persist stores: ', e);\n }\n\n return false;\n }\n\n /**\n * Get observable store props (fields)\n */\n public static getObservableProps(store: TAnyStore, withNotExported = false): Record<string, any> {\n const props = toJS(store);\n\n return Object.entries(props).reduce(\n (res, [prop, value]) => ({\n ...res,\n ...((isObservableProp(store, prop) &&\n !isPropExcludedFromExport(store, prop, withNotExported)) ||\n isPropSimpleExported(store, prop)\n ? { [prop]: value }\n : {}),\n ...(isPropObservableExported(store, prop)\n ? { [prop]: Manager.getObservableProps(store[prop] as TAnyStore) }\n : {}),\n }),\n {},\n );\n }\n\n /**\n * Persist store\n */\n public static persistStore<TSt>(\n store: IConstructableStore<TSt>,\n id: string,\n options: IPersistOptions = {},\n ): IConstructableStore<TSt> {\n Manager.persistedStores.add(id);\n\n store.libStoreId = id;\n\n // add storage options\n if (!('libStorageOptions' in store.prototype)) {\n store.prototype.libStorageOptions = options;\n }\n\n // add default wakeup handler\n if (!('wakeup' in store.prototype)) {\n store.prototype.wakeup = wakeup;\n }\n\n // add default changes listener\n if (!('addOnChangeListener' in store.prototype)) {\n store.prototype.addOnChangeListener = onChangeListener;\n }\n\n return store;\n }\n}\n\nexport default Manager;\n"],"names":["Manager","static","stores","Map","storesRelations","Set","initState","storage","storesParams","options","shouldDisablePersist","shouldRemoveInitState","failedCreationStrategy","suspenseRelations","logger","constructor","this","Logger","level","manager","CombinedStorage","default","undefined","Object","assign","instance","window","state","mbxM","push","pushInitState","Array","isArray","forEach","init","get","e","err","Error","getStores","getStoresRelations","getSuspenseRelations","getPersistedStoresIds","persistedStores","storesState","storeId","entries","getStoreId","store","params","id","contextId","key","libStoreId","name","isGlobal","getStore","has","createStore","parentId","ROOT_CONTEXT_ID","suspenseId","componentName","componentProps","lookupStore","defaultParentId","clearId","split","ids","matchedIds","filter","startsWith","length","getBiggerContext","ctx1","ctx2","regexp","replace","newStore","storeManager","targetStore","targetParams","libStoreContextId","libStoreParentId","libStoreSuspenseId","libStoreComponentName","setStoreStatus","StoreStatus","inUse","prepareStore","EventManager","publish","Events","CREATE_STORE","createStores","map","result","reduce","res","s","isParent","msg","warn","debug","hasCreationFailure","storeInstance","parentStores","globalStores","relativeStores","createRelationContext","set","removeRelationContext","size","delete","deepMerge","wakeup","persistedState","getStoreData","onDestroyDefault","onDestroy","bind","removeListener","addOnChangeListener","add","removeStore","DELETE_STORE","mountStores","touchableStores","values","MOUNT_STORE","unused","UNMOUNT_STORE","touchedStores","libStoreStatus","touched","status","destroyTimers","clearTimeout","libDestroyTimer","destroyTime","setTimeout","getStoreState","withNotExported","toJSON","getObservableProps","isIncludeExported","savePersistedStore","saveStoreData","props","toJS","prop","value","isObservableProp","isPropExcludedFromExport","isPropSimpleExported","isPropObservableExported","persistStore","prototype","libStorageOptions","onChangeListener"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"manager.js","sources":["../src/manager.ts"],"sourcesContent":["import EventManager from '@lomray/event-manager';\nimport { isObservableProp, toJS } from 'mobx';\nimport { ROOT_CONTEXT_ID } from './constants';\nimport deepMerge from './deep-merge';\nimport Events from './events';\nimport Logger from './logger';\nimport {\n isPropExcludedFromExport,\n isPropObservableExported,\n isPropSimpleExported,\n} from './make-exported';\nimport onChangeListener from './on-change-listener';\nimport CombinedStorage from './storages/combined-storage';\nimport StoreStatus from './store-status';\nimport type {\n IConstructableStore,\n IGroupedStores,\n IManagerOptions,\n IManagerParams,\n IPersistOptions,\n IStoreParams,\n IStorePersisted,\n TAnyStore,\n TInitStore,\n TStoreDefinition,\n TStores,\n} from './types';\nimport wakeup from './wakeup';\n\n/**\n * Mobx stores manager\n */\nclass Manager {\n /**\n * Manger instance\n */\n protected static instance: Manager;\n\n /**\n * Created stores\n */\n protected readonly stores = new Map<string, TInitStore>();\n\n /**\n * Relations between stores\n */\n protected readonly storesRelations = new Map<\n string, // contextId\n { ids: Set<string>; parentId: string | null; componentName?: string }\n >();\n\n /**\n * Save persisted stores identities\n */\n protected static readonly persistedStores = new Set<string>();\n\n /**\n * Initial stores state (local storage, custom etc.)\n */\n protected readonly initState: Record<string, any>;\n\n /**\n * Storage for persisted stores\n */\n public readonly storage?: CombinedStorage;\n\n /**\n * Additional store's constructor params\n */\n protected readonly storesParams: IManagerParams['storesParams'];\n\n /**\n * Manager options\n */\n public readonly options: IManagerOptions = {\n shouldDisablePersist: false,\n shouldRemoveInitState: true,\n failedCreationStrategy: 'empty',\n };\n\n /**\n * Suspense stores relations\n * @see withStores\n */\n protected suspenseRelations: Map<string, Set<string>> = new Map();\n\n /**\n * Mobx manager logger\n */\n protected readonly logger: Logger;\n\n /**\n * @constructor\n */\n public constructor({ initState, storesParams, storage, options, logger }: IManagerParams = {}) {\n this.initState = initState || {};\n this.storesParams = storesParams || {};\n this.logger =\n logger && 'log' in logger\n ? logger\n : new Logger({ level: 3, ...(logger ?? {}), manager: this });\n this.storage =\n storage instanceof CombinedStorage\n ? storage\n : storage\n ? new CombinedStorage({ default: storage })\n : undefined;\n\n Object.assign(this.options, options || {});\n\n Manager.instance = this;\n\n // only client side\n if (typeof window !== 'undefined') {\n const state = window.mbxM;\n\n window.mbxM = { push: this.pushInitState };\n\n (Array.isArray(state) ? state : []).forEach(this.pushInitState);\n }\n }\n\n /**\n * Init store manager\n */\n public async init(): Promise<Manager> {\n try {\n if (this.storage) {\n await this.storage.get();\n }\n } catch (e) {\n this.logger.err('Failed initialized store manager: ', e);\n }\n\n return this;\n }\n\n /**\n * Get manager instance\n */\n public static get(): Manager {\n if (!Manager.instance) {\n throw new Error('Store manager is not initialized.');\n }\n\n return Manager.instance;\n }\n\n /**\n * Get all stores\n */\n public getStores(): Manager['stores'] {\n return this.stores;\n }\n\n /**\n * Get stores relations\n */\n public getStoresRelations(): Manager['storesRelations'] {\n return this.storesRelations;\n }\n\n /**\n * Get suspense relations with stores\n */\n public getSuspenseRelations(): Manager['suspenseRelations'] {\n return this.suspenseRelations;\n }\n\n /**\n * Get persisted stores ids\n */\n public static getPersistedStoresIds(): Set<string> {\n return Manager.persistedStores;\n }\n\n /**\n * Push initial state dynamically\n * E.g. when stream html\n */\n public pushInitState = (storesState: Record<string, any> = {}): void => {\n for (const [storeId, state] of Object.entries(storesState)) {\n this.initState[storeId] = state;\n }\n };\n\n /**\n * Get store identity\n */\n protected getStoreId<T extends TAnyStore>(\n store: IConstructableStore<T> | TInitStore,\n params: IStoreParams = {},\n ): string {\n const { id, contextId, key } = params;\n\n if (id) {\n return id;\n }\n\n if (store.libStoreId) {\n return store.libStoreId;\n }\n\n let storeId = (store['id'] as string) || (store['name'] as string) || store.constructor.name;\n\n if (store.isGlobal) {\n return storeId;\n }\n\n storeId = `${storeId}--${contextId!}`;\n\n return key ? `${storeId}--${key}` : storeId;\n }\n\n /**\n * Get exist store\n */\n public getStore<T>(store: IConstructableStore<T>, params: IStoreParams = {}): T | undefined {\n const storeId = this.getStoreId(store, params);\n\n // full match\n if (this.stores.has(storeId)) {\n return this.stores.get(storeId) as T;\n }\n\n // in case with global store (create if not exist)\n if (store.isGlobal) {\n return this.createStore(store, {\n id: storeId,\n contextId: 'global',\n parentId: ROOT_CONTEXT_ID,\n suspenseId: '',\n componentName: 'root-app',\n componentProps: {},\n });\n }\n\n // try to look up store in current or parent context\n return this.lookupStore(storeId, params) as T;\n }\n\n /**\n * Lookup store\n */\n protected lookupStore(id: string, params: IStoreParams): TInitStore<TAnyStore> | undefined {\n const { contextId, parentId: defaultParentId } = params;\n const clearId = id.split('--')?.[0];\n const { ids, parentId } = this.storesRelations.get(contextId!) ?? {\n ids: new Set(),\n parentId: defaultParentId,\n };\n\n const matchedIds = [...ids].filter((storeId) => storeId.startsWith(`${clearId}--`));\n\n if (matchedIds.length === 1) {\n return this.stores.get(matchedIds[0]);\n } else if (matchedIds.length > 1) {\n this.logger.err(\n 'Parent context has multiple stores with the same id, please pass key to getStore function.',\n );\n\n return undefined;\n }\n\n if (!parentId || parentId === ROOT_CONTEXT_ID) {\n return undefined;\n }\n\n return this.lookupStore(id, { contextId: this.getBiggerContext(parentId, defaultParentId) });\n }\n\n /**\n * Get bigger context from two\n */\n protected getBiggerContext(ctx1?: string, ctx2?: string): string | undefined {\n if (!ctx1) {\n return ctx2;\n } else if (!ctx2) {\n return ctx1;\n }\n\n const regexp = /[^a-zA-Z]/g;\n\n return ctx1.replace(regexp, '') > ctx2.replace(regexp, '') ? ctx1 : ctx2;\n }\n\n /**\n * Create new store instance\n */\n protected createStore<T>(\n store: IConstructableStore<T>,\n params: Omit<Required<IStoreParams>, 'key'>,\n ): T {\n const { id, contextId, parentId, suspenseId, componentName, componentProps } = params;\n\n // only for global store\n if (this.stores.has(id)) {\n return this.stores.get(id) as T;\n }\n\n const newStore = new store({\n ...this.storesParams,\n storeManager: this,\n getStore: <TS>(\n targetStore: IConstructableStore<TS>,\n targetParams = { contextId, parentId },\n ) => this.getStore(targetStore, targetParams),\n componentProps,\n initState: this.initState[id],\n });\n\n // assign params to new store\n newStore.libStoreId = id;\n newStore.isGlobal = store.isGlobal;\n newStore.libStoreContextId = store.isGlobal ? 'global' : contextId;\n newStore.libStoreParentId =\n store.isGlobal || !parentId || parentId === contextId ? ROOT_CONTEXT_ID : parentId;\n newStore.libStoreSuspenseId = suspenseId;\n newStore.libStoreComponentName = componentName;\n\n this.setStoreStatus(newStore, store.isGlobal ? StoreStatus.inUse : StoreStatus.init);\n this.prepareStore(newStore);\n EventManager.publish(Events.CREATE_STORE, { store });\n\n return newStore as T;\n }\n\n /**\n * Create stores for component\n *\n * NOTE: use only inside withStores wrapper\n */\n public createStores(\n map: [string, TStoreDefinition][],\n parentId: string,\n contextId: string,\n suspenseId: string,\n componentName: string,\n componentProps: Record<string, any> = {},\n ): IGroupedStores {\n const { failedCreationStrategy } = this.options;\n\n const result = map.reduce(\n (res, [key, store]) => {\n const {\n id,\n store: s,\n isParent = false,\n } = 'store' in store ? store : { store, id: undefined, isParent: false };\n let storeId =\n id ||\n (isParent\n ? (this.getStore(s, { contextId, parentId })?.libStoreId as string)\n : this.getStoreId(s, { key, contextId }));\n\n if (!storeId) {\n const msg = `Cannot find or create store '${key}': '${this.getStoreId(s)}'`;\n\n this.logger.warn(msg);\n this.logger.debug(\n msg,\n { contextId, parentId, suspenseId, componentName, isParent },\n true,\n );\n\n if (failedCreationStrategy === 'dummy') {\n // try to force create store\n storeId = this.getStoreId(s, { key, contextId });\n } else {\n if (failedCreationStrategy === 'empty') {\n res.hasCreationFailure = true;\n }\n\n return res;\n }\n }\n\n const storeInstance = this.createStore(s, {\n id: storeId,\n contextId,\n parentId,\n suspenseId,\n componentName,\n componentProps: !s.isGlobal && !isParent ? componentProps : {},\n });\n\n if (isParent) {\n res.parentStores[key] = storeInstance;\n } else if (storeInstance.isGlobal) {\n res.globalStores[key] = storeInstance;\n } else {\n res.relativeStores[key] = storeInstance;\n }\n\n return res;\n },\n { relativeStores: {}, parentStores: {}, globalStores: {}, hasCreationFailure: false },\n );\n\n // need create context relation in case when component doesn't include relative stores\n this.createRelationContext(contextId, parentId, componentName);\n\n return result;\n }\n\n /**\n * Create empty relation context\n */\n protected createRelationContext(\n contextId: string,\n parentId?: string,\n componentName?: string,\n ): void {\n if (this.storesRelations.has(contextId)) {\n return;\n }\n\n this.storesRelations.set(contextId, {\n ids: new Set(),\n parentId: !parentId || parentId === contextId ? ROOT_CONTEXT_ID : parentId,\n componentName,\n });\n }\n\n /**\n * Delete relation context id\n */\n protected removeRelationContext(contextId: string): void {\n const storesRelations = this.storesRelations.get(contextId);\n\n if (!storesRelations || contextId === ROOT_CONTEXT_ID || storesRelations.ids.size > 0) {\n return;\n }\n\n this.storesRelations.delete(contextId);\n }\n\n /**\n * Append callback to store destroy lifecycle\n */\n protected appendDestroyCallback(store: TStores[string], callback?: () => void): void {\n if (!callback) {\n return;\n }\n\n const onDestroyDefault = store.onDestroy?.bind(store);\n\n store.onDestroy = (): void => {\n callback();\n onDestroyDefault?.();\n };\n }\n\n /**\n * Prepare store before usage\n */\n protected prepareStore(store: TStores[string]): void {\n const storeId = store.libStoreId!;\n const contextId = store.libStoreContextId!;\n const suspenseId = store.libStoreSuspenseId!;\n\n if (this.stores.has(storeId)) {\n return;\n }\n\n // restore initial state from server\n const initState = this.initState[storeId];\n\n if (initState) {\n deepMerge(store, initState);\n }\n\n // restore persisted state\n if ('wakeup' in store && Manager.persistedStores.has(storeId)) {\n store.wakeup?.({\n initState,\n persistedState: this.storage?.getStoreData(store),\n manager: this,\n });\n }\n\n // track changes in persisted store\n if (Manager.persistedStores.has(storeId) && 'addOnChangeListener' in store) {\n const removeListener = store.addOnChangeListener!(store, this);\n\n this.appendDestroyCallback(store, removeListener);\n }\n\n const initCleanup = store.init?.();\n\n if (typeof initCleanup === 'function') {\n this.appendDestroyCallback(store, initCleanup);\n }\n\n this.createRelationContext(contextId, store.libStoreParentId, store.libStoreComponentName);\n\n if (!this.suspenseRelations.has(suspenseId)) {\n this.suspenseRelations.set(suspenseId, new Set());\n }\n\n const { ids } = this.storesRelations.get(contextId)!;\n\n // add store to manager\n this.stores.set(storeId, store);\n ids.add(storeId);\n // add store relation with suspense\n this.suspenseRelations.get(suspenseId)!.add(storeId);\n }\n\n /**\n * Remove store\n */\n protected removeStore(store: TStores[string]): void {\n const storeId = store.libStoreId!;\n const suspenseId = store.libStoreSuspenseId!;\n const { ids } = this.storesRelations.get(store.libStoreContextId!) ?? { ids: new Set() };\n\n if (!this.stores.has(storeId)) {\n return;\n }\n\n this.stores.delete(storeId);\n ids.delete(storeId);\n\n if (suspenseId && this.suspenseRelations.get(suspenseId)?.has(storeId)) {\n this.suspenseRelations.get(suspenseId)!.delete(storeId);\n }\n\n this.removeRelationContext(store.libStoreContextId!);\n\n if ('onDestroy' in store) {\n store.onDestroy?.();\n }\n\n EventManager.publish(Events.DELETE_STORE, { store });\n }\n\n /**\n * Mount stores to component\n *\n * NOTE: use only inside withStores wrapper\n */\n public mountStores(\n contextId: string,\n { globalStores = {}, relativeStores = {} }: Partial<IGroupedStores>,\n ): () => void {\n const { shouldRemoveInitState } = this.options;\n const touchableStores = { ...globalStores, ...relativeStores };\n\n Object.values(touchableStores).forEach((store) => {\n const storeId = store.libStoreId!;\n\n // cleanup init state\n if (shouldRemoveInitState && this.initState[storeId]) {\n delete this.initState[storeId];\n }\n\n this.setStoreStatus(store, StoreStatus.inUse);\n EventManager.publish(Events.MOUNT_STORE, { store });\n });\n\n return () => {\n Object.values(touchableStores).forEach((store) => {\n if (store.isGlobal) {\n return;\n }\n\n this.setStoreStatus(store, StoreStatus.unused);\n EventManager.publish(Events.UNMOUNT_STORE, { store });\n });\n\n this.removeRelationContext(contextId);\n };\n }\n\n /**\n * Destroy manager stores and detach internal relations\n */\n public destroy(): void {\n for (const store of Array.from(this.stores.values())) {\n clearTimeout(store.libDestroyTimer);\n this.removeStore(store);\n }\n\n this.storesRelations.clear();\n this.suspenseRelations.clear();\n }\n\n /**\n * Change the stores status to touched\n */\n public touchedStores(stores: TStores): void {\n Object.values(stores).forEach((store) => {\n if (store.libStoreStatus !== StoreStatus.init || store.isGlobal) {\n return;\n }\n\n this.setStoreStatus(store, StoreStatus.touched);\n });\n }\n\n /**\n * Change store status\n */\n protected setStoreStatus(store: TStores[string], status: StoreStatus): void {\n const { destroyTimers: { init = 500, touched = 10000, unused = 1000 } = {} } = this.options;\n\n store.libStoreStatus = status;\n\n clearTimeout(store.libDestroyTimer);\n\n let destroyTime = 0;\n\n switch (status) {\n case StoreStatus.init:\n destroyTime = init;\n break;\n\n case StoreStatus.touched:\n destroyTime = touched;\n break;\n\n case StoreStatus.unused:\n destroyTime = unused;\n break;\n }\n\n if (!destroyTime) {\n return;\n }\n\n store.libDestroyTimer = setTimeout(() => this.removeStore(store), destroyTime);\n }\n\n /**\n * Get store state\n */\n public getStoreState(store: TAnyStore, withNotExported = false): Record<string, any> {\n return store.toJSON?.() ?? Manager.getObservableProps(store, withNotExported);\n }\n\n /**\n * Get store's state\n */\n public toJSON(ids?: string[], isIncludeExported = false): Record<string, any> {\n const result = {};\n const stores = Array.isArray(ids)\n ? ids.reduce((res, id) => {\n if (this.stores.has(id)) {\n res.set(id, this.stores.get(id)!);\n }\n\n return res;\n }, new Map<string, TInitStore>())\n : this.stores;\n\n for (const [storeId, store] of stores.entries()) {\n result[storeId] = this.getStoreState(store, isIncludeExported);\n }\n\n return result;\n }\n\n /**\n * Save persisted store state to provided storage\n */\n public async savePersistedStore(store: IStorePersisted): Promise<boolean> {\n if (this.options.shouldDisablePersist || !this.storage) {\n return false;\n }\n\n try {\n await this.storage.saveStoreData(store, this.getStoreState(store, true));\n\n return true;\n } catch (e) {\n this.logger.err('Failed to persist stores: ', e);\n }\n\n return false;\n }\n\n /**\n * Get observable store props (fields)\n */\n public static getObservableProps(store: TAnyStore, withNotExported = false): Record<string, any> {\n const props = toJS(store);\n\n return Object.entries(props).reduce(\n (res, [prop, value]) => ({\n ...res,\n ...((isObservableProp(store, prop) &&\n !isPropExcludedFromExport(store, prop, withNotExported)) ||\n isPropSimpleExported(store, prop)\n ? { [prop]: value }\n : {}),\n ...(isPropObservableExported(store, prop)\n ? { [prop]: Manager.getObservableProps(store[prop] as TAnyStore) }\n : {}),\n }),\n {},\n );\n }\n\n /**\n * Persist store\n */\n public static persistStore<TSt>(\n store: IConstructableStore<TSt>,\n id: string,\n options: IPersistOptions = {},\n ): IConstructableStore<TSt> {\n Manager.persistedStores.add(id);\n\n store.libStoreId = id;\n\n // add storage options\n if (!('libStorageOptions' in store.prototype)) {\n store.prototype.libStorageOptions = options;\n }\n\n // add default wakeup handler\n if (!('wakeup' in store.prototype)) {\n store.prototype.wakeup = wakeup;\n }\n\n // add default changes listener\n if (!('addOnChangeListener' in store.prototype)) {\n store.prototype.addOnChangeListener = onChangeListener;\n }\n\n return store;\n }\n}\n\nexport default Manager;\n"],"names":["Manager","static","stores","Map","storesRelations","Set","initState","storage","storesParams","options","shouldDisablePersist","shouldRemoveInitState","failedCreationStrategy","suspenseRelations","logger","constructor","this","Logger","level","manager","CombinedStorage","default","undefined","Object","assign","instance","window","state","mbxM","push","pushInitState","Array","isArray","forEach","init","get","e","err","Error","getStores","getStoresRelations","getSuspenseRelations","getPersistedStoresIds","persistedStores","storesState","storeId","entries","getStoreId","store","params","id","contextId","key","libStoreId","name","isGlobal","getStore","has","createStore","parentId","ROOT_CONTEXT_ID","suspenseId","componentName","componentProps","lookupStore","defaultParentId","clearId","split","ids","matchedIds","filter","startsWith","length","getBiggerContext","ctx1","ctx2","regexp","replace","newStore","storeManager","targetStore","targetParams","libStoreContextId","libStoreParentId","libStoreSuspenseId","libStoreComponentName","setStoreStatus","StoreStatus","inUse","prepareStore","EventManager","publish","Events","CREATE_STORE","createStores","map","result","reduce","res","s","isParent","msg","warn","debug","hasCreationFailure","storeInstance","parentStores","globalStores","relativeStores","createRelationContext","set","removeRelationContext","size","delete","appendDestroyCallback","callback","onDestroyDefault","onDestroy","bind","deepMerge","wakeup","persistedState","getStoreData","removeListener","addOnChangeListener","initCleanup","add","removeStore","DELETE_STORE","mountStores","touchableStores","values","MOUNT_STORE","unused","UNMOUNT_STORE","destroy","from","clearTimeout","libDestroyTimer","clear","touchedStores","libStoreStatus","touched","status","destroyTimers","destroyTime","setTimeout","getStoreState","withNotExported","toJSON","getObservableProps","isIncludeExported","savePersistedStore","saveStoreData","props","toJS","prop","value","isObservableProp","isPropExcludedFromExport","isPropSimpleExported","isPropObservableExported","persistStore","prototype","libStorageOptions","onChangeListener"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lomray/react-mobx-manager",
|
|
3
|
-
"version": "4.2
|
|
3
|
+
"version": "4.3.0-beta.2",
|
|
4
4
|
"description": "This package provides Mobx stores manager for react.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -32,41 +32,43 @@
|
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "rollup -c",
|
|
34
34
|
"build:watch": "rollup -c -w",
|
|
35
|
+
"docs:dev": "vitepress dev docs",
|
|
36
|
+
"docs:build": "vitepress build docs",
|
|
37
|
+
"docs:preview": "vitepress preview docs",
|
|
35
38
|
"lint:check": "eslint \"src/**/*.{ts,tsx,*.ts,*tsx}\"",
|
|
36
39
|
"lint:format": "eslint --fix \"src/**/*.{ts,tsx,*.ts,*tsx}\"",
|
|
37
40
|
"ts:check": "tsc --project ./tsconfig.checks.json --skipLibCheck --noemit",
|
|
38
41
|
"test": "vitest run"
|
|
39
42
|
},
|
|
40
43
|
"devDependencies": {
|
|
41
|
-
"@commitlint/cli": "^20.
|
|
42
|
-
"@commitlint/config-conventional": "^20.
|
|
43
|
-
"@lomray/eslint-config-react": "^
|
|
44
|
-
"@lomray/prettier-config": "^2.0
|
|
45
|
-
"@rollup/plugin-terser": "^0.
|
|
46
|
-
"@types/chai": "^
|
|
47
|
-
"@types/hoist-non-react-statics": "^3.3.
|
|
48
|
-
"@types/lodash": "^4.
|
|
44
|
+
"@commitlint/cli": "^20.5.0",
|
|
45
|
+
"@commitlint/config-conventional": "^20.5.0",
|
|
46
|
+
"@lomray/eslint-config-react": "^6.0.3",
|
|
47
|
+
"@lomray/prettier-config": "^2.1.0",
|
|
48
|
+
"@rollup/plugin-terser": "^1.0.0",
|
|
49
|
+
"@types/chai": "^5.2.3",
|
|
50
|
+
"@types/hoist-non-react-statics": "^3.3.7",
|
|
51
|
+
"@types/lodash": "^4.17.24",
|
|
49
52
|
"@types/react": "^18.2.47",
|
|
50
|
-
"@types/sinon": "^
|
|
51
|
-
"@
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"eslint": "^8.57.0",
|
|
53
|
+
"@types/sinon": "^21.0.0",
|
|
54
|
+
"@vitest/coverage-v8": "^4.1.0",
|
|
55
|
+
"chai": "^6.2.2",
|
|
56
|
+
"eslint": "^9.39.4",
|
|
55
57
|
"husky": "^9.1.7",
|
|
56
|
-
"jsdom": "^
|
|
57
|
-
"lint-staged": "^16.
|
|
58
|
-
"prettier": "^3.
|
|
59
|
-
"rollup": "^4.
|
|
58
|
+
"jsdom": "^29.0.0",
|
|
59
|
+
"lint-staged": "^16.4.0",
|
|
60
|
+
"prettier": "^3.8.1",
|
|
61
|
+
"rollup": "^4.59.0",
|
|
60
62
|
"rollup-plugin-copy": "^3.5.0",
|
|
61
63
|
"rollup-plugin-folder-input": "^1.0.1",
|
|
62
64
|
"rollup-plugin-ts": "^3.4.5",
|
|
63
65
|
"semantic-release": "^25.0.3",
|
|
64
|
-
"sinon": "^
|
|
65
|
-
"sinon-chai": "^3.7.0",
|
|
66
|
+
"sinon": "^21.0.3",
|
|
66
67
|
"typescript": "4.9.5",
|
|
67
68
|
"vite": "^7.3.1",
|
|
68
69
|
"vite-tsconfig-paths": "^6.1.1",
|
|
69
|
-
"
|
|
70
|
+
"vitepress": "^1.6.4",
|
|
71
|
+
"vitest": "^4.1.0"
|
|
70
72
|
},
|
|
71
73
|
"peerDependencies": {
|
|
72
74
|
"@lomray/consistent-suspense": ">=2.0.1",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IConstructableStore, TAnyStore } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Mark store definition as parent store
|
|
4
|
+
*/
|
|
5
|
+
declare const parentStore: <TSto extends TAnyStore>(store: IConstructableStore<TSto>) => {
|
|
6
|
+
store: IConstructableStore<TSto>;
|
|
7
|
+
isParent: true;
|
|
8
|
+
};
|
|
9
|
+
export { parentStore as default };
|
package/parent-store.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parent-store.js","sources":["../src/parent-store.ts"],"sourcesContent":["import type { IConstructableStore, TAnyStore } from './types';\n\n/**\n * Mark store definition as parent store\n */\nconst parentStore = <TSto extends TAnyStore>(store: IConstructableStore<TSto>) => ({\n store,\n isParent: true as const,\n});\n\nexport default parentStore;\n"],"names":["parentStore","store","isParent"],"mappings":"AAKA,MAAMA,EAAuCC,IAAgC,CAC3EA,QACAC,UAAU"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import Manager from "../../../manager.js";
|
|
2
|
+
import ManagerHmr from "./service.js";
|
|
3
|
+
import { IHmrOptions, IHmrRuntime } from "./types.js";
|
|
4
|
+
type TConnectOptions = Omit<IHmrOptions, 'manager'>;
|
|
5
|
+
declare const connectHmrRuntime: (manager: Manager, runtime?: IHmrRuntime, options?: TConnectOptions) => ManagerHmr;
|
|
6
|
+
declare const connectViteHmr: (manager: Manager, runtime?: IHmrRuntime, options?: TConnectOptions) => ManagerHmr;
|
|
7
|
+
declare const connectWebpackHmr: (manager: Manager, runtime?: IHmrRuntime, options?: TConnectOptions) => ManagerHmr;
|
|
8
|
+
declare const connectReactNativeHmr: (manager: Manager, runtime?: IHmrRuntime, options?: TConnectOptions) => ManagerHmr;
|
|
9
|
+
export { connectHmrRuntime as default, connectViteHmr, connectWebpackHmr, connectReactNativeHmr };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import e from"./service.js";const r=(r,t,n={})=>{const o=new e({manager:r,...n});return t?o.bind(t):o.restore(),o},t=(e,t,n={})=>r(e,t,n),n=(e,t,n={})=>r(e,t,n),o=(e,t,n={})=>r(e,t,n);export{o as connectReactNativeHmr,t as connectViteHmr,n as connectWebpackHmr,r as default};
|
|
2
|
+
//# sourceMappingURL=adapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.js","sources":["../../../../src/plugins/dev-extension/hmr/adapters.ts"],"sourcesContent":["import type Manager from '@src/manager';\nimport ManagerHmr from './service';\nimport type { IHmrOptions, IHmrRuntime } from './types';\n\ntype TConnectOptions = Omit<IHmrOptions, 'manager'>;\n\nconst connectHmrRuntime = (\n manager: Manager,\n runtime?: IHmrRuntime,\n options: TConnectOptions = {},\n): ManagerHmr => {\n const bridge = new ManagerHmr({ manager, ...options });\n\n if (runtime) {\n bridge.bind(runtime);\n } else {\n bridge.restore();\n }\n\n return bridge;\n};\n\nexport const connectViteHmr = (\n manager: Manager,\n runtime?: IHmrRuntime,\n options: TConnectOptions = {},\n): ManagerHmr => connectHmrRuntime(manager, runtime, options);\n\nexport const connectWebpackHmr = (\n manager: Manager,\n runtime?: IHmrRuntime,\n options: TConnectOptions = {},\n): ManagerHmr => connectHmrRuntime(manager, runtime, options);\n\nexport const connectReactNativeHmr = (\n manager: Manager,\n runtime?: IHmrRuntime,\n options: TConnectOptions = {},\n): ManagerHmr => connectHmrRuntime(manager, runtime, options);\n\nexport default connectHmrRuntime;\n"],"names":["connectHmrRuntime","manager","runtime","options","bridge","ManagerHmr","bind","restore","connectViteHmr","connectWebpackHmr","connectReactNativeHmr"],"mappings":"4BAMA,MAAMA,EAAoB,CACxBC,EACAC,EACAC,EAA2B,CAAA,KAE3B,MAAMC,EAAS,IAAIC,EAAW,CAAEJ,aAAYE,IAQ5C,OANID,EACFE,EAAOE,KAAKJ,GAEZE,EAAOG,UAGFH,GAGII,EAAiB,CAC5BP,EACAC,EACAC,EAA2B,CAAA,IACZH,EAAkBC,EAASC,EAASC,GAExCM,EAAoB,CAC/BR,EACAC,EACAC,EAA2B,CAAA,IACZH,EAAkBC,EAASC,EAASC,GAExCO,EAAwB,CACnCT,EACAC,EACAC,EAA2B,CAAA,IACZH,EAAkBC,EAASC,EAASC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { IHmrOptions, IHmrRuntime, IHmrSnapshot } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Dev-only HMR snapshot bridge for store manager
|
|
4
|
+
*/
|
|
5
|
+
declare class ManagerHmr {
|
|
6
|
+
/**
|
|
7
|
+
* @protected
|
|
8
|
+
*/
|
|
9
|
+
protected readonly manager: IHmrOptions['manager'];
|
|
10
|
+
/**
|
|
11
|
+
* @protected
|
|
12
|
+
*/
|
|
13
|
+
protected readonly appId: string;
|
|
14
|
+
/**
|
|
15
|
+
* @constructor
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* @constructor
|
|
19
|
+
*/
|
|
20
|
+
constructor({ manager, appId }: IHmrOptions);
|
|
21
|
+
/**
|
|
22
|
+
* Get shared HMR storage
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Get shared HMR storage
|
|
26
|
+
*/
|
|
27
|
+
protected getStorage(): Record<string, IHmrSnapshot | undefined>;
|
|
28
|
+
/**
|
|
29
|
+
* Get current snapshot if exists
|
|
30
|
+
*/
|
|
31
|
+
/**
|
|
32
|
+
* Get current snapshot if exists
|
|
33
|
+
*/
|
|
34
|
+
protected getSnapshot(runtimeData?: Record<string, unknown>): IHmrSnapshot | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Save current stores snapshot
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Save current stores snapshot
|
|
40
|
+
*/
|
|
41
|
+
save(runtimeData?: Record<string, unknown>): IHmrSnapshot;
|
|
42
|
+
/**
|
|
43
|
+
* Restore stores snapshot
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* Restore stores snapshot
|
|
47
|
+
*/
|
|
48
|
+
restore(runtimeData?: Record<string, unknown>): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Clear saved snapshot
|
|
51
|
+
*/
|
|
52
|
+
/**
|
|
53
|
+
* Clear saved snapshot
|
|
54
|
+
*/
|
|
55
|
+
clear(runtimeData?: Record<string, unknown>): void;
|
|
56
|
+
/**
|
|
57
|
+
* Save state and destroy manager instance
|
|
58
|
+
*/
|
|
59
|
+
/**
|
|
60
|
+
* Save state and destroy manager instance
|
|
61
|
+
*/
|
|
62
|
+
dispose(runtimeData?: Record<string, unknown>): void;
|
|
63
|
+
/**
|
|
64
|
+
* Bind to HMR runtime
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* Bind to HMR runtime
|
|
68
|
+
*/
|
|
69
|
+
bind(runtime: IHmrRuntime): ManagerHmr;
|
|
70
|
+
}
|
|
71
|
+
export { ManagerHmr as default };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import t from"../../../deep-merge.js";const e="__MOBX_STORE_MANAGER_HMR__";class s{manager;appId;constructor({manager:t,appId:e="default"}){this.manager=t,this.appId=e}getStorage(){const t=globalThis;return t[e]||(t[e]={}),t[e]}getSnapshot(t){const e=t?.[this.appId];return e||this.getStorage()[this.appId]}save(t){const e={stores:Array.from(this.manager.getStores().values()).reduce((t,e)=>{const s=e.libStoreId;return s?(t[s]=this.manager.getStoreState(e,!0),t):t},{})};return this.getStorage()[this.appId]=e,t&&(t[this.appId]=e),e}restore(e){const s=this.getSnapshot(e);return!!s&&(this.manager.pushInitState(s.stores),this.manager.getStores().forEach((e,r)=>{const a=s.stores[r];a&&t(e,a)}),this.clear(e),!0)}clear(t){delete this.getStorage()[this.appId],t&&delete t[this.appId]}dispose(t){this.save(t),this.manager.destroy()}bind(t){return this.restore(t.data),t.accept(()=>{}),t.dispose(t=>{this.dispose(t)}),this}}export{s as default};
|
|
2
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sources":["../../../../src/plugins/dev-extension/hmr/service.ts"],"sourcesContent":["import deepMerge from '@src/deep-merge';\nimport type { TAnyStore } from '@src/types';\nimport type { IHmrOptions, IHmrRuntime, IHmrSnapshot } from './types';\n\nconst HMR_GLOBAL_KEY = '__MOBX_STORE_MANAGER_HMR__';\n\n/**\n * Dev-only HMR snapshot bridge for store manager\n */\nclass ManagerHmr {\n /**\n * @protected\n */\n protected readonly manager: IHmrOptions['manager'];\n\n /**\n * @protected\n */\n protected readonly appId: string;\n\n /**\n * @constructor\n */\n public constructor({ manager, appId = 'default' }: IHmrOptions) {\n this.manager = manager;\n this.appId = appId;\n }\n\n /**\n * Get shared HMR storage\n */\n protected getStorage(): Record<string, IHmrSnapshot | undefined> {\n const scope = globalThis as typeof globalThis & {\n [HMR_GLOBAL_KEY]?: Record<string, IHmrSnapshot | undefined>;\n };\n\n if (!scope[HMR_GLOBAL_KEY]) {\n scope[HMR_GLOBAL_KEY] = {};\n }\n\n return scope[HMR_GLOBAL_KEY];\n }\n\n /**\n * Get current snapshot if exists\n */\n protected getSnapshot(runtimeData?: Record<string, unknown>): IHmrSnapshot | undefined {\n const dataSnapshot = runtimeData?.[this.appId];\n\n if (dataSnapshot) {\n return dataSnapshot as IHmrSnapshot;\n }\n\n return this.getStorage()[this.appId];\n }\n\n /**\n * Save current stores snapshot\n */\n public save(runtimeData?: Record<string, unknown>): IHmrSnapshot {\n const stores = Array.from(this.manager.getStores().values()).reduce(\n (result, store) => {\n const storeId = store.libStoreId;\n\n if (!storeId) {\n return result;\n }\n\n result[storeId] = this.manager.getStoreState(store as TAnyStore, true);\n\n return result;\n },\n {} as IHmrSnapshot['stores'],\n );\n const snapshot = { stores };\n\n this.getStorage()[this.appId] = snapshot;\n\n if (runtimeData) {\n runtimeData[this.appId] = snapshot;\n }\n\n return snapshot;\n }\n\n /**\n * Restore stores snapshot\n */\n public restore(runtimeData?: Record<string, unknown>): boolean {\n const snapshot = this.getSnapshot(runtimeData);\n\n if (!snapshot) {\n return false;\n }\n\n this.manager.pushInitState(snapshot.stores);\n\n this.manager.getStores().forEach((store, storeId) => {\n const state = snapshot.stores[storeId];\n\n if (!state) {\n return;\n }\n\n deepMerge(store, state);\n });\n\n this.clear(runtimeData);\n\n return true;\n }\n\n /**\n * Clear saved snapshot\n */\n public clear(runtimeData?: Record<string, unknown>): void {\n delete this.getStorage()[this.appId];\n\n if (runtimeData) {\n delete runtimeData[this.appId];\n }\n }\n\n /**\n * Save state and destroy manager instance\n */\n public dispose(runtimeData?: Record<string, unknown>): void {\n this.save(runtimeData);\n this.manager.destroy();\n }\n\n /**\n * Bind to HMR runtime\n */\n public bind(runtime: IHmrRuntime): ManagerHmr {\n this.restore(runtime.data);\n runtime.accept(() => undefined);\n runtime.dispose((data) => {\n this.dispose(data);\n });\n\n return this;\n }\n}\n\nexport default ManagerHmr;\n"],"names":["HMR_GLOBAL_KEY","ManagerHmr","manager","appId","constructor","this","getStorage","scope","globalThis","getSnapshot","runtimeData","dataSnapshot","save","snapshot","stores","Array","from","getStores","values","reduce","result","store","storeId","libStoreId","getStoreState","restore","pushInitState","forEach","state","deepMerge","clear","dispose","destroy","bind","runtime","data","accept"],"mappings":"sCAIA,MAAMA,EAAiB,6BAKvB,MAAMC,EAIeC,QAKAC,MAKnB,WAAAC,EAAmBF,QAAEA,EAAOC,MAAEA,EAAQ,YACpCE,KAAKH,QAAUA,EACfG,KAAKF,MAAQA,CACf,CAKU,UAAAG,GACR,MAAMC,EAAQC,WAQd,OAJKD,EAAMP,KACTO,EAAMP,GAAkB,CAAA,GAGnBO,EAAMP,EACf,CAKU,WAAAS,CAAYC,GACpB,MAAMC,EAAeD,IAAcL,KAAKF,OAExC,OAAIQ,GAIGN,KAAKC,aAAaD,KAAKF,MAChC,CAKO,IAAAS,CAAKF,GACV,MAcMG,EAAW,CAAEC,OAdJC,MAAMC,KAAKX,KAAKH,QAAQe,YAAYC,UAAUC,OAC3D,CAACC,EAAQC,KACP,MAAMC,EAAUD,EAAME,WAEtB,OAAKD,GAILF,EAAOE,GAAWjB,KAAKH,QAAQsB,cAAcH,GAAoB,GAE1DD,GALEA,GAOX,CAAA,IAUF,OANAf,KAAKC,aAAaD,KAAKF,OAASU,EAE5BH,IACFA,EAAYL,KAAKF,OAASU,GAGrBA,CACT,CAKO,OAAAY,CAAQf,GACb,MAAMG,EAAWR,KAAKI,YAAYC,GAElC,QAAKG,IAILR,KAAKH,QAAQwB,cAAcb,EAASC,QAEpCT,KAAKH,QAAQe,YAAYU,QAAQ,CAACN,EAAOC,KACvC,MAAMM,EAAQf,EAASC,OAAOQ,GAEzBM,GAILC,EAAUR,EAAOO,KAGnBvB,KAAKyB,MAAMpB,IAEJ,EACT,CAKO,KAAAoB,CAAMpB,UACJL,KAAKC,aAAaD,KAAKF,OAE1BO,UACKA,EAAYL,KAAKF,MAE5B,CAKO,OAAA4B,CAAQrB,GACbL,KAAKO,KAAKF,GACVL,KAAKH,QAAQ8B,SACf,CAKO,IAAAC,CAAKC,GAOV,OANA7B,KAAKoB,QAAQS,EAAQC,MACrBD,EAAQE,OAAO,QACfF,EAAQH,QAASI,IACf9B,KAAK0B,QAAQI,KAGR9B,IACT"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Manager from "../../../manager.js";
|
|
2
|
+
interface IHmrSnapshot {
|
|
3
|
+
stores: Record<string, Record<string, any>>;
|
|
4
|
+
}
|
|
5
|
+
interface IHmrOptions {
|
|
6
|
+
manager: Manager;
|
|
7
|
+
appId?: string;
|
|
8
|
+
}
|
|
9
|
+
interface IHmrRuntime {
|
|
10
|
+
data?: Record<string, unknown>;
|
|
11
|
+
accept: (callback?: () => void) => void;
|
|
12
|
+
dispose: (callback: (data: Record<string, unknown>) => void) => void;
|
|
13
|
+
}
|
|
14
|
+
export { IHmrSnapshot, IHmrOptions, IHmrRuntime };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import t from"../deep-compare.js";class e{storages;persistData={};defaultId;constructor(t){this.storages=t,this.defaultId=Object.keys(t)?.[0]}async get(){try{const t=await Promise.all(Object.values(this.storages).map(t=>t.get()||{}));return this.persistData=Object.keys(this.storages).reduce((e,s,a)=>({...e,[s]:t[a]}),{}),this.persistData}catch
|
|
1
|
+
import t from"../deep-compare.js";class e{storages;persistData={};defaultId;constructor(t){this.storages=t,this.defaultId=Object.keys(t)?.[0]}async get(){try{const t=await Promise.all(Object.values(this.storages).map(t=>t.get()||{}));return this.persistData=Object.keys(this.storages).reduce((e,s,a)=>({...e,[s]:t[a]}),{}),this.persistData}catch{return{}}}flush(){return Promise.all(Object.values(this.storages).map(t=>t.flush()))}set(t,e){const s=this.storages[e??this.defaultId];if(s)return s.set(t)}getStoreOptions(t){return{attributes:{[this.defaultId]:["*"]},behaviour:"exclude",...t.libStorageOptions??{}}}getStoreData(t){const e=t.libStoreId,{attributes:s}=this.getStoreOptions(t);return Object.entries(s).reduce((t,[s,a])=>{const r=this.persistData[s]?.[e]??{};return{...t,..."*"===a[0]?r:a.reduce((t,e)=>({...t,...void 0!==r[e]?{[e]:r[e]}:{}}),{})}},{})}async saveStoreData(e,s){const a=e.libStoreId,{attributes:r,behaviour:i}=this.getStoreOptions(e),o=new Set(Object.keys(s??{})),u=Object.entries(r).map(([e,r])=>{const u=("*"===r[0]?[...o]:r).reduce((t,e)=>o.has(e)?("exclude"===i&&o.delete(e),{...t,[e]:s?.[e]}):t,{}),c={...this.persistData?.[e]??{},[a]:u};return t(this.persistData?.[e]?.[a]??{},u)?null:(this.persistData[e]||(this.persistData[e]={}),this.persistData[e]?.[a]||(this.persistData[e][a]={}),this.persistData[e][a]=u,this.set(c,e))});await Promise.all(u)}}export{e as default};
|
|
2
2
|
//# sourceMappingURL=combined-storage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"combined-storage.js","sources":["../../src/storages/combined-storage.ts"],"sourcesContent":["import deepCompare from '../deep-compare';\nimport type { IPersistOptions, IStorage, IStorePersisted } from '../types';\n\ninterface ICombinedStorage {\n [name: string]: IStorage;\n}\n\n/**\n * Combined storage for mobx store manager\n */\nclass CombinedStorage implements IStorage {\n /**\n * @protected\n */\n protected storages: ICombinedStorage;\n\n /**\n * Restored persist storage data\n * @protected\n */\n protected persistData: Record<string, any> = {};\n\n /**\n * Default storage id\n * @protected\n */\n protected defaultId: string;\n\n /**\n * @constructor\n *\n * First storage will be used as default\n */\n constructor(storages: ICombinedStorage) {\n this.storages = storages;\n this.defaultId = Object.keys(storages)?.[0];\n }\n\n /**\n * @inheritDoc\n */\n public async get(): Promise<Record<string, any> | undefined> {\n try {\n const data = await Promise.all(\n Object.values(this.storages).map((storage) => storage.get() || {}),\n );\n\n this.persistData = Object.keys(this.storages).reduce(\n (res, key, index) => ({\n ...res,\n [key]: data[index],\n }),\n {},\n );\n\n return this.persistData;\n } catch
|
|
1
|
+
{"version":3,"file":"combined-storage.js","sources":["../../src/storages/combined-storage.ts"],"sourcesContent":["import deepCompare from '../deep-compare';\nimport type { IPersistOptions, IStorage, IStorePersisted } from '../types';\n\ninterface ICombinedStorage {\n [name: string]: IStorage;\n}\n\n/**\n * Combined storage for mobx store manager\n */\nclass CombinedStorage implements IStorage {\n /**\n * @protected\n */\n protected storages: ICombinedStorage;\n\n /**\n * Restored persist storage data\n * @protected\n */\n protected persistData: Record<string, any> = {};\n\n /**\n * Default storage id\n * @protected\n */\n protected defaultId: string;\n\n /**\n * @constructor\n *\n * First storage will be used as default\n */\n constructor(storages: ICombinedStorage) {\n this.storages = storages;\n this.defaultId = Object.keys(storages)?.[0];\n }\n\n /**\n * @inheritDoc\n */\n public async get(): Promise<Record<string, any> | undefined> {\n try {\n const data = await Promise.all(\n Object.values(this.storages).map((storage) => storage.get() || ({} as any)),\n );\n\n this.persistData = Object.keys(this.storages).reduce(\n (res, key, index) => ({\n ...res,\n [key]: data[index],\n }),\n {},\n );\n\n return this.persistData;\n } catch {\n return {};\n }\n }\n\n /**\n * @inheritDoc\n */\n public flush(): Promise<any> {\n return Promise.all(Object.values(this.storages).map((storage) => storage.flush() as any));\n }\n\n /**\n * @inheritDoc\n */\n public set(\n value: Record<string, any> | undefined,\n storageId?: string,\n ): ReturnType<IStorage['set']> {\n const storage = this.storages[storageId ?? this.defaultId];\n\n if (!storage) {\n return;\n }\n\n return storage.set(value);\n }\n\n /**\n * Return store storage options\n */\n protected getStoreOptions(store: IStorePersisted): IPersistOptions {\n return {\n attributes: {\n [this.defaultId]: ['*'],\n },\n behaviour: 'exclude',\n ...(store.libStorageOptions ?? {}),\n };\n }\n\n /**\n * Return store persist data\n */\n public getStoreData(store: IStorePersisted): Record<string, any> | undefined {\n const storeId = store.libStoreId!;\n const { attributes } = this.getStoreOptions(store);\n\n return Object.entries(attributes!).reduce((res, [storageId, attr]) => {\n const storageData = this.persistData[storageId]?.[storeId] ?? {};\n const allowedData =\n attr[0] === '*'\n ? storageData\n : attr.reduce(\n (r, attrName) => ({\n ...r,\n ...(storageData[attrName] !== undefined\n ? { [attrName]: storageData[attrName] }\n : {}),\n }),\n {},\n );\n\n return {\n ...res,\n ...allowedData,\n };\n }, {});\n }\n\n /**\n * Save store data in storage\n */\n public async saveStoreData(\n store: IStorePersisted,\n data: Record<string, any> | undefined,\n ): Promise<void> {\n const storeId = store.libStoreId!;\n const { attributes, behaviour } = this.getStoreOptions(store);\n const dataKeys = new Set(Object.keys(data ?? {}));\n\n const dataByStorages = Object.entries(attributes!).map(([storageId, attr]) => {\n const storeData = (attr[0] === '*' ? [...dataKeys] : attr).reduce((r, attrName) => {\n if (!dataKeys.has(attrName)) {\n return r;\n }\n\n if (behaviour === 'exclude') {\n dataKeys.delete(attrName);\n }\n\n return {\n ...r,\n [attrName]: data?.[attrName],\n };\n }, {});\n\n const newData = {\n ...(this.persistData?.[storageId] ?? {}),\n [storeId]: storeData,\n } as Record<string, any>;\n\n // skip updating if nothing changed\n if (deepCompare(this.persistData?.[storageId]?.[storeId] ?? {}, storeData)) {\n return null;\n }\n\n if (!this.persistData[storageId]) {\n this.persistData[storageId] = {};\n }\n\n if (!this.persistData[storageId]?.[storeId]) {\n this.persistData[storageId][storeId] = {};\n }\n\n this.persistData[storageId][storeId] = storeData;\n\n return this.set(newData, storageId);\n });\n\n await Promise.all(dataByStorages as Promise<any>[]);\n }\n}\n\nexport default CombinedStorage;\n"],"names":["CombinedStorage","storages","persistData","defaultId","constructor","this","Object","keys","get","data","Promise","all","values","map","storage","reduce","res","key","index","flush","set","value","storageId","getStoreOptions","store","attributes","behaviour","libStorageOptions","getStoreData","storeId","libStoreId","entries","attr","storageData","r","attrName","undefined","saveStoreData","dataKeys","Set","dataByStorages","storeData","has","delete","newData","deepCompare"],"mappings":"kCAUA,MAAMA,EAIMC,SAMAC,YAAmC,CAAA,EAMnCC,UAOV,WAAAC,CAAYH,GACVI,KAAKJ,SAAWA,EAChBI,KAAKF,UAAYG,OAAOC,KAAKN,KAAY,EAC3C,CAKO,SAAMO,GACX,IACE,MAAMC,QAAaC,QAAQC,IACzBL,OAAOM,OAAOP,KAAKJ,UAAUY,IAAKC,GAAYA,EAAQN,OAAU,CAAA,IAWlE,OARAH,KAAKH,YAAcI,OAAOC,KAAKF,KAAKJ,UAAUc,OAC5C,CAACC,EAAKC,EAAKC,KAAK,IACXF,EACHC,CAACA,GAAMR,EAAKS,KAEd,CAAA,GAGKb,KAAKH,WACb,CAAC,MACA,MAAO,CAAA,CACR,CACH,CAKO,KAAAiB,GACL,OAAOT,QAAQC,IAAIL,OAAOM,OAAOP,KAAKJ,UAAUY,IAAKC,GAAYA,EAAQK,SAC3E,CAKO,GAAAC,CACLC,EACAC,GAEA,MAAMR,EAAUT,KAAKJ,SAASqB,GAAajB,KAAKF,WAEhD,GAAKW,EAIL,OAAOA,EAAQM,IAAIC,EACrB,CAKU,eAAAE,CAAgBC,GACxB,MAAO,CACLC,WAAY,CACV,CAACpB,KAAKF,WAAY,CAAC,MAErBuB,UAAW,aACPF,EAAMG,mBAAqB,GAEnC,CAKO,YAAAC,CAAaJ,GAClB,MAAMK,EAAUL,EAAMM,YAChBL,WAAEA,GAAepB,KAAKkB,gBAAgBC,GAE5C,OAAOlB,OAAOyB,QAAQN,GAAaV,OAAO,CAACC,GAAMM,EAAWU,MAC1D,MAAMC,EAAc5B,KAAKH,YAAYoB,KAAaO,IAAY,CAAA,EAc9D,MAAO,IACFb,KAbS,MAAZgB,EAAK,GACDC,EACAD,EAAKjB,OACH,CAACmB,EAAGC,KAAQ,IACPD,UAC2BE,IAA1BH,EAAYE,GACZ,CAAEA,CAACA,GAAWF,EAAYE,IAC1B,KAEN,CAAA,KAOP,CAAA,EACL,CAKO,mBAAME,CACXb,EACAf,GAEA,MAAMoB,EAAUL,EAAMM,YAChBL,WAAEA,EAAUC,UAAEA,GAAcrB,KAAKkB,gBAAgBC,GACjDc,EAAW,IAAIC,IAAIjC,OAAOC,KAAKE,GAAQ,CAAA,IAEvC+B,EAAiBlC,OAAOyB,QAAQN,GAAaZ,IAAI,EAAES,EAAWU,MAClE,MAAMS,GAAyB,MAAZT,EAAK,GAAa,IAAIM,GAAYN,GAAMjB,OAAO,CAACmB,EAAGC,IAC/DG,EAASI,IAAIP,IAIA,YAAdT,GACFY,EAASK,OAAOR,GAGX,IACFD,EACHC,CAACA,GAAW1B,IAAO0B,KATZD,EAWR,CAAA,GAEGU,EAAU,IACVvC,KAAKH,cAAcoB,IAAc,CAAA,EACrCO,CAACA,GAAUY,GAIb,OAAII,EAAYxC,KAAKH,cAAcoB,KAAaO,IAAY,GAAIY,GACvD,MAGJpC,KAAKH,YAAYoB,KACpBjB,KAAKH,YAAYoB,GAAa,CAAA,GAG3BjB,KAAKH,YAAYoB,KAAaO,KACjCxB,KAAKH,YAAYoB,GAAWO,GAAW,CAAA,GAGzCxB,KAAKH,YAAYoB,GAAWO,GAAWY,EAEhCpC,KAAKe,IAAIwB,EAAStB,YAGrBZ,QAAQC,IAAI6B,EACpB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
class t{globalKey;storage;cookieAttr;constructor({storage:t,cookieAttr:e,globalKey:s}){this.storage=t,this.cookieAttr=e??{},this.globalKey=s??"stores"}get(){try{return JSON.parse(this.storage.get(this.globalKey)||"{}")}catch
|
|
1
|
+
class t{globalKey;storage;cookieAttr;constructor({storage:t,cookieAttr:e,globalKey:s}){this.storage=t,this.cookieAttr=e??{},this.globalKey=s??"stores"}get(){try{return JSON.parse(this.storage.get(this.globalKey)||"{}")}catch{return{}}}flush(){return this.storage.remove(this.globalKey,this.cookieAttr)}set(t){return this.storage.set(this.globalKey,JSON.stringify(t||"{}"),this.cookieAttr)}}export{t as default};
|
|
2
2
|
//# sourceMappingURL=cookie-storage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cookie-storage.js","sources":["../../src/storages/cookie-storage.ts"],"sourcesContent":["import type { IStorage } from '../types';\n\ninterface ICookiesStorageAttributes {\n expires?: number | Date | undefined;\n path?: string | undefined;\n domain?: string | undefined;\n secure?: boolean | undefined;\n sameSite?: 'strict' | 'Strict' | 'lax' | 'Lax' | 'none' | 'None' | undefined;\n [property: string]: any;\n}\n\ninterface ICookieStorage {\n get: (key: string) => string | null | undefined;\n set: (key: string, value: string, options: ICookiesStorageAttributes) => any;\n remove: (key: string, options: ICookiesStorageAttributes) => any;\n}\n\ninterface ICookiesStorageOptions {\n storage: ICookieStorage;\n globalKey?: string;\n cookieAttr?: ICookiesStorageAttributes;\n}\n\n/**\n * Cookie storage for mobx store manager\n */\nclass CookieStorage implements IStorage {\n /**\n * Cookie storage key\n */\n protected globalKey: string;\n\n /**\n * @protected\n */\n protected storage: ICookieStorage;\n\n /**\n * Cookie attributes\n */\n protected cookieAttr: ICookiesStorageAttributes;\n\n /**\n * @constructor\n */\n constructor({ storage, cookieAttr, globalKey }: ICookiesStorageOptions) {\n this.storage = storage;\n this.cookieAttr = cookieAttr ?? {};\n this.globalKey = globalKey ?? 'stores';\n }\n\n /**\n * @inheritDoc\n */\n public get(): Record<string, any> | Promise<Record<string, any> | undefined> {\n try {\n return JSON.parse(this.storage.get(this.globalKey) || '{}') as Record<string, any>;\n } catch
|
|
1
|
+
{"version":3,"file":"cookie-storage.js","sources":["../../src/storages/cookie-storage.ts"],"sourcesContent":["import type { IStorage } from '../types';\n\ninterface ICookiesStorageAttributes {\n expires?: number | Date | undefined;\n path?: string | undefined;\n domain?: string | undefined;\n secure?: boolean | undefined;\n sameSite?: 'strict' | 'Strict' | 'lax' | 'Lax' | 'none' | 'None' | undefined;\n [property: string]: any;\n}\n\ninterface ICookieStorage {\n get: (key: string) => string | null | undefined;\n set: (key: string, value: string, options: ICookiesStorageAttributes) => any;\n remove: (key: string, options: ICookiesStorageAttributes) => any;\n}\n\ninterface ICookiesStorageOptions {\n storage: ICookieStorage;\n globalKey?: string;\n cookieAttr?: ICookiesStorageAttributes;\n}\n\n/**\n * Cookie storage for mobx store manager\n */\nclass CookieStorage implements IStorage {\n /**\n * Cookie storage key\n */\n protected globalKey: string;\n\n /**\n * @protected\n */\n protected storage: ICookieStorage;\n\n /**\n * Cookie attributes\n */\n protected cookieAttr: ICookiesStorageAttributes;\n\n /**\n * @constructor\n */\n constructor({ storage, cookieAttr, globalKey }: ICookiesStorageOptions) {\n this.storage = storage;\n this.cookieAttr = cookieAttr ?? {};\n this.globalKey = globalKey ?? 'stores';\n }\n\n /**\n * @inheritDoc\n */\n public get(): Record<string, any> | Promise<Record<string, any> | undefined> {\n try {\n return JSON.parse(this.storage.get(this.globalKey) || '{}') as Record<string, any>;\n } catch {\n return {};\n }\n }\n\n /**\n * @inheritDoc\n */\n public flush(): void | Promise<any> {\n return this.storage.remove(this.globalKey, this.cookieAttr);\n }\n\n /**\n * @inheritDoc\n */\n public set(value: Record<string, any> | undefined): void {\n return this.storage.set(this.globalKey, JSON.stringify(value || '{}'), this.cookieAttr);\n }\n}\n\nexport default CookieStorage;\n"],"names":["CookieStorage","globalKey","storage","cookieAttr","constructor","this","get","JSON","parse","flush","remove","set","value","stringify"],"mappings":"AA0BA,MAAMA,EAIMC,UAKAC,QAKAC,WAKV,WAAAC,EAAYF,QAAEA,EAAOC,WAAEA,EAAUF,UAAEA,IACjCI,KAAKH,QAAUA,EACfG,KAAKF,WAAaA,GAAc,CAAA,EAChCE,KAAKJ,UAAYA,GAAa,QAChC,CAKO,GAAAK,GACL,IACE,OAAOC,KAAKC,MAAMH,KAAKH,QAAQI,IAAID,KAAKJ,YAAc,KACvD,CAAC,MACA,MAAO,CAAA,CACR,CACH,CAKO,KAAAQ,GACL,OAAOJ,KAAKH,QAAQQ,OAAOL,KAAKJ,UAAWI,KAAKF,WAClD,CAKO,GAAAQ,CAAIC,GACT,OAAOP,KAAKH,QAAQS,IAAIN,KAAKJ,UAAWM,KAAKM,UAAUD,GAAS,MAAOP,KAAKF,WAC9E"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
class t{globalKey;storage;constructor({storage:t,globalKey:e}={}){this.storage=t??localStorage,this.globalKey=e??"stores"}get(){try{return JSON.parse(this.storage.getItem(this.globalKey)||"{}")}catch
|
|
1
|
+
class t{globalKey;storage;constructor({storage:t,globalKey:e}={}){this.storage=t??localStorage,this.globalKey=e??"stores"}get(){try{return JSON.parse(this.storage.getItem(this.globalKey)||"{}")}catch{return{}}}flush(){return this.storage.removeItem(this.globalKey)}set(t){return this.storage.setItem(this.globalKey,JSON.stringify(t||"{}"))}}export{t as default};
|
|
2
2
|
//# sourceMappingURL=local-storage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-storage.js","sources":["../../src/storages/local-storage.ts"],"sourcesContent":["import type { IStorage } from '../types';\n\nexport interface ILocalStorageOptions {\n globalKey?: string;\n storage?: Storage;\n}\n\n/**\n * Local storage for mobx store manager\n */\nclass LocalStorage implements IStorage {\n /**\n * Local storage key\n */\n protected globalKey: string;\n\n /**\n * @protected\n */\n protected storage: Storage;\n\n /**\n * @constructor\n */\n constructor({ storage, globalKey }: ILocalStorageOptions = {}) {\n this.storage = storage ?? localStorage;\n this.globalKey = globalKey ?? 'stores';\n }\n\n /**\n * @inheritDoc\n */\n get(): Record<string, any> | Promise<Record<string, any> | undefined> {\n try {\n return JSON.parse(this.storage.getItem(this.globalKey) || '{}') as Record<string, any>;\n } catch
|
|
1
|
+
{"version":3,"file":"local-storage.js","sources":["../../src/storages/local-storage.ts"],"sourcesContent":["import type { IStorage } from '../types';\n\nexport interface ILocalStorageOptions {\n globalKey?: string;\n storage?: Storage;\n}\n\n/**\n * Local storage for mobx store manager\n */\nclass LocalStorage implements IStorage {\n /**\n * Local storage key\n */\n protected globalKey: string;\n\n /**\n * @protected\n */\n protected storage: Storage;\n\n /**\n * @constructor\n */\n constructor({ storage, globalKey }: ILocalStorageOptions = {}) {\n this.storage = storage ?? localStorage;\n this.globalKey = globalKey ?? 'stores';\n }\n\n /**\n * @inheritDoc\n */\n get(): Record<string, any> | Promise<Record<string, any> | undefined> {\n try {\n return JSON.parse(this.storage.getItem(this.globalKey) || '{}') as Record<string, any>;\n } catch {\n return {};\n }\n }\n\n /**\n * @inheritDoc\n */\n flush(): void | Promise<any> {\n return this.storage.removeItem(this.globalKey);\n }\n\n /**\n * @inheritDoc\n */\n set(value: Record<string, any> | undefined): void {\n return this.storage.setItem(this.globalKey, JSON.stringify(value || '{}'));\n }\n}\n\nexport default LocalStorage;\n"],"names":["LocalStorage","globalKey","storage","constructor","this","localStorage","get","JSON","parse","getItem","flush","removeItem","set","value","setItem","stringify"],"mappings":"AAUA,MAAMA,EAIMC,UAKAC,QAKV,WAAAC,EAAYD,QAAEA,EAAOD,UAAEA,GAAoC,CAAA,GACzDG,KAAKF,QAAUA,GAAWG,aAC1BD,KAAKH,UAAYA,GAAa,QAChC,CAKA,GAAAK,GACE,IACE,OAAOC,KAAKC,MAAMJ,KAAKF,QAAQO,QAAQL,KAAKH,YAAc,KAC3D,CAAC,MACA,MAAO,CAAA,CACR,CACH,CAKA,KAAAS,GACE,OAAON,KAAKF,QAAQS,WAAWP,KAAKH,UACtC,CAKA,GAAAW,CAAIC,GACF,OAAOT,KAAKF,QAAQY,QAAQV,KAAKH,UAAWM,KAAKQ,UAAUF,GAAS,MACtE"}
|
package/suspense-query.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{makeExported as r}from"./make-exported.js";class s{promise;subqueries=new Map;store;params;constructor(s,{fieldName:e="sR",errorFields:t=["name","message"]}={}){this.store=s,this.params={fieldName:e,errorFields:t};const i=s.init?.bind(s);s.init=()=>
|
|
1
|
+
import{makeExported as r}from"./make-exported.js";class s{promise;subqueries=new Map;store;params;constructor(s,{fieldName:e="sR",errorFields:t=["name","message"]}={}){this.store=s,this.params={fieldName:e,errorFields:t};const i=s.init?.bind(s);s.init=()=>(this.throwError(),i?.()),r(s,{[e]:"simple"})}errorJson(r){r.toJSON=()=>this.params.errorFields.reduce((s,e)=>({...s,[e]:r?.[e]}),{})}jsonToError(r,s){return this.params.errorFields.forEach(e=>{r[e]=s?.[e]}),r}throwError(){const r=this.store[this.params.fieldName];if(r?.error)throw this.jsonToError(new Error(r?.error?.message??r?.error?.name),r?.error)}isComplete(r){const s=this.store[this.params.fieldName];return s?.error&&this.throwError(),!0===s?.done&&s.hash===r}query=(r,e={})=>{const{hash:t=""}=e,{fieldName:i}=this.params;if(!this.isComplete(t))return this.store[i]?.hash!==t&&(this.store[i]={hash:t,done:!1},this.promise=void 0),this.promise||(this.promise=r(),this.promise.then(()=>{this.store[i]={hash:t,done:!0}},r=>{this.errorJson(r),this.store[i]={error:r}})),s.run(this.promise)};subquery=(r,e)=>{const{id:t,hash:i}=e,o=this.subqueries.get(t);if(!o)return void this.subqueries.set(t,{hash:i});if(o?.hash===i)return s.run(o?.promise);const h=r();return this.subqueries.set(t,{hash:i,promise:h}),s.run(h)};static run=r=>{if(r){switch(r.status){case"fulfilled":return r.value;case"pending":throw r;case"rejected":throw r.reason;default:r.status="pending",r.then(s=>{r.status="fulfilled",r.value=s},s=>{r.status="rejected",r.reason=s})}throw r}}}export{s as default};
|
|
2
2
|
//# sourceMappingURL=suspense-query.js.map
|
package/suspense-query.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suspense-query.js","sources":["../src/suspense-query.ts"],"sourcesContent":["import { makeExported } from './make-exported';\nimport type { TInitStore } from './types';\n\nexport interface IPromise<TReturn> extends Promise<TReturn> {\n status?: 'fulfilled' | 'pending' | 'rejected';\n value?: TReturn;\n reason?: any;\n}\n\ninterface ISuspenseQueryParams {\n fieldName?: string; // field name in target store for save suspense state\n errorFields?: string[];\n}\n\ninterface ISuspenseQueryOptions {\n hash?: unknown;\n}\n\ninterface ISuspenseSubqueryOptions {\n id: string;\n hash: unknown;\n}\n\n/**\n * Run request and cache promise\n * Sync suspense status between server and client\n */\nclass SuspenseQuery {\n /**\n * @protected\n */\n protected promise: Promise<any> | undefined;\n\n /**\n * Subqueries info\n */\n protected subqueries: Map<string, { hash: unknown; promise?: IPromise<any> }> = new Map();\n\n /**\n * Target store\n */\n protected readonly store: TInitStore;\n\n /**\n * @protected\n */\n protected readonly params: Required<ISuspenseQueryParams>;\n\n /**\n * @constructor\n */\n constructor(\n store: TInitStore,\n { fieldName = 'sR', errorFields = ['name', 'message'] }: ISuspenseQueryParams = {},\n ) {\n this.store = store;\n this.params = { fieldName, errorFields };\n\n const defaultInit = store.init?.bind(store);\n\n store.init = () => {\n this.throwError(); // throw error immediately from server side if exist\n defaultInit?.();\n };\n\n makeExported(store, { [fieldName]: 'simple' });\n }\n\n /**\n * Error to json\n */\n protected errorJson(e: any): void {\n e.toJSON = () =>\n this.params.errorFields.reduce(\n (res, name) => ({\n ...res,\n [name]: e?.[name],\n }),\n {},\n );\n }\n\n /**\n * Assign custom error fields to error\n */\n protected jsonToError(e: Error, values: Record<string, any>): Error {\n this.params.errorFields.forEach((name) => {\n e[name] = values?.[name];\n });\n\n return e;\n }\n\n /**\n * Throw suspense error\n */\n protected throwError(): void {\n const value = this.store[this.params.fieldName];\n\n // pass error to error boundary\n if (value?.error) {\n throw this.jsonToError(\n new Error((value?.error?.message ?? value?.error?.name) as string),\n value?.error as Record<string, any>,\n );\n }\n }\n\n /**\n * Detect if suspense is restored from server side:\n * - throw error if exist\n * - skip run suspense if already completed\n */\n protected isComplete(hash: unknown): boolean {\n const value = this.store[this.params.fieldName];\n\n // pass error to error boundary\n if (value?.error) {\n this.throwError();\n }\n\n return value?.done === true && value.hash === hash;\n }\n\n /**\n * Run request\n * Save request resolve status\n */\n public query = <TReturn>(\n promise: () => Promise<TReturn>,\n options: ISuspenseQueryOptions = {},\n ): TReturn | undefined => {\n const { hash = '' } = options;\n const { fieldName } = this.params;\n\n if (this.isComplete(hash)) {\n return;\n }\n\n if (this.store[fieldName]?.hash !== hash) {\n this.store[fieldName] = { hash, done: false };\n this.promise = undefined;\n }\n\n if (!this.promise) {\n this.promise = promise();\n\n this.promise.then(\n () => {\n this.store[fieldName] = { hash, done: true };\n },\n (e) => {\n this.errorJson(e);\n\n this.store[fieldName] = { error: e };\n },\n );\n }\n\n return SuspenseQuery.run<TReturn>(this.promise);\n };\n\n /**\n * Run subquery\n * Re-fetch data from query by hash changes in children components\n * NOTE: only client side\n */\n public subquery = <TReturn>(\n promise: () => Promise<TReturn>,\n options: ISuspenseSubqueryOptions,\n ): TReturn | undefined => {\n const { id, hash } = options;\n const subquery = this.subqueries.get(id);\n\n // skip first run\n if (!subquery) {\n this.subqueries.set(id, { hash });\n\n return undefined;\n }\n\n if (subquery?.hash === hash) {\n return SuspenseQuery.run<TReturn>(subquery?.promise);\n }\n\n const newQuery = promise();\n\n this.subqueries.set(id, { hash, promise: newQuery });\n\n return SuspenseQuery.run<TReturn>(newQuery);\n };\n\n /**\n * Change status of promise.\n * Throw promise to react suspense\n */\n public static run = <TReturn>(promise: IPromise<TReturn> | undefined): TReturn | undefined => {\n if (!promise) {\n return;\n }\n\n switch (promise.status) {\n case 'fulfilled':\n return promise.value;\n\n case 'pending':\n throw promise;\n\n case 'rejected':\n throw promise.reason;\n\n default:\n promise.status = 'pending';\n\n promise.then(\n (result) => {\n promise.status = 'fulfilled';\n promise.value = result;\n },\n (reason) => {\n promise.status = 'rejected';\n promise.reason = reason;\n },\n );\n }\n\n throw promise;\n };\n}\n\nexport default SuspenseQuery;\n"],"names":["SuspenseQuery","promise","subqueries","Map","store","params","constructor","fieldName","errorFields","this","defaultInit","init","bind","throwError","makeExported","errorJson","e","toJSON","reduce","res","name","jsonToError","values","forEach","value","error","Error","message","isComplete","hash","done","query","options","undefined","then","run","subquery","id","get","set","newQuery","static","status","reason","result"],"mappings":"kDA2BA,MAAMA,EAIMC,QAKAC,WAAsE,IAAIC,IAKjEC,MAKAC,OAKnB,WAAAC,CACEF,GACAG,UAAEA,EAAY,KAAIC,YAAEA,EAAc,CAAC,OAAQ,YAAqC,IAEhFC,KAAKL,MAAQA,EACbK,KAAKJ,OAAS,CAAEE,YAAWC,eAE3B,MAAME,EAAcN,EAAMO,MAAMC,KAAKR,GAErCA,EAAMO,KAAO,KACXF,KAAKI,
|
|
1
|
+
{"version":3,"file":"suspense-query.js","sources":["../src/suspense-query.ts"],"sourcesContent":["import { makeExported } from './make-exported';\nimport type { TInitStore } from './types';\n\nexport interface IPromise<TReturn> extends Promise<TReturn> {\n status?: 'fulfilled' | 'pending' | 'rejected';\n value?: TReturn;\n reason?: any;\n}\n\ninterface ISuspenseQueryParams {\n fieldName?: string; // field name in target store for save suspense state\n errorFields?: string[];\n}\n\ninterface ISuspenseQueryOptions {\n hash?: unknown;\n}\n\ninterface ISuspenseSubqueryOptions {\n id: string;\n hash: unknown;\n}\n\n/**\n * Run request and cache promise\n * Sync suspense status between server and client\n */\nclass SuspenseQuery {\n /**\n * @protected\n */\n protected promise: Promise<any> | undefined;\n\n /**\n * Subqueries info\n */\n protected subqueries: Map<string, { hash: unknown; promise?: IPromise<any> }> = new Map();\n\n /**\n * Target store\n */\n protected readonly store: TInitStore;\n\n /**\n * @protected\n */\n protected readonly params: Required<ISuspenseQueryParams>;\n\n /**\n * @constructor\n */\n constructor(\n store: TInitStore,\n { fieldName = 'sR', errorFields = ['name', 'message'] }: ISuspenseQueryParams = {},\n ) {\n this.store = store;\n this.params = { fieldName, errorFields };\n\n const defaultInit = store.init?.bind(store);\n\n store.init = () => {\n this.throwError(); // throw error immediately from server side if exist\n\n return defaultInit?.();\n };\n\n makeExported(store, { [fieldName]: 'simple' });\n }\n\n /**\n * Error to json\n */\n protected errorJson(e: any): void {\n e.toJSON = () =>\n this.params.errorFields.reduce(\n (res, name) => ({\n ...res,\n [name]: e?.[name],\n }),\n {},\n );\n }\n\n /**\n * Assign custom error fields to error\n */\n protected jsonToError(e: Error, values: Record<string, any>): Error {\n this.params.errorFields.forEach((name) => {\n e[name] = values?.[name];\n });\n\n return e;\n }\n\n /**\n * Throw suspense error\n */\n protected throwError(): void {\n const value = this.store[this.params.fieldName];\n\n // pass error to error boundary\n if (value?.error) {\n throw this.jsonToError(\n new Error((value?.error?.message ?? value?.error?.name) as string),\n value?.error as Record<string, any>,\n );\n }\n }\n\n /**\n * Detect if suspense is restored from server side:\n * - throw error if exist\n * - skip run suspense if already completed\n */\n protected isComplete(hash: unknown): boolean {\n const value = this.store[this.params.fieldName];\n\n // pass error to error boundary\n if (value?.error) {\n this.throwError();\n }\n\n return value?.done === true && value.hash === hash;\n }\n\n /**\n * Run request\n * Save request resolve status\n */\n public query = <TReturn>(\n promise: () => Promise<TReturn>,\n options: ISuspenseQueryOptions = {},\n ): TReturn | undefined => {\n const { hash = '' } = options;\n const { fieldName } = this.params;\n\n if (this.isComplete(hash)) {\n return;\n }\n\n if (this.store[fieldName]?.hash !== hash) {\n this.store[fieldName] = { hash, done: false };\n this.promise = undefined;\n }\n\n if (!this.promise) {\n this.promise = promise();\n\n this.promise.then(\n () => {\n this.store[fieldName] = { hash, done: true };\n },\n (e) => {\n this.errorJson(e);\n\n this.store[fieldName] = { error: e };\n },\n );\n }\n\n return SuspenseQuery.run<TReturn>(this.promise);\n };\n\n /**\n * Run subquery\n * Re-fetch data from query by hash changes in children components\n * NOTE: only client side\n */\n public subquery = <TReturn>(\n promise: () => Promise<TReturn>,\n options: ISuspenseSubqueryOptions,\n ): TReturn | undefined => {\n const { id, hash } = options;\n const subquery = this.subqueries.get(id);\n\n // skip first run\n if (!subquery) {\n this.subqueries.set(id, { hash });\n\n return undefined;\n }\n\n if (subquery?.hash === hash) {\n return SuspenseQuery.run<TReturn>(subquery?.promise);\n }\n\n const newQuery = promise();\n\n this.subqueries.set(id, { hash, promise: newQuery });\n\n return SuspenseQuery.run<TReturn>(newQuery);\n };\n\n /**\n * Change status of promise.\n * Throw promise to react suspense\n */\n public static run = <TReturn>(promise: IPromise<TReturn> | undefined): TReturn | undefined => {\n if (!promise) {\n return;\n }\n\n switch (promise.status) {\n case 'fulfilled':\n return promise.value;\n\n case 'pending':\n throw promise;\n\n case 'rejected':\n throw promise.reason;\n\n default:\n promise.status = 'pending';\n\n promise.then(\n (result) => {\n promise.status = 'fulfilled';\n promise.value = result;\n },\n (reason) => {\n promise.status = 'rejected';\n promise.reason = reason;\n },\n );\n }\n\n throw promise;\n };\n}\n\nexport default SuspenseQuery;\n"],"names":["SuspenseQuery","promise","subqueries","Map","store","params","constructor","fieldName","errorFields","this","defaultInit","init","bind","throwError","makeExported","errorJson","e","toJSON","reduce","res","name","jsonToError","values","forEach","value","error","Error","message","isComplete","hash","done","query","options","undefined","then","run","subquery","id","get","set","newQuery","static","status","reason","result"],"mappings":"kDA2BA,MAAMA,EAIMC,QAKAC,WAAsE,IAAIC,IAKjEC,MAKAC,OAKnB,WAAAC,CACEF,GACAG,UAAEA,EAAY,KAAIC,YAAEA,EAAc,CAAC,OAAQ,YAAqC,IAEhFC,KAAKL,MAAQA,EACbK,KAAKJ,OAAS,CAAEE,YAAWC,eAE3B,MAAME,EAAcN,EAAMO,MAAMC,KAAKR,GAErCA,EAAMO,KAAO,KACXF,KAAKI,aAEEH,OAGTI,EAAaV,EAAO,CAAEG,CAACA,GAAY,UACrC,CAKU,SAAAQ,CAAUC,GAClBA,EAAEC,OAAS,IACTR,KAAKJ,OAAOG,YAAYU,OACtB,CAACC,EAAKC,KAAI,IACLD,EACHC,CAACA,GAAOJ,IAAII,KAEd,CAAA,EAEN,CAKU,WAAAC,CAAYL,EAAUM,GAK9B,OAJAb,KAAKJ,OAAOG,YAAYe,QAASH,IAC/BJ,EAAEI,GAAQE,IAASF,KAGdJ,CACT,CAKU,UAAAH,GACR,MAAMW,EAAQf,KAAKL,MAAMK,KAAKJ,OAAOE,WAGrC,GAAIiB,GAAOC,MACT,MAAMhB,KAAKY,YACT,IAAIK,MAAOF,GAAOC,OAAOE,SAAWH,GAAOC,OAAOL,MAClDI,GAAOC,MAGb,CAOU,UAAAG,CAAWC,GACnB,MAAML,EAAQf,KAAKL,MAAMK,KAAKJ,OAAOE,WAOrC,OAJIiB,GAAOC,OACThB,KAAKI,cAGgB,IAAhBW,GAAOM,MAAiBN,EAAMK,OAASA,CAChD,CAMOE,MAAQ,CACb9B,EACA+B,EAAiC,MAEjC,MAAMH,KAAEA,EAAO,IAAOG,GAChBzB,UAAEA,GAAcE,KAAKJ,OAE3B,IAAII,KAAKmB,WAAWC,GAwBpB,OApBIpB,KAAKL,MAAMG,IAAYsB,OAASA,IAClCpB,KAAKL,MAAMG,GAAa,CAAEsB,OAAMC,MAAM,GACtCrB,KAAKR,aAAUgC,GAGZxB,KAAKR,UACRQ,KAAKR,QAAUA,IAEfQ,KAAKR,QAAQiC,KACX,KACEzB,KAAKL,MAAMG,GAAa,CAAEsB,OAAMC,MAAM,IAEvCd,IACCP,KAAKM,UAAUC,GAEfP,KAAKL,MAAMG,GAAa,CAAEkB,MAAOT,MAKhChB,EAAcmC,IAAa1B,KAAKR,UAQlCmC,SAAW,CAChBnC,EACA+B,KAEA,MAAMK,GAAEA,EAAER,KAAEA,GAASG,EACfI,EAAW3B,KAAKP,WAAWoC,IAAID,GAGrC,IAAKD,EAGH,YAFA3B,KAAKP,WAAWqC,IAAIF,EAAI,CAAER,SAK5B,GAAIO,GAAUP,OAASA,EACrB,OAAO7B,EAAcmC,IAAaC,GAAUnC,SAG9C,MAAMuC,EAAWvC,IAIjB,OAFAQ,KAAKP,WAAWqC,IAAIF,EAAI,CAAER,OAAM5B,QAASuC,IAElCxC,EAAcmC,IAAaK,IAO7BC,WAAuBxC,IAC5B,GAAKA,EAAL,CAIA,OAAQA,EAAQyC,QACd,IAAK,YACH,OAAOzC,EAAQuB,MAEjB,IAAK,UACH,MAAMvB,EAER,IAAK,WACH,MAAMA,EAAQ0C,OAEhB,QACE1C,EAAQyC,OAAS,UAEjBzC,EAAQiC,KACLU,IACC3C,EAAQyC,OAAS,YACjBzC,EAAQuB,MAAQoB,GAEjBD,IACC1C,EAAQyC,OAAS,WACjBzC,EAAQ0C,OAASA,IAKzB,MAAM1C,CA3BL"}
|
package/types.d.ts
CHANGED
|
@@ -19,7 +19,9 @@ interface IConstructorParams<TProps = any> {
|
|
|
19
19
|
initState?: Record<string, any>;
|
|
20
20
|
}
|
|
21
21
|
interface IStoreLifecycle {
|
|
22
|
+
init?: () => void | (() => void);
|
|
22
23
|
onDestroy?: () => void;
|
|
24
|
+
onComponentPropsUpdate?: (props: Record<string, any>) => void;
|
|
23
25
|
}
|
|
24
26
|
interface IStore extends IStoreLifecycle {
|
|
25
27
|
libStoreId?: string;
|
|
@@ -30,9 +32,12 @@ interface IStore extends IStoreLifecycle {
|
|
|
30
32
|
libStoreStatus?: StoreStatus;
|
|
31
33
|
libDestroyTimer?: ReturnType<typeof setTimeout>;
|
|
32
34
|
isGlobal?: boolean;
|
|
33
|
-
init?: () => void;
|
|
34
35
|
toJSON?: () => Record<string, any>;
|
|
35
36
|
}
|
|
37
|
+
interface IRelativeStore extends IStore {
|
|
38
|
+
}
|
|
39
|
+
interface IGlobalStore extends IStore {
|
|
40
|
+
}
|
|
36
41
|
interface IStorePersisted extends IStore {
|
|
37
42
|
libStorageOptions?: IPersistOptions;
|
|
38
43
|
addOnChangeListener?: (store: IStorePersisted, manager: Manager) => (() => void) | undefined;
|
|
@@ -84,7 +89,7 @@ interface IManagerOptions {
|
|
|
84
89
|
*/
|
|
85
90
|
failedCreationStrategy?: 'none' | 'dummy' | 'empty';
|
|
86
91
|
}
|
|
87
|
-
type TAnyStore = IStore | IStorePersisted;
|
|
92
|
+
type TAnyStore = IStore | IRelativeStore | IGlobalStore | IStorePersisted;
|
|
88
93
|
type TStores = {
|
|
89
94
|
[storeKey: string]: TAnyStore;
|
|
90
95
|
};
|
|
@@ -139,4 +144,4 @@ interface IPersistOptions {
|
|
|
139
144
|
};
|
|
140
145
|
isNotExported?: boolean;
|
|
141
146
|
}
|
|
142
|
-
export { IWindowManager, IConstructorParams, IStoreLifecycle, IStore, IStorePersisted, TInitStore, IConstructableStore, IStoreConfig, TStoreDefinition, TMapStores, IManagerParams, TWakeup, IStorage, IManagerOptions, TAnyStore, TStores, ClassReturnType, StoresType, IStoreParams, IWithStoreOptions, IMobxManagerEvents, IGroupedStores, IPersistOptions };
|
|
147
|
+
export { IWindowManager, IConstructorParams, IStoreLifecycle, IStore, IRelativeStore, IGlobalStore, IStorePersisted, TInitStore, IConstructableStore, IStoreConfig, TStoreDefinition, TMapStores, IManagerParams, TWakeup, IStorage, IManagerOptions, TAnyStore, TStores, ClassReturnType, StoresType, IStoreParams, IWithStoreOptions, IMobxManagerEvents, IGroupedStores, IPersistOptions };
|
package/with-stores.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{useConsistentSuspense as e,useId as t}from"@lomray/consistent-suspense";import o from"hoist-non-react-statics";import{observer as r}from"mobx-react-lite";import s,{useState as a,useEffect as
|
|
1
|
+
import{useConsistentSuspense as e,useId as t}from"@lomray/consistent-suspense";import o from"hoist-non-react-statics";import{observer as r}from"mobx-react-lite";import s,{useState as a,useRef as n,useEffect as c}from"react";import{useStoreManager as m,useStoreManagerParent as l,StoreManagerParentProvider as i}from"./context.js";const u=(u,p,{customContextId:S}={})=>{const b=r(u),d=S||u.libStoreContextId,f=u.displayName||u.name,h=o=>{const r=m(),u=l(),{suspenseId:S}=e(),h=t(),[{contextId:x,hasFailure:I,touchableStores:v,componentStores:y,relativeStores:j,mountStores:C}]=a(()=>{const e=d||h,t=r.createStores(Object.entries(p),u,e,S,f,o),{globalStores:s,relativeStores:a,parentStores:n,hasCreationFailure:c}=t,m={...a,...s};return{contextId:e,hasFailure:c,touchableStores:m,componentStores:{...m,...n},relativeStores:a,mountStores:()=>r.mountStores(e,t)}}),E=n(!1);return c(C,[C]),c(()=>{E.current?Object.values(j).forEach(e=>{e.onComponentPropsUpdate?.(o)}):E.current=!0},[o,j]),s.createElement(i,{parentId:x,touchableStores:v},!I&&s.createElement(b,{...o,...y}))};return o(h,u),h.displayName=`Mobx(${f})`,Object.defineProperty(h,"name",{value:h.displayName,writable:!1,enumerable:!1})};export{u as default};
|
|
2
2
|
//# sourceMappingURL=with-stores.js.map
|