mobx-view-model
Version:
⚡ Clean MVVM for React + MobX | Powerful ViewModels made simple ⚡
1 lines • 70.2 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../src/utils/generate-vm-id.ts","../src/config/utils/merge-vm-configs.ts","../src/config/global-config.ts","../src/config/utils/apply-observable.ts","../src/utils/typeguards.ts","../src/view-model/view-model.base.ts","../src/view-model/view-model.store.base.ts","../src/react/contexts/active-view-context.ts","../src/react/contexts/view-models-context.ts","../src/react/components/active-view-model-provider.tsx","../src/react/lib/hooks/use-isomorphic-layout-effect.ts","../src/react/lib/hooks/use-value.ts","../src/react/hooks/use-create-view-model.ts","../src/react/hooks/use-view-model.ts","../src/react/components/only-view-model.tsx","../src/react/components/view-models-provider.tsx","../src/react/hoc/with-view-model.tsx","../src/react/hoc/with-lazy-view-model.tsx"],"sourcesContent":["import { createCounter } from 'yummies/complex';\nimport type { AnyObject } from 'yummies/types';\nimport type { GenerateViewModelIdFn } from '../config/index.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst staticCounter = createCounter((counter) => counter.toString(16));\n\nexport const generateVmId: GenerateViewModelIdFn = (ctx: AnyObject) => {\n if (!ctx.generateId) {\n const staticId = staticCounter();\n const counter = createCounter((counter) =>\n counter.toString().padStart(5, '0'),\n );\n\n ctx.generateId = () =>\n `${staticId}_${counter().toString().padStart(5, '0')}`;\n }\n\n if (process.env.NODE_ENV === 'production') {\n return ctx.generateId();\n } else {\n const viewModelName = ctx.VM?.name ?? '';\n\n if (viewModelName) {\n return `${viewModelName}_${ctx.generateId()}`;\n } else {\n return ctx.generateId();\n }\n }\n};\n","import type { Maybe } from 'yummies/types';\n\nimport { viewModelsConfig as globalConfig } from '../global-config.js';\nimport type { ViewModelsConfig, ViewModelsRawConfig } from '../types.js';\n\n/**\n * [**Documentation**](https://js2me.github.io/mobx-view-model/api/view-models/view-models-config)\n */\nexport const mergeVMConfigs = (...configs: Maybe<ViewModelsRawConfig>[]) => {\n const result: ViewModelsConfig = {\n ...globalConfig,\n startViewTransitions: structuredClone(globalConfig.startViewTransitions),\n observable: {\n viewModels: {\n ...globalConfig.observable.viewModels,\n },\n viewModelStores: {\n ...globalConfig.observable.viewModelStores,\n },\n },\n };\n\n configs.forEach((config) => {\n if (!config) {\n return;\n }\n\n const {\n startViewTransitions,\n comparePayload,\n observable,\n generateId,\n ...otherConfigUpdates\n } = config;\n\n if (generateId) {\n result.generateId = generateId;\n }\n if (startViewTransitions) {\n const startViewTransitonsUpdate: Partial<\n ViewModelsConfig['startViewTransitions']\n > =\n typeof startViewTransitions === 'boolean'\n ? ({\n mount: startViewTransitions,\n payloadChange: startViewTransitions,\n unmount: startViewTransitions,\n } satisfies ViewModelsConfig['startViewTransitions'])\n : startViewTransitions;\n\n Object.assign(result.startViewTransitions, startViewTransitonsUpdate);\n }\n if (observable?.viewModels) {\n Object.assign(result.observable.viewModels, observable.viewModels || {});\n }\n if (observable?.viewModelStores) {\n Object.assign(\n result.observable.viewModelStores,\n observable.viewModelStores || {},\n );\n }\n\n if (comparePayload != null) {\n result.comparePayload = comparePayload;\n }\n\n Object.assign(result, otherConfigUpdates);\n });\n\n return result;\n};\n","import { createGlobalConfig, createPubSub } from 'yummies/complex';\nimport { generateVmId } from '../utils/generate-vm-id.js';\nimport type { ViewModelStore } from '../view-model/view-model.store.js';\nimport type { ViewModelsConfig } from './types.js';\nimport { mergeVMConfigs } from './utils/merge-vm-configs.js';\n\n/**\n * Global configuration options for view models\n */\nexport const viewModelsConfig = createGlobalConfig<ViewModelsConfig>(\n {\n comparePayload: false,\n payloadComputed: 'struct',\n payloadObservable: 'ref',\n wrapViewsInObserver: true,\n startViewTransitions: {\n mount: false,\n payloadChange: false,\n unmount: false,\n },\n observable: {\n viewModels: {\n useDecorators: true,\n },\n viewModelStores: {\n useDecorators: true,\n },\n },\n generateId: generateVmId,\n factory: (config) => {\n const VM = config.VM;\n return new VM({\n ...config,\n vmConfig: mergeVMConfigs(config.vmConfig),\n });\n },\n hooks: {\n storeCreate: createPubSub<[ViewModelStore]>(),\n },\n },\n Symbol.for('VIEW_MODELS_CONFIG'),\n);\n","import {\n applyObservable as applyObservableLib,\n type ObservableAnnotationsArray,\n} from 'yummies/mobx';\nimport type { AnyObject } from 'yummies/types';\n\nimport type { ViewModelObservableConfig } from '../index.js';\n\nexport const applyObservable = (\n context: AnyObject,\n annotationsArray: ObservableAnnotationsArray,\n observableConfig: ViewModelObservableConfig,\n) => {\n if (observableConfig.custom) {\n return observableConfig.custom(context, annotationsArray);\n }\n\n if (observableConfig.disableWrapping) {\n return;\n }\n\n applyObservableLib(context, annotationsArray, observableConfig.useDecorators);\n};\n","import type { AnyObject, Class, EmptyObject } from 'yummies/types';\nimport type {\n AnyViewModel,\n AnyViewModelSimple,\n ViewModel,\n ViewModelSimple,\n} from '../view-model/index.js';\n\nexport const isViewModel = <\n TPayload extends AnyObject = EmptyObject,\n ParentViewModel extends AnyViewModel | AnyViewModelSimple | null = null,\n>(\n value: AnyObject,\n): value is ViewModel<TPayload, ParentViewModel> => value.payloadChanged;\n\nexport const isViewModelClass = <\n TPayload extends AnyObject = EmptyObject,\n ParentViewModel extends AnyViewModel | AnyViewModelSimple | null = null,\n>(\n value: Function,\n): value is Class<ViewModel<TPayload, ParentViewModel>> =>\n value.prototype.payloadChanged;\n\nexport const isViewModeSimpleClass = <\n TPayload extends AnyObject = EmptyObject,\n ParentViewModel extends AnyViewModel | AnyViewModelSimple | null = null,\n>(\n value: Function,\n): value is Class<ViewModelSimple<TPayload, ParentViewModel>> =>\n !isViewModelClass(value);\n","import { action, comparer, computed, observable, runInAction } from 'mobx';\nimport { isShallowEqual } from 'yummies/data';\nimport { startViewTransitionSafety } from 'yummies/html';\nimport type { ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { AnyObject, EmptyObject, Maybe } from 'yummies/types';\nimport {\n applyObservable,\n mergeVMConfigs,\n type ViewModelsConfig,\n} from '../config/index.js';\nimport type { ViewModel } from './view-model.js';\nimport type { ViewModelStore } from './view-model.store.js';\nimport type {\n AnyViewModel,\n AnyViewModelSimple,\n PayloadCompareFn,\n ViewModelParams,\n} from './view-model.types.js';\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nconst baseAnnotations: ObservableAnnotationsArray = [\n [observable.ref, '_isMounted', '_isUnmounting'],\n [computed, 'isMounted', 'isUnmounting', 'parentViewModel'],\n [action, 'didMount', 'didUnmount', 'willUnmount', 'setPayload'],\n [action.bound, 'mount', 'unmount'],\n];\n\nexport class ViewModelBase<\n Payload extends AnyObject = EmptyObject,\n ParentViewModel extends AnyViewModel | AnyViewModelSimple | null = null,\n ComponentProps extends AnyObject = AnyObject,\n> implements ViewModel<Payload, ParentViewModel>\n{\n private abortController: AbortController;\n\n public unmountSignal: AbortSignal;\n\n id: string;\n\n private _isMounted = false;\n\n private _isUnmounting = false;\n\n private _payload: Payload;\n\n public vmConfig: ViewModelsConfig;\n\n protected isPayloadEqual?: PayloadCompareFn<Payload>;\n\n protected props: ComponentProps;\n\n constructor(\n protected vmParams: ViewModelParams<\n Payload,\n ParentViewModel,\n ComponentProps\n >,\n ) {\n this.id = vmParams.id;\n this.vmConfig = mergeVMConfigs(vmParams.vmConfig);\n this._payload = vmParams.payload;\n this.props = vmParams.props ?? ({} as ComponentProps);\n this.abortController = new AbortController();\n this.unmountSignal = this.abortController.signal;\n\n if (this.vmConfig.comparePayload === 'strict') {\n this.isPayloadEqual = comparer.structural;\n } else if (this.vmConfig.comparePayload === 'shallow') {\n this.isPayloadEqual = isShallowEqual;\n } else if (typeof this.vmConfig.comparePayload === 'function') {\n this.isPayloadEqual = this.vmConfig.comparePayload;\n }\n\n const annotations: ObservableAnnotationsArray = [...baseAnnotations];\n\n if (this.vmConfig.payloadObservable !== false) {\n annotations.push([\n observable[this.vmConfig.payloadObservable ?? 'ref'],\n '_payload',\n ]);\n }\n\n if (this.vmConfig.payloadComputed) {\n if (this.vmConfig.payloadComputed === 'struct') {\n annotations.push([computed.struct, 'payload']);\n } else {\n annotations.push([\n computed({\n equals:\n this.vmConfig.payloadComputed === true\n ? undefined\n : this.vmConfig.payloadComputed,\n }),\n 'payload',\n ]);\n }\n }\n\n applyObservable(this, annotations, this.vmConfig.observable.viewModels);\n }\n\n get payload() {\n return this._payload;\n }\n\n protected get viewModels(): ViewModelStore {\n if (process.env.NODE_ENV !== 'production' && !this.vmParams.viewModels) {\n console.error(\n `Error #3: No access to ViewModelStore.\\n` +\n 'This happened because [viewModels] param is not provided during to creating instance ViewModelBase.\\n' +\n 'More info: https://js2me.github.io/mobx-view-model/errors/3',\n );\n }\n\n return this.vmParams.viewModels!;\n }\n\n get isMounted() {\n return this._isMounted;\n }\n\n get isUnmounting() {\n return this._isUnmounting;\n }\n\n willUnmount(): void {\n this._isUnmounting = true;\n }\n\n /**\n * Empty method to be overridden\n */\n willMount(): void {\n /* Empty method to be overridden */\n }\n\n /**\n * The method is called when the view starts mounting\n */\n mount() {\n this.vmConfig.onMount?.(this);\n startViewTransitionSafety(\n () => {\n runInAction(() => {\n this._isMounted = true;\n });\n },\n {\n disabled: !this.vmConfig.startViewTransitions.mount,\n },\n );\n\n this.didMount();\n }\n\n /**\n * The method is called when the view was mounted\n */\n didMount() {\n /* Empty method to be overridden */\n }\n\n /**\n * The method is called when the view starts unmounting\n */\n unmount() {\n this.vmConfig.onUnmount?.(this);\n startViewTransitionSafety(\n () => {\n runInAction(() => {\n this._isMounted = false;\n });\n },\n {\n disabled: !this.vmConfig.startViewTransitions.unmount,\n },\n );\n\n this.didUnmount();\n }\n\n /**\n * The method is called when the view was unmounted\n */\n didUnmount() {\n this.abortController.abort();\n\n runInAction(() => {\n this._isUnmounting = false;\n });\n }\n\n /**\n * The method is called when the payload of the view model was changed\n *\n * The state - \"was changed\" is determined inside the setPayload method\n */\n payloadChanged(payload: Payload, prevPayload: Payload) {\n /* Empty method to be overridden */\n }\n\n /**\n * Returns the parent view model\n * For this property to work, the getParentViewModel method is required\n */\n get parentViewModel() {\n return this.getParentViewModel(this.vmParams.parentViewModelId);\n }\n\n /**\n * The method is called when the payload changes in the react component\n */\n setPayload(payload: Payload) {\n if (!this.isPayloadEqual?.(this._payload, payload)) {\n startViewTransitionSafety(\n () => {\n runInAction(() => {\n this.payloadChanged(payload, this._payload);\n this._payload = payload;\n });\n },\n {\n disabled: !this.vmConfig.startViewTransitions.payloadChange,\n },\n );\n }\n }\n\n /**\n * The method of getting the parent view model\n */\n protected getParentViewModel(\n parentViewModelId: Maybe<string>,\n ): ParentViewModel {\n return (\n this.vmParams.parentViewModel ??\n (this.viewModels?.get(parentViewModelId) as unknown as ParentViewModel)\n );\n }\n}\n","import { action, computed, observable, runInAction } from 'mobx';\nimport type { ObservableAnnotationsArray } from 'yummies/mobx';\nimport type { Class, Maybe } from 'yummies/types';\nimport {\n applyObservable,\n mergeVMConfigs,\n type ViewModelsConfig,\n} from '../config/index.js';\nimport type { VMComponent, VMLazyComponent } from '../react/hoc/index.js';\nimport type { ViewModelBase } from './view-model.base.js';\nimport type { ViewModelStore } from './view-model.store.js';\nimport type {\n ViewModelCreateConfig,\n ViewModelGenerateIdConfig,\n ViewModelLookup,\n ViewModelStoreConfig,\n} from './view-model.store.types.js';\nimport type {\n AnyViewModel,\n AnyViewModelSimple,\n ViewModelParams,\n} from './view-model.types.js';\n\nconst baseAnnotations: ObservableAnnotationsArray = [\n [computed, 'mountedViewsCount'],\n [\n action,\n 'mount',\n 'unmount',\n 'attachVMConstructor',\n 'attach',\n 'detach',\n 'linkComponents',\n 'unlinkComponents',\n ],\n];\n\nexport class ViewModelStoreBase<VMBase extends AnyViewModel = AnyViewModel>\n implements ViewModelStore<VMBase>\n{\n protected viewModels: Map<string, VMBase | AnyViewModelSimple>;\n protected linkedComponentVMClasses: Map<\n VMComponent<VMBase, any>,\n Class<VMBase>\n >;\n protected viewModelIdsByClasses: Map<\n Class<VMBase> | Class<AnyViewModelSimple>,\n string[]\n >;\n protected instanceAttachedCount: Map<string, number>;\n\n /**\n * It is temp heap which is needed to get access to view model instance before all initializations happens\n */\n protected viewModelsTempHeap: Map<string, VMBase>;\n\n /**\n * Views waiting for mount\n */\n protected mountingViews: Set<string>;\n\n /**\n * Views waiting for unmount\n */\n protected unmountingViews: Set<string>;\n\n protected vmConfig: ViewModelsConfig;\n\n constructor(protected config?: ViewModelStoreConfig) {\n this.viewModels = observable.map([], { deep: false });\n this.linkedComponentVMClasses = observable.map([], { deep: false });\n this.viewModelIdsByClasses = observable.map([], { deep: true });\n this.instanceAttachedCount = observable.map([], { deep: false });\n this.mountingViews = observable.set([], { deep: false });\n this.unmountingViews = observable.set([], { deep: false });\n this.vmConfig = mergeVMConfigs(config?.vmConfig);\n this.viewModelsTempHeap = new Map();\n\n applyObservable(\n this,\n baseAnnotations,\n this.vmConfig.observable.viewModelStores,\n );\n\n this.vmConfig.hooks.storeCreate(this as ViewModelStore);\n }\n\n get mountedViewsCount() {\n return [...this.instanceAttachedCount.values()].reduce(\n (sum, count) => sum + count,\n 0,\n );\n }\n\n processCreateConfig<VM extends VMBase>(\n config: ViewModelCreateConfig<VM>,\n ): void {\n this.linkComponents(\n config.VM,\n config.component,\n config.ctx?.externalComponent,\n );\n }\n\n createViewModel<VM extends VMBase>(config: ViewModelCreateConfig<VM>): VM {\n const VMConstructor = config.VM as unknown as typeof ViewModelBase;\n const vmConfig = mergeVMConfigs(this.vmConfig, config.vmConfig);\n const vmParams: ViewModelParams<any, any> & ViewModelCreateConfig<VM> = {\n ...config,\n vmConfig,\n };\n\n if (vmConfig.factory) {\n return vmConfig.factory(vmParams) as VM;\n }\n\n return new VMConstructor(vmParams) as unknown as VM;\n }\n\n generateViewModelId<VM extends VMBase>(\n config: ViewModelGenerateIdConfig<VM>,\n ): string {\n if (config.id) {\n return config.id;\n } else {\n return this.vmConfig.generateId(config.ctx);\n }\n }\n\n linkComponents(\n VM: Class<VMBase>,\n ...components: Maybe<\n VMComponent<VMBase, any> | VMLazyComponent<VMBase, any>\n >[]\n ): void {\n components.forEach((component) => {\n if (component && !this.linkedComponentVMClasses.has(component)) {\n this.linkedComponentVMClasses.set(component, VM);\n }\n });\n }\n\n unlinkComponents(\n ...components: Maybe<\n VMComponent<VMBase, any> | VMLazyComponent<VMBase, any>\n >[]\n ): void {\n components.forEach((component) => {\n if (component && this.linkedComponentVMClasses.has(component)) {\n this.linkedComponentVMClasses.delete(component);\n }\n });\n }\n\n getIds<T extends VMBase | AnyViewModelSimple>(\n vmLookup: Maybe<ViewModelLookup<T>>,\n ): string[] {\n if (!vmLookup) return [];\n\n if (typeof vmLookup === 'string') {\n return [vmLookup];\n }\n\n const viewModelClass = (this.linkedComponentVMClasses.get(\n vmLookup as any,\n ) || vmLookup) as Class<T>;\n\n const viewModelIds = this.viewModelIdsByClasses.get(viewModelClass) || [];\n\n return viewModelIds;\n }\n\n getId<T extends VMBase | AnyViewModelSimple>(\n vmLookup: Maybe<ViewModelLookup<T>>,\n ): string | null {\n const viewModelIds = this.getIds(vmLookup);\n\n if (viewModelIds.length === 0) return null;\n\n if (process.env.NODE_ENV !== 'production' && viewModelIds.length > 1) {\n console.warn(\n `Found more than 1 view model with the same identifier. Last instance will been returned`,\n );\n }\n\n return viewModelIds.at(-1)!;\n }\n\n has<T extends VMBase | AnyViewModelSimple>(\n vmLookup: Maybe<ViewModelLookup<T>>,\n ): boolean {\n const id = this.getId(vmLookup);\n\n if (!id) return false;\n\n return this.viewModels.has(id);\n }\n\n get<T extends VMBase | AnyViewModelSimple>(\n vmLookup: Maybe<ViewModelLookup<T>>,\n ): T | null {\n // helps to users of this method to better observe changes in view models\n // this.viewModels.keys();\n\n const id = this.getId(vmLookup);\n\n if (!id) return null;\n\n const observedVM = this.viewModels.get(id) as Maybe<T>;\n\n return observedVM ?? (this.viewModelsTempHeap.get(id) as Maybe<T>) ?? null;\n }\n\n getOrCreateVmId(model: VMBase | AnyViewModelSimple): string {\n if (!model.id) {\n (model as AnyViewModelSimple).id = this.vmConfig.generateId({\n VM: model.constructor,\n });\n }\n\n return model.id!;\n }\n\n getAll<T extends VMBase | AnyViewModelSimple>(\n vmLookup: Maybe<ViewModelLookup<T>>,\n ): T[] {\n const viewModelIds = this.getIds(vmLookup);\n\n return viewModelIds.map((id) => this.viewModels.get(id) as T);\n }\n\n async mount(model: VMBase | AnyViewModelSimple) {\n const modelId = this.getOrCreateVmId(model);\n\n this.mountingViews.add(modelId);\n\n await model.mount?.();\n\n runInAction(() => {\n this.mountingViews.delete(modelId);\n });\n }\n\n async unmount(model: VMBase | AnyViewModelSimple) {\n const modelId = this.getOrCreateVmId(model);\n\n this.unmountingViews.add(modelId);\n\n await model.unmount?.();\n\n runInAction(() => {\n this.unmountingViews.delete(modelId);\n });\n }\n\n protected attachVMConstructor(model: VMBase | AnyViewModelSimple) {\n const modelId = this.getOrCreateVmId(model);\n const constructor = (model as any).constructor as Class<any, any>;\n\n if (this.viewModelIdsByClasses.has(constructor)) {\n const vmIds = this.viewModelIdsByClasses.get(constructor)!;\n if (!vmIds.includes(modelId)) {\n vmIds.push(modelId);\n }\n } else {\n this.viewModelIdsByClasses.set(constructor, [modelId]);\n }\n }\n\n protected dettachVMConstructor(model: VMBase | AnyViewModelSimple) {\n const constructor = (model as any).constructor as Class<any, any>;\n\n if (this.viewModelIdsByClasses.has(constructor)) {\n const vmIds = this.viewModelIdsByClasses\n .get(constructor)!\n .filter((it) => it !== model.id);\n\n if (vmIds.length > 0) {\n this.viewModelIdsByClasses.set(constructor, vmIds);\n } else {\n this.viewModelIdsByClasses.delete(constructor);\n }\n }\n }\n\n markToBeAttached(model: VMBase | AnyViewModelSimple) {\n const modelId = this.getOrCreateVmId(model);\n\n this.viewModelsTempHeap.set(modelId, model as VMBase);\n\n if ('attachViewModelStore' in model) {\n model.attachViewModelStore!(this as ViewModelStore);\n }\n\n this.attachVMConstructor(model);\n }\n\n async attach(model: VMBase | AnyViewModelSimple) {\n const modelId = this.getOrCreateVmId(model);\n\n const attachedCount = this.instanceAttachedCount.get(modelId) ?? 0;\n\n this.instanceAttachedCount.set(modelId, attachedCount + 1);\n\n if (this.viewModels.has(modelId)) {\n return;\n }\n\n this.viewModels.set(modelId, model);\n\n this.attachVMConstructor(model);\n\n await this.mount(model);\n\n this.viewModelsTempHeap.delete(modelId);\n }\n\n async detach(id: string) {\n const attachedCount = this.instanceAttachedCount.get(id) ?? 0;\n\n this.viewModelsTempHeap.delete(id);\n\n const model = this.viewModels.get(id);\n\n if (!model) {\n return;\n }\n\n const nextInstanceAttachedCount = attachedCount - 1;\n\n this.instanceAttachedCount.set(id, nextInstanceAttachedCount);\n\n if (nextInstanceAttachedCount <= 0) {\n if ('willUnmount' in model) {\n model.willUnmount();\n }\n\n this.instanceAttachedCount.delete(id);\n this.viewModels.delete(id);\n this.dettachVMConstructor(model);\n\n await this.unmount(model);\n }\n }\n\n isAbleToRenderView(id: Maybe<string>): boolean {\n const isViewMounting = this.mountingViews.has(id!);\n const hasViewModel = this.viewModels.has(id!);\n return !!id && hasViewModel && !isViewMounting;\n }\n\n clean(): void {\n this.viewModels.clear();\n this.linkedComponentVMClasses.clear();\n this.viewModelIdsByClasses.clear();\n this.instanceAttachedCount.clear();\n this.mountingViews.clear();\n this.unmountingViews.clear();\n this.viewModelsTempHeap.clear();\n }\n}\n","import { createContext } from 'react';\n\nimport type {\n AnyViewModel,\n AnyViewModelSimple,\n} from '../../view-model/index.js';\n\n// will contains the view model\nexport const ActiveViewModelContext = createContext<\n AnyViewModel | AnyViewModelSimple\n>(null as any);\n","import { createContext } from 'react';\n\nimport type { ViewModelStore } from '../../view-model/index.js';\n\n/**\n * Context which contains the view models store instance.\n * This context is used to access the view models store inside the React components.\n * @see {@link ViewModelStore}\n */\nexport const ViewModelsContext = createContext<ViewModelStore>(\n null as unknown as ViewModelStore,\n);\n","import type { ReactNode } from 'react';\nimport type {\n AnyViewModel,\n AnyViewModelSimple,\n} from '../../view-model/index.js';\nimport { ActiveViewModelContext } from '../contexts/index.js';\n\n/**\n * This is a provider for the `ActiveViewModelContext`.\n * This HOC is not recommended for public usage.\n * Better to use `withViewModel` HOC.\n */\nexport const ActiveViewModelProvider =\n ActiveViewModelContext.Provider as unknown as React.ComponentType<{\n value: AnyViewModel | AnyViewModelSimple;\n children?: ReactNode;\n }>;\n","import { useEffect, useLayoutEffect } from 'react';\n\nexport const useIsomorphicLayoutEffect =\n typeof window === 'undefined' ? useEffect : useLayoutEffect;\n","import { useMemo, useRef } from 'react';\nimport type { AnyObject } from 'yummies/types';\n\ntype UseValueHook = <TValue extends AnyObject>(\n getValue: () => TValue,\n) => TValue;\n\nlet useValueImpl = null as unknown as UseValueHook;\n\nif (process.env.NODE_ENV === 'production') {\n /**\n * This implementation is not working with HMR\n */\n useValueImpl = (getValue) => {\n const valueRef = useRef<any | null>(null);\n\n if (!valueRef.current) {\n valueRef.current = getValue();\n }\n\n return valueRef.current;\n };\n} else {\n /**\n * This is might be helpful for better HMR Vite\n */\n useValueImpl = (getValue) => {\n return useMemo(getValue, []);\n };\n}\n\n/**\n * This hook accept `getValue` function and returns it result.\n *\n * `getValue` _should_ executes **ONLY ONCE**.\n * But in HMR it can executes more than 1 time\n *\n * @example\n * ```\n * const num = useValue(() => 1); // 1\n * ```\n */\nexport const useValue = useValueImpl;\n","import { useContext, useLayoutEffect } from 'react';\nimport type { Class, IsPartial, Maybe } from 'yummies/types';\nimport type { ViewModelsConfig } from '../../config/index.js';\nimport { viewModelsConfig } from '../../config/index.js';\nimport { isViewModelClass } from '../../utils/index.js';\nimport type {\n AnyViewModel,\n AnyViewModelSimple,\n ViewModelCreateConfig,\n ViewModelSimple,\n} from '../../view-model/index.js';\nimport {\n ActiveViewModelContext,\n ViewModelsContext,\n} from '../contexts/index.js';\nimport { useIsomorphicLayoutEffect, useValue } from '../lib/hooks/index.js';\n\nexport interface UseCreateViewModelConfig<TViewModel extends AnyViewModel>\n extends Pick<\n ViewModelCreateConfig<TViewModel>,\n 'vmConfig' | 'ctx' | 'component' | 'props'\n > {\n /**\n * Unique identifier for the view\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html#id)\n */\n id?: Maybe<string>;\n\n /**\n * Function to generate an identifier for the view model\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html#generateid)\n */\n generateId?: ViewModelsConfig<TViewModel>['generateId'];\n\n /**\n * Function to create an instance of the VM class\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html#factory)\n */\n factory?: ViewModelsConfig<TViewModel>['factory'];\n}\n\n/**\n * Creates new instance of ViewModel\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/use-create-view-model.html)\n */\nexport function useCreateViewModel<TViewModel extends AnyViewModel>(\n VM: Class<TViewModel>,\n ...args: IsPartial<TViewModel['payload']> extends true\n ? [\n payload?: TViewModel['payload'],\n config?: UseCreateViewModelConfig<TViewModel>,\n ]\n : [\n payload: TViewModel['payload'],\n config?: UseCreateViewModelConfig<TViewModel>,\n ]\n): TViewModel;\n\n/**\n * Creates new instance of ViewModelSimple\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/use-create-view-model.html)\n */\nexport function useCreateViewModel<TViewModelSimple extends ViewModelSimple>(\n VM: Class<TViewModelSimple>,\n ...args: TViewModelSimple extends ViewModelSimple<infer TPayload>\n ? IsPartial<TPayload> extends true\n ? [payload?: TPayload]\n : [payload: TPayload]\n : []\n): TViewModelSimple;\n\n/**\n * Creates new instance of ViewModelSimple\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/use-create-view-model.html)\n */\nexport function useCreateViewModel<TViewModelSimple>(\n VM: Class<TViewModelSimple>,\n): TViewModelSimple;\n\n/**\n * Creates new instance of ViewModel\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/use-create-view-model.html)\n */\nexport function useCreateViewModel(\n VM: Class<any>,\n payload?: any,\n config?: any,\n) {\n if (isViewModelClass(VM)) {\n // scenario for ViewModelBase\n return useCreateViewModelBase(VM, payload, config);\n }\n\n // scenario for ViewModelSimple\n return useCreateViewModelSimple(VM, payload);\n}\n\nconst useCreateViewModelBase = (\n VM: Class<AnyViewModel>,\n payload?: any,\n config?: Maybe<UseCreateViewModelConfig<AnyViewModel>>,\n) => {\n const viewModels = useContext(ViewModelsContext);\n const parentViewModel = useContext(ActiveViewModelContext);\n\n const ctx = config?.ctx ?? {};\n\n const instance = useValue(() => {\n const id =\n viewModels?.generateViewModelId({\n ...config,\n ctx,\n VM,\n parentViewModelId: parentViewModel?.id ?? null,\n }) ??\n config?.id ??\n viewModelsConfig.generateId(ctx);\n\n const instanceFromStore = viewModels ? viewModels.get(id) : null;\n\n if (instanceFromStore) {\n return instanceFromStore as AnyViewModel;\n } else {\n const configCreate: ViewModelCreateConfig<any> = {\n ...config,\n vmConfig: config?.vmConfig,\n id,\n parentViewModelId: parentViewModel?.id,\n payload: payload ?? {},\n VM,\n viewModels,\n parentViewModel,\n ctx,\n };\n\n viewModels?.processCreateConfig(configCreate);\n\n const instance: AnyViewModel =\n config?.factory?.(configCreate) ??\n viewModels?.createViewModel<any>(configCreate) ??\n viewModelsConfig.factory(configCreate);\n\n instance.willMount();\n\n viewModels?.markToBeAttached(instance);\n\n return instance;\n }\n });\n\n useIsomorphicLayoutEffect(() => {\n if (viewModels) {\n viewModels.attach(instance);\n return () => {\n viewModels.detach(instance.id);\n };\n } else {\n instance.mount();\n return () => {\n instance.willUnmount();\n instance.unmount();\n };\n }\n }, [instance]);\n\n instance.setPayload(payload ?? {});\n\n return instance;\n};\n\nconst useCreateViewModelSimple = (\n VM: Class<AnyViewModelSimple>,\n payload?: any,\n) => {\n const viewModels = useContext(ViewModelsContext);\n const parentViewModel = useContext(ActiveViewModelContext);\n\n const instance = useValue(() => {\n const instance = new VM();\n\n instance.parentViewModel =\n parentViewModel as unknown as (typeof instance)['parentViewModel'];\n\n viewModels?.markToBeAttached(instance);\n\n return instance;\n });\n\n if ('setPayload' in instance) {\n useLayoutEffect(() => {\n instance.setPayload!(payload);\n }, [payload]);\n }\n\n useIsomorphicLayoutEffect(() => {\n if (viewModels) {\n viewModels.attach(instance);\n return () => {\n viewModels.detach(instance.id);\n };\n } else {\n instance.mount?.();\n return () => {\n instance.unmount?.();\n };\n }\n }, [instance]);\n\n return instance;\n};\n","import { useContext, useRef } from 'react';\nimport type { AnyObject } from 'yummies/types';\nimport type {\n AnyViewModel,\n AnyViewModelSimple,\n ViewModelLookup,\n} from '../../view-model/index.js';\nimport {\n ActiveViewModelContext,\n ViewModelsContext,\n} from '../contexts/index.js';\n\n/**\n * Get access to **already created** instance of ViewModel\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/use-view-model.html)\n */\nexport const useViewModel = <T extends AnyViewModel | AnyViewModelSimple>(\n vmLookup?: ViewModelLookup<T>,\n): T => {\n const viewModels = useContext(ViewModelsContext);\n const activeViewModel = useContext(ActiveViewModelContext);\n const model = viewModels?.get(vmLookup);\n\n // This ref is needed only for development\n // support better HMR in vite\n let devModeModelRef = undefined as unknown as React.MutableRefObject<any>;\n\n if (process.env.NODE_ENV !== 'production') {\n devModeModelRef = useRef<any>();\n }\n\n if (vmLookup == null || !viewModels) {\n if (process.env.NODE_ENV !== 'production' && !viewModels) {\n console.warn(\n 'Warning #1: ViewModelStore not found.\\n',\n 'Unable to get access to view model by id or class name without using ViewModelStore\\n',\n 'Last active view model will be returned.\\n',\n 'More info: https://js2me.github.io/mobx-view-model/warnings/1',\n );\n }\n\n if (!activeViewModel) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'Error #1: Active ViewModel not found.\\n' +\n 'This happened because \"vmLookup\" for hook \"useViewModel\" is not provided and hook trying to lookup active view model using ActiveViewModelContext which works only with using \"withViewModel\" HOC.\\n' +\n 'Please provide \"vmLookup\" (first argument for \"useViewModel\" hook) or use \"withViewModel\" HOC.\\n' +\n 'More info: https://js2me.github.io/mobx-view-model/errors/1',\n );\n }\n throw new Error(\n 'Error #1: https://js2me.github.io/mobx-view-model/errors/1',\n );\n }\n\n if (process.env.NODE_ENV !== 'production') {\n devModeModelRef.current = activeViewModel;\n }\n\n return activeViewModel as unknown as T;\n }\n\n if (!model) {\n let displayName: string = '';\n\n if (typeof vmLookup === 'string') {\n displayName = vmLookup;\n } else if ('name' in vmLookup) {\n displayName = vmLookup.name;\n } else {\n displayName = (vmLookup as AnyObject).displayName;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (devModeModelRef.current) {\n return devModeModelRef.current;\n } else {\n throw new Error(\n `Error #2: View model not found for ${displayName}.\\n` +\n 'This happened because your \"vmLookup\" provided for hook \"useViewModel\" is not found in \"ViewModelStore\".\\n' +\n 'More info: https://js2me.github.io/mobx-view-model/errors/2',\n );\n }\n } else {\n throw new Error(\n 'Error #2: https://js2me.github.io/mobx-view-model/errors/2',\n );\n }\n }\n\n if (process.env.NODE_ENV !== 'production') {\n devModeModelRef.current = activeViewModel;\n }\n\n return model;\n};\n","import { observer } from 'mobx-react-lite';\nimport type { ReactNode } from 'react';\nimport type { Class, IsPartial } from 'yummies/types';\nimport type { AnyViewModel } from '../../view-model/index.js';\nimport {\n type UseCreateViewModelConfig,\n useCreateViewModel,\n} from '../hooks/index.js';\n\nexport type OnlyViewModelProps<TViewModel extends AnyViewModel> = {\n model: Class<TViewModel>;\n children?: ReactNode | ((model: TViewModel) => ReactNode);\n} & (IsPartial<TViewModel['payload']> extends true\n ? {\n payload?: TViewModel['payload'];\n config?: UseCreateViewModelConfig<TViewModel>;\n }\n : {\n payload: TViewModel['payload'];\n config?: UseCreateViewModelConfig<TViewModel>;\n });\n\nexport const OnlyViewModel = observer(\n <TViewModel extends AnyViewModel>({\n model,\n config,\n payload,\n children,\n }: OnlyViewModelProps<TViewModel>) => {\n const vm = useCreateViewModel(model, payload, config);\n\n if (!vm.isMounted) {\n return null;\n }\n\n if (typeof children === 'function') {\n return children(vm);\n }\n return <>{children}</>;\n },\n);\n","import type { ReactNode } from 'react';\nimport type { ViewModelStore } from '../../view-model/index.js';\nimport { ViewModelsContext } from '../contexts/index.js';\n\nexport const ViewModelsProvider =\n ViewModelsContext.Provider as unknown as React.ComponentType<{\n value: ViewModelStore;\n children?: ReactNode;\n }>;\n","import { observer } from 'mobx-react-lite';\nimport { forwardRef, useContext } from 'react';\nimport type {\n AnyObject,\n Class,\n Defined,\n EmptyObject,\n HasKey,\n IsAny,\n IsPartial,\n IsUnknown,\n Maybe,\n} from 'yummies/types';\nimport { viewModelsConfig } from '../../config/index.js';\nimport type {\n AnyViewModel,\n AnyViewModelSimple,\n ViewModel,\n ViewModelSimple,\n ViewModelStore,\n} from '../../view-model/index.js';\nimport { ActiveViewModelProvider } from '../components/active-view-model-provider.js';\nimport { ViewModelsContext } from '../contexts/index.js';\nimport {\n type UseCreateViewModelConfig,\n useCreateViewModel,\n} from '../hooks/index.js';\n\ntype FixedComponentType<P extends AnyObject = {}> =\n /**\n * Fixes typings loss with use `withViewModel` with inline function component\n */\n ((props: P) => React.ReactNode) | React.ComponentClass<P>;\n\ndeclare const process: { env: { NODE_ENV?: string } };\n\nexport type ExtractReactRef<T> = Defined<T> extends React.ForwardedRef<\n infer TForwardedRef\n>\n ? TForwardedRef\n : Defined<T> extends React.LegacyRef<infer TRef>\n ? TRef\n : T;\n\n/**\n * This type is needed to declare prop types for your View component wrapped into `withViewModel` HOC\n *\n * Use second generic type add typings for `forwardedRef` prop\n */\nexport type ViewModelProps<\n VM,\n TForwardedRef = unknown,\n> = IsAny<TForwardedRef> extends true\n ? { model: VM; forwardedRef?: React.ForwardedRef<TForwardedRef> }\n : IsUnknown<TForwardedRef> extends true\n ? { model: VM }\n : { model: VM; forwardedRef?: React.ForwardedRef<TForwardedRef> };\n\ntype ViewModelPropsChargedProps<\n TComponentOriginProps extends AnyObject,\n TViewModel,\n TForwardedRef = unknown,\n> = HasKey<TComponentOriginProps, 'ref'> extends true\n ? Omit<TComponentOriginProps, 'ref'> &\n ViewModelProps<TViewModel, ExtractReactRef<TComponentOriginProps['ref']>>\n : HasKey<TComponentOriginProps, 'forwardedRef'> extends true\n ? TComponentOriginProps\n : TComponentOriginProps &\n ViewModelProps<\n TViewModel,\n IsUnknown<TForwardedRef> extends true ? any : TForwardedRef\n >;\n\ntype VMInputPayloadPropObj<VM> = VM extends ViewModel<infer TPayload, any>\n ? TPayload extends EmptyObject\n ? {}\n : IsPartial<TPayload> extends true\n ? {\n payload?: TPayload;\n }\n : {\n payload: TPayload;\n }\n : VM extends ViewModelSimple<infer TPayload>\n ? TPayload extends EmptyObject\n ? {}\n : IsPartial<TPayload> extends true\n ? {\n payload?: TPayload;\n }\n : {\n payload: TPayload;\n }\n : {};\n\n/**\n * @deprecated use `VMComponentProps`\n */\nexport type ViewModelInputProps<\n VM,\n TForwardedRef = unknown,\n> = VMInputPayloadPropObj<VM> & {\n ref?: React.LegacyRef<TForwardedRef>;\n};\n\nexport type WithViewModelReactHook = (\n allProps: AnyObject,\n ctx: AnyObject,\n viewModels: Maybe<ViewModelStore>,\n ref?: any,\n) => void;\n\nexport interface ViewModelHocConfig<VM extends AnyViewModel>\n extends Omit<UseCreateViewModelConfig<VM>, 'component' | 'componentProps'> {\n /**\n * Component to render if the view model initialization takes too long\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html#fallback)\n */\n fallback?: React.ComponentType;\n\n /**\n * Function to invoke additional React hooks in the resulting component\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html#reacthook)\n */\n reactHook?: WithViewModelReactHook;\n\n /**\n * Function that should return the payload for the VM\n * by default, it is - (props) => props.payload\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html#getpayload)\n */\n getPayload?: (allProps: any) => any;\n\n /**\n * Forwards ref using `React.forwardRef` but pass it to props as prop `ref`\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html#forwardref)\n */\n forwardRef?: boolean;\n}\n\nexport interface ViewModelSimpleHocConfig<_VM> {\n /**\n * Component to render if the view model initialization takes too long\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html#fallback)\n */\n fallback?: React.ComponentType;\n\n /**\n * Function to invoke additional React hooks in the resulting component\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html#reacthook)\n */\n reactHook?: WithViewModelReactHook;\n\n /**\n * Function that should return the payload for the VM\n * by default, it is - (props) => props.payload\n */\n getPayload?: (allProps: any) => any;\n\n /**\n * Forwards ref using `React.forwardRef` but pass it to props as prop `ref`\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html#forwardref)\n */\n forwardRef?: boolean;\n}\n\nexport type AllViewModelPropsKeys = keyof Required<ViewModelProps<any, any>>;\n\nexport type VMComponentProps<\n TViewModel,\n TComponentOriginProps extends AnyObject = AnyObject,\n TForwardedRef = unknown,\n> = Omit<TComponentOriginProps, AllViewModelPropsKeys> &\n VMInputPayloadPropObj<TViewModel> &\n (HasKey<TComponentOriginProps, 'ref'> extends true\n ? {}\n : HasKey<TComponentOriginProps, 'forwardedRef'> extends true\n ? Required<TComponentOriginProps>['forwardedRef'] extends React.LegacyRef<any>\n ? {\n ref?: TComponentOriginProps['forwardedRef'];\n }\n : Pick<TComponentOriginProps, 'forwardedRef'>\n : IsUnknown<TForwardedRef> extends true\n ? {}\n : { ref?: React.LegacyRef<TForwardedRef> });\n\nexport type VMComponent<\n TViewModel,\n TComponentOriginProps extends AnyObject = AnyObject,\n TForwardedRef = unknown,\n> = (\n props: VMComponentProps<TViewModel, TComponentOriginProps, TForwardedRef>,\n) => React.ReactNode;\n\n/**\n * A Higher-Order Component that connects React components to their ViewModels, providing seamless MobX integration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html)\n */\nexport function withViewModel<\n TViewModel extends AnyViewModel,\n TComponentOriginProps extends AnyObject = AnyObject,\n TForwardedRef = unknown,\n>(\n model: Class<TViewModel>,\n component: React.ComponentType<\n ViewModelPropsChargedProps<TComponentOriginProps, TViewModel, TForwardedRef>\n >,\n config?: ViewModelHocConfig<TViewModel>,\n): VMComponent<TViewModel, TComponentOriginProps, TForwardedRef>;\n\n/**\n * A Higher-Order Component that connects React components to their ViewModels, providing seamless MobX integration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html)\n */\nexport function withViewModel<\n TViewModel extends AnyViewModel,\n TForwardedRef = unknown,\n>(\n model: Class<TViewModel>,\n config?: ViewModelHocConfig<TViewModel>,\n): <TComponentOriginProps extends AnyObject = ViewModelProps<TViewModel>>(\n Component?: React.ComponentType<\n ViewModelPropsChargedProps<TComponentOriginProps, TViewModel, TForwardedRef>\n >,\n) => VMComponent<TViewModel, TComponentOriginProps, TForwardedRef>;\n\n/**\n * A Higher-Order Component that connects React components to their ViewModels, providing seamless MobX integration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html)\n */\nexport function withViewModel<TViewModel, TForwardedRef = unknown>(\n model: Class<TViewModel>,\n config?: ViewModelSimpleHocConfig<TViewModel>,\n): <TComponentOriginProps extends AnyObject = ViewModelProps<TViewModel>>(\n Component?: FixedComponentType<\n ViewModelPropsChargedProps<TComponentOriginProps, TViewModel, TForwardedRef>\n >,\n) => VMComponent<TViewModel, TComponentOriginProps, TForwardedRef>;\n\n/**\n * A Higher-Order Component that connects React components to their ViewModels, providing seamless MobX integration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html)\n */\nexport function withViewModel<\n TViewModel extends AnyViewModelSimple,\n TComponentOriginProps extends AnyObject = AnyObject,\n TForwardedRef = unknown,\n>(\n model: Class<TViewModel>,\n component: FixedComponentType<\n ViewModelPropsChargedProps<TComponentOriginProps, TViewModel, TForwardedRef>\n >,\n config?: ViewModelSimpleHocConfig<TViewModel>,\n): VMComponent<TViewModel, TComponentOriginProps, TForwardedRef>;\n\n/**\n * A Higher-Order Component that connects React components to their ViewModels, providing seamless MobX integration.\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html)\n */\nexport function withViewModel<\n TViewModel,\n TComponentOriginProps extends AnyObject = ViewModelProps<TViewModel>,\n TForwardedRef = unknown,\n>(\n model: Class<TViewModel>,\n component: FixedComponentType<\n ViewModelPropsChargedProps<TComponentOriginProps, TViewModel, TForwardedRef>\n >,\n config?: ViewModelSimpleHocConfig<TViewModel>,\n): VMComponent<TViewModel, TComponentOriginProps, TForwardedRef>;\n\n/**\n * Creates new instance of ViewModel\n *\n * [**Documentation**](https://js2me.github.io/mobx-view-model/react/api/with-view-model.html)\n */\nexport function withViewModel(\n VM: Class<any>,\n configOrComponent?: any,\n configOrNothing?: any,\n): any {\n if (\n typeof configOrComponent === 'function' ||\n (configOrComponent && configOrComponent.$$typeof !== undefined)\n ) {\n const config = configOrNothing ?? {};\n return withViewModelWrapper(\n VM,\n {\n ...config,\n ctx: {\n VM,\n generateId: config.generateId,\n ...config.ctx,\n },\n },\n configOrComponent,\n );\n } else {\n const config = configOrComponent ?? {};\n const finalConfig = {\n ...config,\n ctx: {\n VM,\n generateId: config.generateId,\n ...config.ctx,\n },\n };\n\n return (Component: React.ComponentType<any>) =>\n withViewModelWrapper(VM, finalConfig, Component);\n }\n}\n\nconst REACT_MEMO_SYMBOL = Symbol.for('react.memo');\n\nconst withViewModelWrapper = (\n VM: Class<any>,\n config: ViewModelHocConfig<any>,\n OriginalComponent?: React.ComponentType<any>,\n) => {\n const processViewComponent =\n config.vmConfig?.processViewComponent ??\n viewModelsConfig.processViewComponent;\n\n const wrapViewsInObserver =\n config.vmConfig?.wrapViewsInObserver ??\n viewModelsConfig.wrapViewsInObserver;\n\n let Component =\n processViewComponent?.(OriginalComponent, VM, config) ?? OriginalComponent;\n\n if (\n wrapViewsInObserver &&\n Component &&\n (Component as any).$$typeof !== REACT_MEMO_SYMBOL\n ) {\n // @ts-expect-error\n Component = observer(Component);\n }\n\n const reactHook = config.reactHook;\n const getPayload = config.getPayload;\n const FallbackComponent =\n config.fallback ?? viewModelsConfig.fallbackComponent;\n\n const RawComponent = (allProps: any, ref: any) => {\n const viewModels = useContext(ViewModelsContext);\n\n reactHook?.(allProps, config.ctx!, viewModels, ref);\n\n const { payload: rawPayload, ...componentProps } = allProps;\n const payload = getPayload?.(allProps) ?? rawPayload;\n\n if (config.forwardRef && !('forwardedRef' in componentProps)) {\n componentProps.forwardedRef = ref;\n }\n\n const model = useCreateViewModel(VM, payload, {\n ...config,\n props: componentProps,\n }) as unknown as AnyViewModel | AnyViewModelSimple;\n\n const isRenderAllowedByStore =\n !viewModels || viewModels.isAbleToRenderView(model.id);\n\n // This condition is works for AnyViewModelSimple too\n // All other variants will be bad for performance\n const isRenderAllowed =\n isRenderAllowedByStore && (model as AnyViewModel).isMounted !== false;\n\n if (isRenderAllowed) {\n return (\n <ActiveViewModelProvider value={model}>\n {Component && <Component {...componentProps} model={model} />}\n </ActiveViewModelProvider>\n );\n }\n\n return (\n FallbackComponent && <FallbackComponent {...allProps} payload={payload} />\n );\n };\n\n let ConnectedViewModel = RawComponent;\n\n if (config.forwardRef) {\n ConnectedViewModel = forwardRef(ConnectedViewModel) as any;\n }\n\n ConnectedViewModel = observer(ConnectedViewModel);\n\n if (process.env.NODE_ENV !== 'production') {\n (ConnectedViewModel as React.ComponentType).displayName =\n `ConnectedViewModel(${VM.name}->Component)`;\n }\n\n // There is no problem to just assign it here to config\n // This property is needed to pass in `useCreateViewModel()` hook\n // @ts-expect-error\n config.component = ConnectedViewModel as unknown as VMComponent<\n AnyViewModel,\n any\n >;\n\n return ConnectedViewModel;\n};\n","import {\n type LoadableConfig,\n type LoadableMixin,\n loadable,\n} from 'react-simple-loadable';\nimport { type PackedAsyncModule, unpackAsyncModule } from 'yummies/imports';\nimport type { Class, Maybe, MaybePromise } from 'yummies/types';\nimport { viewModelsConfig } from '../../config/index.js';\nimport type {\n AnyViewModel,\n AnyViewModelSimple,\n} from '../../view-model/index.js';\nimport {\n type ViewModelHocConfig,\n type ViewModelSimpleHocConfig,\n type VMComponent,\n withViewModel,\n} from './with-view-model.js';\n\nexport interface LazyViewAndModel<\n TViewModel extends AnyViewModel | AnyView