bireactive 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/README.md +14 -7
  2. package/dist/automerge/doc-cell.d.ts +20 -0
  3. package/dist/automerge/doc-cell.js +80 -0
  4. package/dist/automerge/index.d.ts +3 -0
  5. package/dist/automerge/index.js +12 -0
  6. package/dist/automerge/reconcile.d.ts +5 -0
  7. package/dist/automerge/reconcile.js +63 -0
  8. package/dist/core/_counts.d.ts +48 -0
  9. package/dist/core/_counts.js +51 -0
  10. package/dist/core/cell.d.ts +148 -112
  11. package/dist/core/cell.js +945 -768
  12. package/dist/core/debug.d.ts +25 -0
  13. package/dist/core/debug.js +121 -0
  14. package/dist/core/derived-geometry.js +4 -7
  15. package/dist/core/index.d.ts +9 -2
  16. package/dist/core/index.js +8 -1
  17. package/dist/core/lenses/aggregates.d.ts +42 -52
  18. package/dist/core/lenses/aggregates.js +225 -116
  19. package/dist/core/lenses/geometry.d.ts +22 -4
  20. package/dist/core/lenses/geometry.js +59 -27
  21. package/dist/core/lenses/index.d.ts +6 -6
  22. package/dist/core/lenses/index.js +6 -6
  23. package/dist/core/lenses/memory.js +4 -17
  24. package/dist/core/lenses/numerical.d.ts +100 -0
  25. package/dist/core/lenses/{typed-factor.js → numerical.js} +136 -34
  26. package/dist/core/lenses/point-cloud.d.ts +67 -0
  27. package/dist/core/lenses/{closed-form-policies.js → point-cloud.js} +226 -84
  28. package/dist/core/lenses/snap.d.ts +18 -0
  29. package/dist/core/lenses/snap.js +138 -0
  30. package/dist/core/lenses/text.d.ts +40 -0
  31. package/dist/core/lenses/text.js +202 -0
  32. package/dist/core/lifecycle.js +3 -6
  33. package/dist/core/linalg.js +5 -11
  34. package/dist/core/optic.d.ts +13 -0
  35. package/dist/core/optic.js +39 -0
  36. package/dist/core/optics.d.ts +10 -0
  37. package/dist/core/optics.js +26 -0
  38. package/dist/core/store.d.ts +9 -0
  39. package/dist/core/store.js +77 -0
  40. package/dist/core/traits.d.ts +4 -7
  41. package/dist/core/traits.js +8 -12
  42. package/dist/core/values/anchor.js +0 -4
  43. package/dist/core/values/arr.d.ts +110 -0
  44. package/dist/core/values/arr.js +336 -0
  45. package/dist/core/values/audio.d.ts +8 -9
  46. package/dist/core/values/audio.js +11 -28
  47. package/dist/core/values/bool.d.ts +11 -11
  48. package/dist/core/values/bool.js +12 -22
  49. package/dist/core/values/box.d.ts +15 -20
  50. package/dist/core/values/box.js +20 -33
  51. package/dist/core/values/canvas.d.ts +18 -25
  52. package/dist/core/values/canvas.js +32 -66
  53. package/dist/core/values/color.d.ts +5 -7
  54. package/dist/core/values/color.js +5 -11
  55. package/dist/core/values/field.d.ts +6 -7
  56. package/dist/core/values/field.js +10 -35
  57. package/dist/core/values/flags.d.ts +1 -2
  58. package/dist/core/values/flags.js +1 -17
  59. package/dist/core/values/gpu.d.ts +6 -10
  60. package/dist/core/values/gpu.js +8 -22
  61. package/dist/core/values/matrix.d.ts +2 -4
  62. package/dist/core/values/matrix.js +2 -12
  63. package/dist/core/values/num.d.ts +19 -28
  64. package/dist/core/values/num.js +23 -41
  65. package/dist/core/values/pose.d.ts +2 -4
  66. package/dist/core/values/pose.js +3 -12
  67. package/dist/core/values/range.d.ts +18 -26
  68. package/dist/core/values/range.js +22 -39
  69. package/dist/core/values/reg/ambiguity.d.ts +8 -0
  70. package/dist/core/values/reg/ambiguity.js +131 -0
  71. package/dist/core/values/reg/engine.d.ts +91 -0
  72. package/dist/core/values/reg/engine.js +373 -0
  73. package/dist/core/values/reg/nfa.d.ts +42 -0
  74. package/dist/core/values/reg/nfa.js +391 -0
  75. package/dist/core/values/reg/regex.d.ts +7 -0
  76. package/dist/core/values/reg/regex.js +318 -0
  77. package/dist/core/values/reg/types.d.ts +60 -0
  78. package/dist/core/values/reg/types.js +3 -0
  79. package/dist/core/values/reg.d.ts +250 -0
  80. package/dist/core/values/reg.js +649 -0
  81. package/dist/core/values/str.d.ts +16 -60
  82. package/dist/core/values/str.js +133 -315
  83. package/dist/core/values/template.js +1 -24
  84. package/dist/core/values/transform.d.ts +3 -5
  85. package/dist/core/values/transform.js +3 -12
  86. package/dist/core/values/tri.d.ts +9 -10
  87. package/dist/core/values/tri.js +9 -15
  88. package/dist/core/values/vec.d.ts +9 -24
  89. package/dist/core/values/vec.js +9 -64
  90. package/dist/formats/lens.js +6 -9
  91. package/dist/index.d.ts +0 -11
  92. package/dist/index.js +1 -11
  93. package/dist/jsx-dev-runtime.d.ts +2 -0
  94. package/dist/jsx-dev-runtime.js +5 -0
  95. package/dist/jsx-runtime.d.ts +54 -0
  96. package/dist/jsx-runtime.js +219 -0
  97. package/dist/schema/lens.js +5 -5
  98. package/dist/shapes/drag-behaviors.d.ts +56 -0
  99. package/dist/shapes/drag-behaviors.js +102 -0
  100. package/dist/shapes/drag-spec.d.ts +52 -0
  101. package/dist/shapes/drag-spec.js +112 -0
  102. package/dist/shapes/index.d.ts +3 -1
  103. package/dist/shapes/index.js +3 -1
  104. package/dist/shapes/interaction.d.ts +2 -3
  105. package/dist/shapes/interaction.js +77 -56
  106. package/dist/shapes/label.js +6 -0
  107. package/dist/shapes/layout.d.ts +47 -1
  108. package/dist/shapes/layout.js +59 -1
  109. package/package.json +22 -1
  110. package/dist/coll.d.ts +0 -74
  111. package/dist/coll.js +0 -210
  112. package/dist/core/lenses/closed-form-policies.d.ts +0 -57
  113. package/dist/core/lenses/decompositions.d.ts +0 -14
  114. package/dist/core/lenses/decompositions.js +0 -224
  115. package/dist/core/lenses/domain-aggregates.d.ts +0 -42
  116. package/dist/core/lenses/domain-aggregates.js +0 -245
  117. package/dist/core/lenses/typed-factor.d.ts +0 -40
