UNPKG

@tldraw/state

Version:

tldraw infinite canvas SDK (state).

75 lines (68 loc) 2.73 kB
import { ArraySet } from './ArraySet' /** @public */ export const RESET_VALUE: unique symbol = Symbol.for('com.tldraw.state/RESET_VALUE') /** @public */ export type RESET_VALUE = typeof RESET_VALUE /** * A Signal is a reactive value container. The value may change over time, and it may keep track of the diffs between sequential values. * * There are two types of signal: * * - Atomic signals, created using {@link atom}. These are mutable references to values that can be changed using {@link Atom.set}. * - Computed signals, created using `computed`. These are values that are computed from other signals. They are recomputed lazily if their dependencies change. * * @public */ export interface Signal<Value, Diff = unknown> { /** * The name of the signal. This is used at runtime for debugging and perf profiling only. It does not need to be globally unique. */ name: string /** * The current value of the signal. This is a reactive value, and will update when the signal changes. * Any computed signal that depends on this signal will be lazily recomputed if this signal changes. * Any effect that depends on this signal will be rescheduled if this signal changes. */ get(): Value /** * The epoch when this signal's value last changed. Note that this is not the same as when the value was last computed. * A signal may recompute it's value without changing it. */ lastChangedEpoch: number /** * Returns the sequence of diffs between the the value at the given epoch and the current value. * Returns the `RESET_VALUE` constant if there is not enough information to compute the diff sequence. * @param epoch - The epoch to get diffs since. */ getDiffSince(epoch: number): RESET_VALUE | Diff[] /** * Returns the current value of the signal without capturing it as a dependency. * Use this if you need to retrieve the signal's value in a hot loop where the performance overhead of dependency tracking is too high. */ __unsafe__getWithoutCapture(ignoreErrors?: boolean): Value /** @internal */ children: ArraySet<Child> } /** @internal */ export interface Child { lastTraversedEpoch: number readonly parentSet: ArraySet<Signal<any, any>> readonly parents: Signal<any, any>[] readonly parentEpochs: number[] readonly name: string isActivelyListening: boolean __debug_ancestor_epochs__: Map<Signal<any, any>, number> | null } /** * Computes the diff between the previous and current value. * * If the diff cannot be computed for whatever reason, it should return {@link state#RESET_VALUE}. * * @public */ export type ComputeDiff<Value, Diff> = ( previousValue: Value, currentValue: Value, lastComputedEpoch: number, currentEpoch: number ) => Diff | RESET_VALUE