@benev/slate
Version:
frontend web stuff
47 lines (36 loc) • 987 B
text/typescript
import {Slice} from "./parts/slice.js"
import {deep} from "../tools/deep/deep.js"
import {SliceAccessors, Sliceable} from "./parts/types.js"
export class StateTree<S> implements Sliceable<S> {
#state: S
#readable: S
#onChange: () => void
#circularity_lock = false
#make_frozen_clone() {
return deep.freeze(structuredClone(this.#state))
}
constructor(state: S, onChange = () => {}) {
this.#state = structuredClone(state)
this.#readable = this.#make_frozen_clone()
this.#onChange = onChange
}
get state() {
return this.#readable
}
transmute(fun: (state: S) => S) {
if (this.#circularity_lock)
throw new Error("circular error")
this.#circularity_lock = true
this.#state = fun(structuredClone(this.#state))
this.#readable = this.#make_frozen_clone()
this.#onChange()
this.#circularity_lock = false
}
slice<X>({getter, setter}: SliceAccessors<S, X>) {
return new Slice<S, X>({
parent: this as Sliceable<S>,
getter,
setter,
})
}
}