import { BlockModel } from '../model/block/block-model'; import { type DraftModel, toDraftModel } from '../model/block/draft'; import { type InternalPrimitives, internalPrimitives, } from '../model/block/zod'; import type { AssetsManager } from './assets'; import { fromJSON, toJSON } from './json'; import type { BlockSnapshot } from './type'; export type BlockSnapshotLeaf = Pick< BlockSnapshot, 'id' | 'flavour' | 'props' | 'version' >; export type FromSnapshotPayload = { json: BlockSnapshotLeaf; assets: AssetsManager; children: BlockSnapshot[]; }; export type ToSnapshotPayload = { model: DraftModel> | BlockModel; assets: AssetsManager; }; export type SnapshotNode = { id: string; flavour: string; version: number; props: Props; }; export class BaseBlockTransformer { protected _internal: InternalPrimitives = internalPrimitives; protected _propsFromSnapshot(propsJson: Record) { return Object.fromEntries( Object.entries(propsJson).map(([key, value]) => { return [key, fromJSON(value)]; }) ) as Props; } protected _propsToSnapshot(model: DraftModel | BlockModel) { let draftModel: DraftModel; if (model instanceof BlockModel) { draftModel = toDraftModel(model); } else { draftModel = model; } return Object.fromEntries( draftModel.keys.map(key => { const value = draftModel.props[key as keyof typeof draftModel.props]; return [key, toJSON(value)]; }) ); } constructor(public readonly transformerConfigs: Map) {} fromSnapshot({ json, }: FromSnapshotPayload): Promise> | SnapshotNode { const { flavour, id, version, props: _props } = json; const props = this._propsFromSnapshot(_props); return { id, flavour, version: version ?? -1, props, }; } toSnapshot({ model }: ToSnapshotPayload): BlockSnapshotLeaf { const { id, flavour, version } = model; const props = this._propsToSnapshot(model); return { id, flavour, version, props, }; } }