mosx
Version:
Multiview observable state management engine
100 lines (80 loc) • 3.08 kB
text/typescript
import { isObservableMap, ObservableMap, ObservableSet } from "mobx"
import { ITreeNode, IReversibleJsonPatch, Mosx, mx, IChange, MosxTracker } from "../internal"
import { PatchPack } from "patchpack"
import { Serializer } from "."
export class SchemaSerializer extends Serializer {
public patchPack!: PatchPack
public deleted!: number
constructor (tracker: MosxTracker) {
super(tracker)
tracker.privateMapValuePatch = true
}
public onCreate() {
this.deleted = -1
this.patchPack = new PatchPack()
const { _types } = this.patchPack.schema as any
// add mosx types to schema map
mx.$context.types.forEach((type) => {
const meta = mx.$context.meta.get(type.name)
if (!meta) { return }
// this.patchPack.schema.addType(type.name, type.$mx.props.map((prop: any) => prop.key), type)
const index = _types.length
_types.push({ name: type.name, props: type.$mx.props.map((prop: any) => prop.key), index, ref: type })
})
}
public onCreateNode(entry: ITreeNode, target: any) {
const schema = this.patchPack.schema
const parentId = entry.parent ? entry.parent.id : -1
const parent = schema.getNode(parentId)
// if (parent && parent.type === MAP_NODE) {
// parent.keys!.push(entry.path)
// }
const index = parent ? schema.getChildIndex(parent, entry.path) : -1
if (target instanceof ObservableMap) {
// add map node to schema
schema.createNode(entry.id, parent, -2, entry.path, index)
// patch = schema.nodesAddMap(entry.id, parentId, entry.path, [...target.keys()])
} else if (target instanceof ObservableSet) {
// TODO add ObservableSet
} else if (Array.isArray(target)) {
// add array node to schema
schema.createNode(entry.id, parent, -1, entry.path, index)
} else if (target instanceof Mosx) {
// add mosx node to schema
const type = schema.typeByName(entry.meta.type!)!
schema.createNode(entry.id, parent, type, entry.path, index)
}
}
public onDeleteNode(entry: ITreeNode) {
if (this.deleted === -1) {
this.deleted = entry.id
const node = this.patchPack.schema.getNode(this.deleted)!
this.patchPack.schema.deleteNode(node)
}
}
public afterChange(change: IChange) {
if (this.deleted >= 0) {
this.deleted = -1
this.patchPack.schema.clearDeleted()
}
}
public beforeChange(change: IChange, parent: ITreeNode) {
if (isObservableMap(change.object) && change.type === "add") {
const node = this.patchPack.schema.getNode(parent.id)
if (!node) { return }
node.keys!.push(change.name)
}
}
public encodeSnapshot(value: any) {
return this.patchPack.encodeState(value, true, false)
}
public decodeSnapshot(buffer: Buffer) {
return this.patchPack.decodeState(buffer)
}
public encodePatch(patch: IReversibleJsonPatch, entry: ITreeNode): Buffer {
return this.patchPack.encodePatch(patch, false)
}
public decodePatch (buffer: Buffer) {
return this.patchPack.decodePatch(buffer)
}
}