mosx
Version:
Multiview observable state management engine
76 lines (60 loc) • 2.11 kB
text/typescript
import { ObservableMap, ObservableSet } from "mobx"
import { PrimitiveType } from "./decorators"
import { Mosx } from "./mosx"
export interface ISnapshot {
[key: string]: any
}
export interface ISnapshotParams {
tags?: string | string[]
objTags?: Set<string>
spy?: boolean
}
export const snapshot = (target: any, params: ISnapshotParams): any => {
if (target instanceof ObservableMap) {
return mapSnapshot(target, params)
} else if (target instanceof ObservableSet) {
return setSnapshot(target, params)
} else if (Array.isArray(target)) {
return arraySnapshot(target, params)
} else if (target instanceof Mosx) {
return mosxSnapshot(target, params)
} else {
return target
}
}
export const compressedSnapshot = (target: any, params: ISnapshotParams): any => {
return target
}
const mosxSnapshot = (target: any, params: ISnapshotParams): ISnapshot | undefined => {
const { tags = [], objTags = Mosx.getTags(target) || new Set(), spy = false } = params
const tagsArr = !Array.isArray(tags) ? [tags] : tags
// object props
const meta = Mosx.meta(target)
// check if object is visible for listner
if (!spy && meta.hidden && !tagsArr.find((tag) => objTags.has(tag))) { return }
// filtered visible props
const props = meta.props!.filter((prop) => spy || !prop.hidden || tagsArr.find((tag) => objTags.has(tag)))
// create snapshot object
const result: ISnapshot = {}
props.forEach(({ key }) => {
result[key] = snapshot((target as any)[key], params)
})
return result
}
const mapSnapshot = (target: ObservableMap, params: ISnapshotParams): any => {
const result: any = {}
for (const [key, object] of target) {
result[key] = snapshot(object, params)
}
return result
}
const arraySnapshot = (target: PrimitiveType[], params: ISnapshotParams): any[] => {
return target.map((item) => snapshot(item, params))
}
const setSnapshot = (target: ObservableSet, params: ISnapshotParams): any => {
const result: any = new Set()
for (const [key, object] of target) {
result.add(snapshot(object, params))
}
return result
}