mobx-keystone
Version:
A MobX powered state management solution based on data trees with first class support for TypeScript, snapshots, patches and much more
44 lines (37 loc) • 1.22 kB
text/typescript
import { reaction } from "mobx"
import { assertTweakedObject } from "../tweaker/core"
import { getSnapshot } from "./getSnapshot"
import type { SnapshotOutOf } from "./SnapshotOf"
/**
* Listener function for onSnapshot.
*/
export type OnSnapshotListener<T> = (sn: SnapshotOutOf<T>, prevSn: SnapshotOutOf<T>) => void
/**
* Disposer function for onSnapshot.
*/
export type OnSnapshotDisposer = () => void
/**
* Adds a reaction that will trigger every time an snapshot changes.
*
* @template T Object type.
* @param nodeOrFn Object to get the snapshot from or a function to get it.
* @param listener Function that will be triggered when the snapshot changes.
* @returns A disposer.
*/
export function onSnapshot<T extends object>(
nodeOrFn: T | (() => T),
listener: OnSnapshotListener<T>
): OnSnapshotDisposer {
const nodeFn = typeof nodeOrFn === "function" ? (nodeOrFn as () => T) : () => nodeOrFn
const node = nodeFn()
assertTweakedObject(node, "node")
let currentSnapshot = getSnapshot(node)
return reaction(
() => getSnapshot(nodeFn()),
(newSnapshot) => {
const prevSn = currentSnapshot
currentSnapshot = newSnapshot
listener(newSnapshot, prevSn)
}
)
}