UNPKG

mobx-keystone

Version:

A MobX powered state management solution based on data trees with first class support for TypeScript, snapshots, patches and much more

58 lines (51 loc) 2.15 kB
import { AnyModel } from "../model/BaseModel" import { getModelIdPropertyName } from "../model/getModelMetadata" import { modelTypeKey } from "../model/metadata" import { ModelConstructorOptions } from "../model/ModelConstructorOptions" import { isModelSnapshot } from "../model/utils" import { ModelClass } from "../modelShared/BaseModelShared" import { getModelInfoForName } from "../modelShared/modelInfo" import { failure } from "../utils" import { FromSnapshotContext, registerSnapshotter } from "./fromSnapshot" import { SnapshotInOfModel } from "./SnapshotOf" import { SnapshotterAndReconcilerPriority } from "./SnapshotterAndReconcilerPriority" function fromModelSnapshot(sn: SnapshotInOfModel<AnyModel>, ctx: FromSnapshotContext): AnyModel { const type = sn[modelTypeKey] if (!type) { throw failure(`a model snapshot must contain a type key (${modelTypeKey}), but none was found`) } const modelInfo = getModelInfoForName(type) if (!modelInfo) { throw failure(`model with name "${type}" not found in the registry`) } const modelIdPropertyName = getModelIdPropertyName(modelInfo.class as ModelClass<AnyModel>) if (modelIdPropertyName && sn[modelIdPropertyName] === undefined) { throw failure( `a model snapshot of type '${type}' must contain an id key (${modelIdPropertyName}), but none was found` ) } return new (modelInfo.class as any)(undefined, { snapshotInitialData: { unprocessedSnapshot: sn, unprocessedModelType: typeof ctx.untypedSnapshot === "object" && ctx.untypedSnapshot && modelTypeKey in ctx.untypedSnapshot ? ctx.untypedSnapshot[modelTypeKey] : undefined, snapshotToInitialData: ctx.snapshotToInitialData, }, generateNewIds: ctx.options.generateNewIds, } satisfies ModelConstructorOptions) } /** * @internal */ export function registerFromModelSnapshotter() { registerSnapshotter(SnapshotterAndReconcilerPriority.Model, (sn, ctx) => { if (isModelSnapshot(sn)) { return fromModelSnapshot(sn, ctx) } return undefined }) }