mobx-keystone-mindreframer
Version:
A MobX powered state management solution based on data trees with first class support for Typescript, snapshots, patches and much more
48 lines (39 loc) • 1.32 kB
text/typescript
import { set } from "mobx"
import { isArray } from "../utils"
import { ModelPool } from "../utils/ModelPool"
import { fromSnapshot } from "./fromSnapshot"
import { detachIfNeeded, reconcileSnapshot, registerReconciler } from "./reconcileSnapshot"
import type { SnapshotInOfObject } from "./SnapshotOf"
import { SnapshotterAndReconcilerPriority } from "./SnapshotterAndReconcilerPriority"
function reconcileArraySnapshot(
value: any,
sn: SnapshotInOfObject<any[]>,
modelPool: ModelPool
): any[] {
if (!isArray(value)) {
// no reconciliation possible
return fromSnapshot(sn)
}
// remove excess items
if (value.length > sn.length) {
value.splice(sn.length, value.length - sn.length)
}
// reconcile present items
for (let i = 0; i < value.length; i++) {
const oldValue = value[i]
const newValue = reconcileSnapshot(oldValue, sn[i], modelPool)
detachIfNeeded(newValue, oldValue, modelPool)
set(value, i as any, newValue)
}
// add excess items
for (let i = value.length; i < sn.length; i++) {
value.push(reconcileSnapshot(undefined, sn[i], modelPool))
}
return value
}
registerReconciler(SnapshotterAndReconcilerPriority.Array, (value, sn, modelPool) => {
if (isArray(sn)) {
return reconcileArraySnapshot(value, sn, modelPool)
}
return undefined
})