@@ -1,19 +1,3 @@
1
- /** Multi-out / stateful back-write sentinel: "leave this parent untouched."
2
- * A `bwd` returning per-parent updates yields `SKIP` for a parent it declines
3
- * to write; every other slot value is written verbatim — INCLUDING `undefined`,
4
- * which is a first-class cell value, not a hole. A SHORT array skips the trailing
5
- * parents (so writing only the leading few needs no `SKIP` padding); `[]` skips
6
- * all. (Single-out 1→1 `put` has no skip notion: it always writes its one parent,
7
- * so it stays `undefined`-safe by construction.) */
8
- export declare const SKIP: unique symbol;
9
- export type Skip = typeof SKIP;
10
- /** Per-parent back-write result over parents `T`: any PREFIX of the full update
11
- * tuple. A shorter array skips the trailing parents; each present slot is a
12
- * value or `SKIP`. For a fixed tuple this is the prefix union, so `[a]` /
13
- * `[a, SKIP]` / `[]` all type against `[A, B]` while a bare `undefined` in a
14
- * non-undefined slot stays an error (the footgun the `SKIP`/short-array split
15
- * removes); for a variable-length array of parents it's just that array. */
16
- export type BackUpdates<T extends readonly unknown[]> = number extends T["length"] ? T : T extends readonly [infer H, ...infer R] ? readonly [] | readonly [H, ...BackUpdates<R>] : readonly [];
17
1
  interface ReactiveNode {
18
2
  flags: number;
19
3
  deps: Link | undefined;
@@ -33,50 +17,66 @@ interface Link {
33
17
  prevDep: Link | undefined;
34
18
  nextDep: Link | undefined;
35
19
  }
20
+ interface LensLink {
21
+ index: number;
22
+ parent: Cell<unknown>;
23
+ child: Cell<unknown>;
24
+ /** Spliced into `parent.childEdges` yet? The down-list (`parentEdges`) is
25
+ * eager at construction; the up-list is lazy on first back-mark so the
26
+ * parent's child order is arm-order (co-writer resolution is last-write-wins). */
27
+ linked: boolean;
28
+ nextParent: LensLink | undefined;
29
+ prevChild: LensLink | undefined;
30
+ nextChild: LensLink | undefined;
31
+ }
36
32
  /** Install a hook fired on every source value-change; returns a restore fn. */
37
33
  export declare function setCellWriteHook(fn: ((cell: Cell<unknown>) => void) | undefined): () => void;
38
34
  export type MergeFold<T> = (values: readonly T[]) => T;
39
35
  declare class MergeNode<T> {
40
36
  readonly foldFn: MergeFold<T> | undefined;
41
- /** Contributions gathered as this merge's cone resolves; folded and cleared
42
- * in `foldMerge` (the merge-owned buffer, mutated in place). The parent it
43
- * writes to is just `b.parent` (a merge's `b.parent` IS its fold target), so
44
- * this node carries only the policy + buffer — no duplicate edge. */
37
+ /** Contributions gathered as the cone resolves; folded and cleared in `foldMerge`. */
45
38
  contributions: T[];
46
39
  constructor(fold: MergeFold<T> | undefined);
47
40
  }
48
41
  declare class BwdSpec {
49
- /** Backward target(s): one `Cell` (1→1 / merge) or `Cell[]` (multi-out). */
50
- parent: Cell<unknown> | Cell<unknown>[] | undefined;
51
- /** Lens `put` backward derivation (dual of `getter`). A 1→1 / multi-out
52
- * lens is called as `put(target)` (a source-reading lens reads the current
53
- * parent(s) at walk time, untracked); multi-out returns a per-parent update
54
- * array. Stateful is the spec's `bwd`, called `put(target, sources, c)`. */
42
+ /** Lens `put` (dual of `getter`): `put(target)` for 1→1 / multi-out (a
43
+ * source-reading lens reads its parents at walk time), `put(target, sources, c)`
44
+ * for stateful. `undefined` for a merge (folds) or pin (absorbs). */
55
45
  put: ((target: any, current?: any) => any) | undefined;
56
- /** Backward aggregation node; presence IS the merge-mode discriminant. */
46
+ /** Fold payload; present a fan-in merge. */
57
47
  merge: MergeNode<unknown> | undefined;
58
- /** Complement machinery; presence IS the stateful-mode discriminant. */
48
+ /** Complement state; present a complement-carrying (stateful) lens. */
59
49
  stateful: StatefulCore | undefined;
50
+ /** `put` yields a per-parent tuple (split / stateful) vs a scalar (1→1). The
51
+ * only discriminant not derivable from topology (a 1-parent split is a tuple). */
52
+ scatter: boolean;
60
53
  }
61
- /** Runtime state of a stateful (complement-carrying) lens the rare
62
- * backward mode, kept off `BwdSpec` so plain lenses don't carry its slots.
63
- * `put` (the spec's `bwd`) and `parent` stay on `BwdSpec`; this holds the
64
- * complement and the closures that project from / advance it. */
54
+ /** Runtime state of a symmetric-lens complement, kept off `BwdSpec` so plain
55
+ * lenses don't carry its slots. See the stateful-lens header for the theory
56
+ * (symmetric/edit lenses) and the version-stamp provenance. */
65
57
  declare class StatefulCore {
66
58
  /** Engine-owned memory the view discards. */
67
59
  complement: unknown;
68
- /** Advance the complement: `step(sources, complement, external)`. (The
69
- * forward projection `fwd` is captured directly in the getter closure — it
70
- * is only ever read there so it costs no slot here.) */
71
- step: (sources: any, complement: any, external: boolean) => any;
72
- /** Sources this lens last committed back (the own-vs-external test compares
73
- * live sources against these); `undefined` until the first back-write. A
74
- * back-write reads the live sources into a fresh array, builds the committed
75
- * candidate in place, and keeps it as `last` for the next own-vs-external
76
- * comparison. */
77
- last: unknown[] | undefined;
78
- constructor(complement: unknown, step: (sources: any, complement: any, external: boolean) => any);
60
+ /** Advance the complement: `step(sources, complement)`. Run only when the
61
+ * sources actually moved (the engine gates it; see the stateful header). */
62
+ step: (sources: any, complement: any) => any;
63
+ /** Sum of the parents' `version`s as of the last sync. Sources moved iff the
64
+ * live sum differs the lazy own-vs-external provenance that replaces a value
65
+ * witness. A read syncs it after stepping; a back-write re-stamps it post-order
66
+ * (own writes don't re-step, so `bwd` must leave the complement consistent).
67
+ * Seeded to `-1` (sums are 0) so the first use always folds the sources in. */
68
+ stamp: number;
69
+ constructor(complement: unknown, step: (sources: any, complement: any) => any);
79
70
  }
71
+ /** Multi-out / stateful back-write sentinel: "leave this parent untouched."
72
+ * Every non-`SKIP` slot is written verbatim, `undefined` included; a short array
73
+ * skips the trailing parents. (1→1 `put` always writes its one parent.) */
74
+ export declare const SKIP: unique symbol;
75
+ export type Skip = typeof SKIP;
76
+ /** Per-parent back-write result: any prefix of the update tuple, each slot a value
77
+ * or `SKIP` (so `[a]` / `[a, SKIP]` / `[]` all type against `[A, B]`, while a bare
78
+ * `undefined` in a non-undefined slot stays an error). */
79
+ export type BackUpdates<T extends readonly unknown[]> = number extends T["length"] ? T : T extends readonly [infer H, ...infer R] ? readonly [] | readonly [H, ...BackUpdates<R>] : readonly [];
80
80
  /** Plain T or any read-shape; snapshot via `readNow`, close via `reader`. */
81
81
  export type Val<T> = T | Read<T>;
82
82
  /** Covariant read-only surface. */
@@ -97,6 +97,16 @@ export type Writable<R> = R & WritableBrand & {
97
97
  };
98
98
  /** Strict factory input: a literal, or an existing `Writable<Cls>`. */
99
99
  export type Init<C extends Cell<any>> = Inner<C> | Writable<C>;
100
+ /** Per-position value types behind a tuple of read shapes (the tuple form of {@link Inner}). */
101
+ type ReadValues<P extends readonly Read<unknown>[]> = {
102
+ [K in keyof P]: Inner<P[K]>;
103
+ };
104
+ /** {@link ReadValues} with each slot also admitting `SKIP` — the per-parent back-update shape. */
105
+ type ReadValuesOrSkip<P extends readonly Read<unknown>[]> = {
106
+ [K in keyof P]: Inner<P[K]> | Skip;
107
+ };
108
+ /** Any `Cell` subclass constructor — the constraint for polymorphic-`this` statics. */
109
+ type AnyCellCtor = new (...args: never[]) => Cell<any>;
100
110
  /** Snapshot a `Val<T>` to plain `T` (one-shot, no tracking). */
101
111
  export declare function readNow<T>(v: Val<T>): T;
102
112
  /** Resolve a `Val<T>` to a `() => T` closure that unwraps on each call. */
@@ -116,6 +126,19 @@ export interface CellOptions<T = unknown> {
116
126
  unwatched?: () => void;
117
127
  /** Per-instance value equality; defaults to `Object.is`. */
118
128
  equals?: (a: T, b: T) => boolean;
129
+ /** Debug label; surfaces in cyclic-read errors and graph dumps (see debug.ts). */
130
+ name?: string;
131
+ }
132
+ /** A lens as a first-class value, unbound from any source: `get` projects A→B,
133
+ * `put` writes B back into an A. Apply with `cell.through(optic)`; build with
134
+ * `optic` / `iso` / `atKey` / `compose` (optic.ts). `readsSource` is `false`
135
+ * only for an `iso`, letting `through` bind a cheaper 1-arg backward. */
136
+ export interface Optic<A, B> {
137
+ readonly get: (a: A) => B;
138
+ readonly put: (b: B, a: A) => A;
139
+ readonly readsSource: boolean;
140
+ /** Compose with a following optic (this first, then `next`). */
141
+ through<C>(next: Optic<B, C>): Optic<A, C>;
119
142
  }
120
143
  export declare class Cell<T = unknown> implements ReactiveNode {
121
144
  /** @internal */
@@ -142,12 +165,27 @@ export declare class Cell<T = unknown> implements ReactiveNode {
142
165
  pendingValue: T;
143
166
  /** @internal Backward sidecar; `undefined` iff read-only. Writability is `_bwd !== undefined`. */
144
167
  _bwd: BwdSpec | undefined;
145
- /** @internal Backward dual of `subs`: direct lens-children for back-write cone traversal. */
146
- _lensSubs: Cell<unknown>[] | undefined;
168
+ /** @internal Lens-edges to my back-targets (down); dual of `deps`. `markDown`/
169
+ * `backResolve` descend this toward sources. Index-ordered. */
170
+ parentEdges: LensLink | undefined;
171
+ /** @internal */
172
+ parentEdgesTail: LensLink | undefined;
173
+ /** @internal Lens-edges to my lens-children (up); dual of `subs`. `resolveCone`
174
+ * ascends this toward the armed views. */
175
+ childEdges: LensLink | undefined;
176
+ /** @internal */
177
+ childEdgesTail: LensLink | undefined;
147
178
  /** @internal Backward flag word (`BF`), dual of forward `flags`. */
148
179
  bflags: number;
149
- /** @internal Guards against `linkBack` re-registering a duplicate in `_lensSubs`. */
150
- _linkedBack: boolean;
180
+ /** @internal Visit epoch for `backResolve`'s collect phase (dedups diamonds
181
+ * without a Set; compared against the global `backCycle`). */
182
+ bEpoch: number;
183
+ /** @internal Monotone committed-change counter. A stateful lens sums its
184
+ * parents' versions to detect "did my sources move since I last synced?" —
185
+ * the lazy provenance that replaces a value witness (see the stateful header). */
186
+ version: number;
187
+ /** Optional debug label (`cell(0, { name })`); used by errors and graph dumps. */
188
+ name: string | undefined;
151
189
  constructor(initial: T, opts?: CellOptions<T>);
152
190
  readonly value: T;
153
191
  /** @internal Single write-commit point; self-excludes the active network. */
@@ -165,48 +203,42 @@ export declare class Cell<T = unknown> implements ReactiveNode {
165
203
  /** Read-only same-type view: the RO dual of the endo `.lens`. For a cross-type view use the typed static
166
204
  * `Target.derive(src, fn)`. */
167
205
  derive(this: Cell<T>, fn: (v: T) => T): this;
168
- /** Backward fan-in node. Forward, the identity view of its parent;
169
- * backward, the convergence point where N contributors (upstream lenses
170
- * and direct writes) fold into one value for the parent. `fold` is handed
171
- * every live push at once; omitted, it is last-writer-wins. */
206
+ /** Apply optic value(s) as a writable lens: `c.through(o)` `lens(c, o.get,
207
+ * o.put)`; multiple optics compose left-to-right (`c.through(a, b)` = `a`
208
+ * then `b`). Cross-type, unlike the endomorphic instance `.lens`. */
209
+ through<B>(this: Cell<T>, o: Optic<T, B>): Writable<Cell<B>>;
210
+ through<B, C>(this: Cell<T>, o1: Optic<T, B>, o2: Optic<B, C>): Writable<Cell<C>>;
211
+ through<B, C, D>(this: Cell<T>, o1: Optic<T, B>, o2: Optic<B, C>, o3: Optic<C, D>): Writable<Cell<D>>;
212
+ /** Backward fan-in: forwards its parent's value unchanged; on write, folds N
213
+ * contributors into one value. `fold` defaults to last-writer-wins. */
172
214
  merge(this: Cell<T>, fold?: MergeFold<T>): Cell<T>;
173
215
  /** Read-only typed view. `Cls.derive(parent, fn)` (1-input),
174
216
  * `Cls.derive(parents, fn)` (N-input), or `Cls.derive(fn)` (closure).
175
217
  * Polymorphic-`this`: `Vec.derive(...)` → `Vec`. */
176
- static derive<C extends new (...args: never[]) => Cell<any>, P>(this: C, parent: Read<P>, fn: (v: P) => Inner<InstanceType<C>>): InstanceType<C>;
177
- static derive<C extends new (...args: never[]) => Cell<any>, P extends readonly Read<unknown>[]>(this: C, parents: P, fn: (vals: {
178
- [K in keyof P]: P[K] extends Read<infer V> ? V : never;
179
- }) => Inner<InstanceType<C>>): InstanceType<C>;
180
- static derive<C extends new (...args: never[]) => Cell<any>>(this: C, fn: () => Inner<InstanceType<C>>): InstanceType<C>;
218
+ static derive<C extends AnyCellCtor, P>(this: C, parent: Read<P>, fn: (v: P) => Inner<InstanceType<C>>): InstanceType<C>;
219
+ static derive<C extends AnyCellCtor, P extends readonly Read<unknown>[]>(this: C, parents: P, fn: (vals: ReadValues<P>) => Inner<InstanceType<C>>): InstanceType<C>;
220
+ static derive<C extends AnyCellCtor>(this: C, fn: () => Inner<InstanceType<C>>): InstanceType<C>;
181
221
  /** Writable lens. `Cls.lens(parent, fwd, bwd)` for one input,
182
222
  * `Cls.lens(parents, fwd, bwd)` for N; a 2-arg `bwd` reads the source,
183
223
  * a 1-arg `bwd` reconstructs it. `Cls.lens(parent(s), spec)` builds a
184
224
  * complement-carrying lens from `{ init, step, fwd, bwd }`. */
185
- static lens<C extends new (...args: never[]) => Cell<any>, P>(this: C, parent: Read<P>, fwd: (v: P) => Inner<InstanceType<C>>, bwd: (target: Inner<InstanceType<C>>, v: P) => P): Writable<InstanceType<C>>;
186
- static lens<C extends new (...args: never[]) => Cell<any>, P extends readonly Read<unknown>[]>(this: C, parents: P, fwd: (vals: {
187
- [K in keyof P]: P[K] extends Read<infer V> ? V : never;
188
- }) => Inner<InstanceType<C>>, bwd: (target: Inner<InstanceType<C>>, vals: {
189
- [K in keyof P]: P[K] extends Read<infer V> ? V : never;
190
- }) => BackUpdates<{
191
- [K in keyof P]: (P[K] extends Read<infer V> ? V : never) | Skip;
192
- }>): Writable<InstanceType<C>>;
193
- static lens<C extends new (...args: never[]) => Cell<any>, P, Cm>(this: C, parent: Read<P>, spec: StatefulLensSpec<readonly [P], Inner<InstanceType<C>>, Cm>): Writable<InstanceType<C>>;
194
- static lens<C extends new (...args: never[]) => Cell<any>, P extends readonly Read<unknown>[], Cm>(this: C, parents: P, spec: StatefulLensSpec<{
195
- [K in keyof P]: P[K] extends Read<infer V> ? V : never;
196
- }, Inner<InstanceType<C>>, Cm>): Writable<InstanceType<C>>;
225
+ static lens<C extends AnyCellCtor, P>(this: C, parent: Read<P>, fwd: (v: P) => Inner<InstanceType<C>>, bwd: (target: Inner<InstanceType<C>>, v: P) => P): Writable<InstanceType<C>>;
226
+ static lens<C extends AnyCellCtor, P extends readonly Read<unknown>[]>(this: C, parents: P, fwd: (vals: ReadValues<P>) => Inner<InstanceType<C>>, bwd: (target: Inner<InstanceType<C>>, vals: ReadValues<P>) => BackUpdates<ReadValuesOrSkip<P>>): Writable<InstanceType<C>>;
227
+ static lens<C extends AnyCellCtor, P, Cm>(this: C, parent: Read<P>, spec: StatefulLensSpec1<P, Inner<InstanceType<C>>, Cm>): Writable<InstanceType<C>>;
228
+ static lens<C extends AnyCellCtor, P extends readonly Read<unknown>[], Cm>(this: C, parents: P, spec: StatefulLensSpec<ReadValues<P>, Inner<InstanceType<C>>, Cm>): Writable<InstanceType<C>>;
197
229
  /** Type predicate against this class: `Vec.is(x)` narrows `x` to `Vec`.
198
230
  * Inherited static; works for any subclass via polymorphic `this`. */
199
- static is<C extends new (...args: never[]) => Cell<any>>(this: C, v: unknown): v is InstanceType<C>;
231
+ static is<C extends AnyCellCtor>(this: C, v: unknown): v is InstanceType<C>;
200
232
  /** Coerce `Val<Inner<Cls>>` → `Cls`: instance → identity, RO cell →
201
233
  * tracked `derive`, literal → fresh seed. */
202
- static coerce<C extends new (...args: never[]) => Cell<any>>(this: C, v: Val<Inner<InstanceType<C>>>): InstanceType<C>;
234
+ static coerce<C extends AnyCellCtor>(this: C, v: Val<Inner<InstanceType<C>>>): InstanceType<C>;
203
235
  /** Writable-shaped constant: always reads `v`, absorbs writes
204
236
  * (parentless sink lens), for APIs demanding bidirectionality. */
205
- static pin<C extends new (...args: never[]) => Cell<any>>(this: C, v: Inner<InstanceType<C>>): Writable<InstanceType<C>>;
237
+ static pin<C extends AnyCellCtor>(this: C, v: Inner<InstanceType<C>>): Writable<InstanceType<C>>;
206
238
  }
207
239
  /** Typed field lens onto `parent.value[key]`. RO parent → RO derive;
208
240
  * writable parent → bidirectional lens with spread-replace `put`. */
209
- export declare function fieldOf<C extends new (...args: never[]) => Cell<any>>(parent: Cell<any>, key: string | number | symbol, Cls: C): InstanceType<C>;
241
+ export declare function fieldOf<C extends AnyCellCtor>(parent: Cell<any>, key: string | number | symbol, Cls: C): InstanceType<C>;
210
242
  export interface StatefulBwd<S extends readonly unknown[], C> {
211
243
  /** Per-parent updates: a value (written verbatim, `undefined` included) or
212
244
  * `SKIP` to leave that parent. A short array skips the trailing parents. */
@@ -217,43 +249,53 @@ export interface StatefulBwd<S extends readonly unknown[], C> {
217
249
  }
218
250
  export interface StatefulLensSpec<S extends readonly unknown[], V, C> {
219
251
  init: (sources: S) => C;
220
- step: (sources: S, complement: C, external: boolean) => C;
252
+ /** Advance the complement on an outside change. Optional — defaults to `init`
253
+ * (the memoryless refresh); the engine runs it only when sources actually move. */
254
+ step?: (sources: S, complement: C) => C;
221
255
  fwd: (sources: S, complement: C) => V;
222
256
  bwd: (target: V, sources: S, complement: C) => StatefulBwd<S, C>;
223
257
  }
258
+ /** Single-source `bwd` result: a scalar `update` (or `SKIP`) plus the complement. */
259
+ export interface StatefulBwd1<S, C> {
260
+ update: S | Skip;
261
+ complement: C;
262
+ }
263
+ /** Single-source stateful spec — the scalar fast-path of `StatefulLensSpec`: one
264
+ * parent, so `init`/`step`/`fwd`/`bwd` take the source value directly, not a tuple. */
265
+ export interface StatefulLensSpec1<S, V, C> {
266
+ init: (source: S) => C;
267
+ step?: (source: S, complement: C) => C;
268
+ fwd: (source: S, complement: C) => V;
269
+ bwd: (target: V, source: S, complement: C) => StatefulBwd1<S, C>;
270
+ }
224
271
  /** Writable source; passes an existing `Writable` through (idempotent). */
225
272
  export declare function cell<T>(initial: T | Writable<Cell<T>>, opts?: CellOptions<T>): Writable<Cell<T>>;
226
273
  /** Untyped read-only view: `derive(parent, fn)`, `derive(parents, fn)`,
227
274
  * or `derive(fn)` (closure). */
228
275
  export declare function derive<P, R>(parent: Read<P>, fn: (v: P) => R): Cell<R>;
229
- export declare function derive<P extends readonly Read<unknown>[], R>(parents: P, fn: (vals: {
230
- [K in keyof P]: P[K] extends Read<infer V> ? V : never;
231
- }) => R): Cell<R>;
276
+ export declare function derive<P extends readonly Read<unknown>[], R>(parents: P, fn: (vals: ReadValues<P>) => R): Cell<R>;
232
277
  export declare function derive<R>(fn: () => R): Cell<R>;
233
278
  /** Untyped lens, inferring `R` from the closures. A 2-arg `bwd` reads the
234
279
  * source, a 1-arg `bwd` reconstructs it; `lens(parent(s), spec)` builds a
235
280
  * complement-carrying lens. */
236
281
  export declare function lens<P, R>(parent: Read<P>, fwd: (v: P) => R, bwd: (target: R, v: P) => P): Writable<Cell<R>>;
237
- export declare function lens<P extends readonly Read<unknown>[], R>(parents: P, fwd: (vals: {
238
- [K in keyof P]: P[K] extends Read<infer V> ? V : never;
282
+ export declare function lens<P extends readonly Read<unknown>[], R>(parents: P, fwd: (vals: ReadValues<P>) => R, bwd: (target: R, vals: ReadValues<P>) => ReadValuesOrSkip<P>): Writable<Cell<R>>;
283
+ export declare function lens<S extends Record<string, Read<unknown>>, R>(parents: S, fwd: (vals: {
284
+ [K in keyof S]: Inner<S[K]>;
239
285
  }) => R, bwd: (target: R, vals: {
240
- [K in keyof P]: P[K] extends Read<infer V> ? V : never;
241
- }) => {
242
- [K in keyof P]: (P[K] extends Read<infer V> ? V : never) | Skip;
243
- }): Writable<Cell<R>>;
244
- export declare function lens<P, R, C>(parent: Read<P>, spec: StatefulLensSpec<readonly [P], R, C>): Writable<Cell<R>>;
245
- export declare function lens<P extends readonly Read<unknown>[], R, C>(parents: P, spec: StatefulLensSpec<{
246
- [K in keyof P]: P[K] extends Read<infer V> ? V : never;
247
- }, R, C>): Writable<Cell<R>>;
286
+ [K in keyof S]: Inner<S[K]>;
287
+ }) => Partial<{
288
+ [K in keyof S]: Inner<S[K]> | Skip;
289
+ }>): Writable<Cell<R>>;
290
+ export declare function lens<P, R, C>(parent: Read<P>, spec: StatefulLensSpec1<P, R, C>): Writable<Cell<R>>;
291
+ export declare function lens<P extends readonly Read<unknown>[], R, C>(parents: P, spec: StatefulLensSpec<ReadValues<P>, R, C>): Writable<Cell<R>>;
248
292
  export declare function effect(fn: () => (() => void) | void): () => void;
249
- /** Run all pending effects NOW, synchronously. The escape hatch for code (tests,
250
- * imperative call sites) that must observe effect side-effects before yielding
251
- * to the microtask queue. Reads never need it — they pull current values. */
293
+ /** Run all pending effects now, synchronously the escape hatch for code that
294
+ * must observe effect side-effects before yielding. Reads never need it. */
252
295
  export declare function settle(): void;
253
- /** Group writes and flush effects SYNCHRONOUSLY at the end of `fn` — a sync
254
- * barrier. Effects coalesce on the microtask turn anyway (see `schedule`), so
255
- * `batch` is no longer needed for that; reach for it only when you must run the
256
- * woken effects before the call returns (and don't want a `settle()`). */
296
+ /** Group writes and flush effects synchronously at the end of `fn`. Effects
297
+ * coalesce on the microtask turn anyway; reach for `batch` only to run the woken
298
+ * effects before the call returns. */
257
299
  export declare function batch<R>(fn: () => R): R;
258
300
  export declare function untracked<R>(fn: () => R): R;
259
301
  /** Handle to a `network` invocation. */
@@ -267,34 +309,28 @@ export interface Network {
267
309
  /** Remove cells from the topology (idempotent; does NOT fire). */
268
310
  unsubscribe(...cells: Cell<any>[]): void;
269
311
  }
270
- /** Build a reactive sub-DAG node with explicit topology. The body fires
271
- * when any subscribed dep changes (`dirty` = the changed subset), runs
272
- * inside `batch()`, and self-excludes its own writes. Topology is the
273
- * deps array + later subscribe/unsubscribe (body reads add no deps).
274
- * `flush()` from inside the body throws; `manual: true` defers
275
- * auto-firing so only `flush()` advances. */
276
- export declare function network(deps: readonly Cell<any>[], body: (dirty: ReadonlySet<Cell<unknown>>, handle: Network) => void, opts?: {
312
+ type NetworkBody = (dirty: ReadonlySet<Cell<unknown>>, handle: Network) => void;
313
+ /** Build a reactive sub-DAG. The body fires when any subscribed dep changes
314
+ * (`dirty` = the changed subset), self-excludes its own writes, and (auto mode)
315
+ * resolves synchronously. `manual: true` defers firing so only `flush()` advances;
316
+ * `flush()` from inside the body throws. Network-specific state (last-values,
317
+ * handle) lives in this closure, so the shared `Effect` carries none of it. */
318
+ export declare function network(deps: readonly Cell<any>[], body: NetworkBody, opts?: {
277
319
  manual?: boolean;
278
320
  }): Network;
279
- /** Bidirectional field lens onto `parent.value[key]`; write spread-
280
- * replaces the composite. Cached per (instance, key). Return type is
281
- * conditional: `Writable<Cls>` on a writable parent, bare `Cls` on RO.
321
+ /** Bidirectional field lens onto `parent.value[key]` (write spread-replaces),
322
+ * cached per (instance, key). `Writable<Cls>` on a writable parent, bare `Cls` on RO.
282
323
  *
283
324
  * get x() { return fieldLens(this, "x", Num); } */
284
325
  export declare function fieldLens<S extends Cell<any>, K extends keyof Inner<S>, C extends new (...args: never[]) => Cell<Inner<S>[K]>>(parent: S, key: K, Cls: C): S extends WritableBrand ? Writable<InstanceType<C>> : InstanceType<C>;
285
326
  /** Read-only derived view via `Cls.derive(parent, fn)`, memoized per
286
- * (instance, key); always bare `Cls` (RO). The cache is the point — the
287
- * getter form, not a new kind of cell.
327
+ * (instance, key).
288
328
  *
289
329
  * get magnitude() {
290
330
  * return cachedDerive(this, "magnitude", Num, v => Math.hypot(v.x, v.y));
291
331
  * } */
292
- export declare function cachedDerive<S extends Cell<any>, C extends new (...args: never[]) => Cell<any>>(parent: S, key: string | symbol, Cls: C, fn: (v: Inner<S>) => Inner<InstanceType<C>>): InstanceType<C>;
293
- /** Every cell `s` transitively depends on, including itself. Raw cells
294
- * return `{s}`; lens chains return the chain plus all parents. BFS,
295
- * peeking each Computed to populate deps; the `seen` set breaks cycles.
296
- * Used by `Propagators` to expand declared reads into their transitive
297
- * parent set. Inspection is safe: it only reads engine state and peeks
298
- * `.value` (idempotent for lazy Computeds). */
332
+ export declare function cachedDerive<S extends Cell<any>, C extends AnyCellCtor>(parent: S, key: string | symbol, Cls: C, fn: (v: Inner<S>) => Inner<InstanceType<C>>): InstanceType<C>;
333
+ /** Every cell `s` transitively depends on, including itself (BFS, peeking each
334
+ * computed to populate deps; `seen` breaks cycles). */
299
335
  export declare function transitiveDeps(s: Cell<unknown>): Set<Cell<unknown>>;
300
336
  export {};