bireactive 0.2.4 → 0.3.0
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.
- package/dist/animation/anim.js +4 -0
- package/dist/coll.d.ts +7 -7
- package/dist/core/cell.d.ts +89 -66
- package/dist/core/cell.js +642 -401
- package/dist/core/index.d.ts +4 -14
- package/dist/core/index.js +4 -14
- package/dist/core/lenses/aggregates.d.ts +1 -1
- package/dist/core/lenses/aggregates.js +4 -3
- package/dist/core/lenses/closed-form-policies.js +6 -6
- package/dist/core/lenses/decompositions.js +3 -3
- package/dist/core/lenses/domain-aggregates.js +5 -5
- package/dist/core/lenses/geometry.d.ts +1 -1
- package/dist/core/lenses/geometry.js +6 -7
- package/dist/core/lenses/memory.d.ts +2 -2
- package/dist/core/lenses/memory.js +3 -3
- package/dist/core/lenses/typed-factor.js +4 -3
- package/dist/core/traits.d.ts +1 -0
- package/dist/core/values/box.js +7 -7
- package/dist/core/values/color.js +5 -5
- package/dist/core/values/field.d.ts +70 -0
- package/dist/core/values/field.js +230 -0
- package/dist/core/values/gpu.d.ts +4 -2
- package/dist/core/values/gpu.js +11 -4
- package/dist/core/values/matrix.js +7 -7
- package/dist/core/values/num.d.ts +1 -1
- package/dist/core/values/num.js +1 -1
- package/dist/core/values/pose.js +4 -4
- package/dist/core/values/range.js +6 -6
- package/dist/core/values/template.d.ts +1 -1
- package/dist/core/values/template.js +2 -1
- package/dist/core/values/transform.js +7 -7
- package/dist/core/values/tri.js +3 -3
- package/dist/core/values/vec.js +8 -12
- package/dist/ext/timeline.js +2 -2
- package/dist/formats/cst.d.ts +127 -0
- package/dist/formats/cst.js +280 -0
- package/dist/formats/edn.d.ts +2 -0
- package/dist/formats/edn.js +301 -0
- package/dist/formats/index.d.ts +6 -0
- package/dist/formats/index.js +8 -0
- package/dist/formats/json.d.ts +2 -0
- package/dist/formats/json.js +332 -0
- package/dist/formats/lens.d.ts +8 -0
- package/dist/formats/lens.js +54 -0
- package/dist/formats/toml.d.ts +2 -0
- package/dist/formats/toml.js +526 -0
- package/dist/formats/yaml.d.ts +2 -0
- package/dist/formats/yaml.js +661 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/learn/data.d.ts +49 -0
- package/dist/learn/data.js +181 -0
- package/dist/learn/index.d.ts +3 -0
- package/dist/learn/index.js +6 -0
- package/dist/learn/lens-net.d.ts +63 -0
- package/dist/learn/lens-net.js +219 -0
- package/dist/learn/mlp.d.ts +77 -0
- package/dist/learn/mlp.js +292 -0
- package/dist/propagators/csp.d.ts +13 -0
- package/dist/propagators/csp.js +52 -0
- package/dist/propagators/flex.d.ts +31 -0
- package/dist/propagators/flex.js +189 -0
- package/dist/propagators/graph.d.ts +73 -0
- package/dist/propagators/graph.js +543 -0
- package/dist/propagators/index.d.ts +8 -6
- package/dist/propagators/index.js +15 -6
- package/dist/propagators/lattice.d.ts +45 -0
- package/dist/propagators/lattice.js +113 -0
- package/dist/propagators/layout.d.ts +1 -27
- package/dist/propagators/layout.js +6 -175
- package/dist/propagators/numeric.d.ts +17 -0
- package/dist/propagators/numeric.js +93 -0
- package/dist/propagators/solver.d.ts +51 -0
- package/dist/propagators/solver.js +175 -0
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/lens.d.ts +121 -0
- package/dist/schema/lens.js +429 -0
- package/dist/shapes/annular-sector.js +4 -4
- package/dist/shapes/button.js +1 -1
- package/dist/shapes/circle.js +1 -1
- package/dist/shapes/handle.js +2 -2
- package/dist/shapes/label.js +1 -1
- package/dist/shapes/layout.js +2 -2
- package/dist/shapes/rect.js +7 -7
- package/dist/shapes/shape.js +8 -8
- package/dist/web/diagram.js +2 -2
- package/package.json +1 -1
- package/dist/propagators/network.d.ts +0 -52
- package/dist/propagators/network.js +0 -185
- package/dist/propagators/propagator.d.ts +0 -12
- package/dist/propagators/propagator.js +0 -16
- package/dist/propagators/range.d.ts +0 -45
- package/dist/propagators/range.js +0 -147
- package/dist/propagators/relations.d.ts +0 -60
- package/dist/propagators/relations.js +0 -343
package/dist/animation/anim.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
//
|
|
12
12
|
// T (generic), if the suspend is `(wake, spawn) => T`
|
|
13
13
|
// Example: `const result = yield (wake, spawn) => { ... }`
|
|
14
|
+
import { settle } from "../core/cell.js";
|
|
14
15
|
/** Cut sentinel — return `cut(v)` from a concurrent kid to settle the
|
|
15
16
|
* enclosing group with `v` and cancel siblings. Outside a group, the
|
|
16
17
|
* sentinel is transparently unwrapped to `v`. */
|
|
@@ -77,6 +78,9 @@ export class Anim {
|
|
|
77
78
|
}
|
|
78
79
|
}
|
|
79
80
|
}
|
|
81
|
+
// A frame advances reactive state; flush the effects it woke so observers
|
|
82
|
+
// (and the next frame) see this frame's results synchronously.
|
|
83
|
+
settle();
|
|
80
84
|
}
|
|
81
85
|
stepInner(dt) {
|
|
82
86
|
if (dt > 0 && Number.isFinite(dt))
|
package/dist/coll.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Cell, type Read, type Writable } from "./core/index.js";
|
|
2
2
|
/** Accessor for an element's writable field cell. Forward reads `.value`;
|
|
3
3
|
* the backward pass writes it. */
|
|
4
|
-
export type
|
|
4
|
+
export type Accessor<E, V> = (e: E) => Writable<Cell<V>>;
|
|
5
5
|
/** A forward test over an element's fields, optionally assertable —
|
|
6
6
|
* `assert(e)` makes the test pass by writing fields. */
|
|
7
7
|
export interface FieldPred<E> {
|
|
@@ -16,10 +16,10 @@ export interface GroupOpts<E, K> {
|
|
|
16
16
|
/** Fixed key order; seeds empty buckets and pins column order. */
|
|
17
17
|
order?: readonly K[];
|
|
18
18
|
/** Order field within each group; enables `move(e, key, index)`. */
|
|
19
|
-
sort?:
|
|
19
|
+
sort?: Accessor<E, number>;
|
|
20
20
|
}
|
|
21
21
|
/** `field === value`, assertable by writing the field. */
|
|
22
|
-
export declare function is<E, V>(field:
|
|
22
|
+
export declare function is<E, V>(field: Accessor<E, V>, value: V): FieldPred<E>;
|
|
23
23
|
/** Conjunction; asserts every clause. */
|
|
24
24
|
export declare function allPass<E>(...preds: readonly FieldPred<E>[]): FieldPred<E>;
|
|
25
25
|
/** Read-only projection with chainable structural lenses. */
|
|
@@ -36,8 +36,8 @@ export declare class View<E> {
|
|
|
36
36
|
assertContains(e: E): void;
|
|
37
37
|
protected assertSelf(_e: E): void;
|
|
38
38
|
filter(pred: FieldPred<E>): View<E>;
|
|
39
|
-
sortBy(field:
|
|
40
|
-
groupBy<K>(field:
|
|
39
|
+
sortBy(field: Accessor<E, number>): SortView<E>;
|
|
40
|
+
groupBy<K>(field: Accessor<E, K>, opts?: GroupOpts<E, K>): GroupView<K, E>;
|
|
41
41
|
map<F>(f: (e: E) => F): Read<readonly F[]>;
|
|
42
42
|
/** Remove `e` from the source. */
|
|
43
43
|
remove(e: E): void;
|
|
@@ -53,7 +53,7 @@ export declare class Coll<E> extends View<E> {
|
|
|
53
53
|
/** Sorted view. `move` writes the order field between the drop neighbours. */
|
|
54
54
|
export declare class SortView<E> extends View<E> {
|
|
55
55
|
#private;
|
|
56
|
-
constructor(parent: View<E>, field:
|
|
56
|
+
constructor(parent: View<E>, field: Accessor<E, number>);
|
|
57
57
|
move(e: E, to: number): void;
|
|
58
58
|
}
|
|
59
59
|
/** Grouped view. `move`/`insert` write the group field (and, with a `sort`
|
|
@@ -61,7 +61,7 @@ export declare class SortView<E> extends View<E> {
|
|
|
61
61
|
export declare class GroupView<K, E> {
|
|
62
62
|
#private;
|
|
63
63
|
readonly groups: Read<readonly Group<K, E>[]>;
|
|
64
|
-
constructor(parent: View<E>, field:
|
|
64
|
+
constructor(parent: View<E>, field: Accessor<E, K>, opts?: GroupOpts<E, K>);
|
|
65
65
|
get value(): readonly Group<K, E>[];
|
|
66
66
|
map<F>(f: (g: Group<K, E>) => F): Read<readonly F[]>;
|
|
67
67
|
/** Place `e` in group `toKey` at `index`. Inserts it into the source if
|
package/dist/core/cell.d.ts
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
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 [];
|
|
1
17
|
interface ReactiveNode {
|
|
2
18
|
flags: number;
|
|
3
19
|
deps: Link | undefined;
|
|
@@ -19,39 +35,28 @@ interface Link {
|
|
|
19
35
|
}
|
|
20
36
|
/** Install a hook fired on every source value-change; returns a restore fn. */
|
|
21
37
|
export declare function setCellWriteHook(fn: ((cell: Cell<unknown>) => void) | undefined): () => void;
|
|
22
|
-
export
|
|
23
|
-
readonly identity: T;
|
|
24
|
-
combine(acc: T, x: T): T;
|
|
25
|
-
/** Optional inverse for incremental fold. */
|
|
26
|
-
remove?(acc: T, x: T): T;
|
|
27
|
-
}
|
|
28
|
-
export declare const DIRECT_SLOT: unique symbol;
|
|
38
|
+
export type MergeFold<T> = (values: readonly T[]) => T;
|
|
29
39
|
declare class MergeNode<T> {
|
|
30
|
-
readonly
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
fold(): T;
|
|
38
|
-
reset(): void;
|
|
40
|
+
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. */
|
|
45
|
+
contributions: T[];
|
|
46
|
+
constructor(fold: MergeFold<T> | undefined);
|
|
39
47
|
}
|
|
40
48
|
declare class BwdSpec {
|
|
41
49
|
/** Backward target(s): one `Cell` (1→1 / merge) or `Cell[]` (multi-out). */
|
|
42
50
|
parent: Cell<unknown> | Cell<unknown>[] | undefined;
|
|
43
|
-
/** Lens `put` — backward derivation (dual of `getter`).
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
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)`. */
|
|
47
55
|
put: ((target: any, current?: any) => any) | undefined;
|
|
48
56
|
/** Backward aggregation node; presence IS the merge-mode discriminant. */
|
|
49
57
|
merge: MergeNode<unknown> | undefined;
|
|
50
58
|
/** Complement machinery; presence IS the stateful-mode discriminant. */
|
|
51
59
|
stateful: StatefulCore | undefined;
|
|
52
|
-
/** Index in `bwdQueue` of this cell's latest push; the drain skips stale
|
|
53
|
-
* entries so each cell propagates backward once per flush, last-write. */
|
|
54
|
-
queueIdx: number;
|
|
55
60
|
}
|
|
56
61
|
/** Runtime state of a stateful (complement-carrying) lens — the rare
|
|
57
62
|
* backward mode, kept off `BwdSpec` so plain lenses don't carry its slots.
|
|
@@ -60,14 +65,17 @@ declare class BwdSpec {
|
|
|
60
65
|
declare class StatefulCore {
|
|
61
66
|
/** Engine-owned memory the view discards. */
|
|
62
67
|
complement: unknown;
|
|
63
|
-
/**
|
|
64
|
-
|
|
65
|
-
|
|
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.) */
|
|
66
71
|
step: (sources: any, complement: any, external: boolean) => any;
|
|
67
|
-
/**
|
|
68
|
-
* until the first back-write.
|
|
69
|
-
|
|
70
|
-
|
|
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);
|
|
71
79
|
}
|
|
72
80
|
/** Plain T or any read-shape; snapshot via `readNow`, close via `reader`. */
|
|
73
81
|
export type Val<T> = T | Read<T>;
|
|
@@ -110,52 +118,58 @@ export interface CellOptions<T = unknown> {
|
|
|
110
118
|
equals?: (a: T, b: T) => boolean;
|
|
111
119
|
}
|
|
112
120
|
export declare class Cell<T = unknown> implements ReactiveNode {
|
|
121
|
+
/** @internal */
|
|
113
122
|
flags: number;
|
|
123
|
+
/** @internal */
|
|
114
124
|
subs: Link | undefined;
|
|
125
|
+
/** @internal */
|
|
115
126
|
subsTail: Link | undefined;
|
|
127
|
+
/** @internal */
|
|
116
128
|
deps: Link | undefined;
|
|
129
|
+
/** @internal */
|
|
117
130
|
depsTail: Link | undefined;
|
|
118
|
-
/** Forward derivation (computed/lens/merge). `undefined` ⇒ source. */
|
|
131
|
+
/** @internal Forward derivation (computed/lens/merge). `undefined` ⇒ source. */
|
|
119
132
|
getter: (() => T) | undefined;
|
|
120
|
-
/** Per-instance equality
|
|
121
|
-
* construction) so hot paths call it without an `undefined` branch. */
|
|
133
|
+
/** @internal Per-instance equality; always defined (defaults to `Object.is`). */
|
|
122
134
|
_equals: (a: T, b: T) => boolean;
|
|
123
|
-
/** First-subscriber / last-subscriber lifecycle hooks. */
|
|
135
|
+
/** @internal First-subscriber / last-subscriber lifecycle hooks. */
|
|
124
136
|
_watched: (() => void) | undefined;
|
|
137
|
+
/** @internal */
|
|
125
138
|
_unwatchedHook: (() => void) | undefined;
|
|
126
|
-
/** Source:
|
|
127
|
-
* Getter cell: `currentValue` = last derived cache, `pendingValue`
|
|
128
|
-
* reused as the deferred backward target (see `set value`). The two
|
|
129
|
-
* roles never coexist, so two fields suffice for four. */
|
|
139
|
+
/** @internal Source: committed value + staged write. */
|
|
130
140
|
currentValue: T;
|
|
141
|
+
/** @internal */
|
|
131
142
|
pendingValue: T;
|
|
132
|
-
/** Backward sidecar
|
|
133
|
-
* `undefined` for a read-only cell (source or computed). Allocated only
|
|
134
|
-
* for writable derived cells, keeping the common node lean. Writability
|
|
135
|
-
* is exactly `_bwd !== undefined`. See `BwdSpec`. */
|
|
143
|
+
/** @internal Backward sidecar; `undefined` iff read-only. Writability is `_bwd !== undefined`. */
|
|
136
144
|
_bwd: BwdSpec | undefined;
|
|
145
|
+
/** @internal Backward dual of `subs`: direct lens-children for back-write cone traversal. */
|
|
146
|
+
_lensSubs: Cell<unknown>[] | undefined;
|
|
147
|
+
/** @internal Backward flag word (`BF`), dual of forward `flags`. */
|
|
148
|
+
bflags: number;
|
|
149
|
+
/** @internal Guards against `linkBack` re-registering a duplicate in `_lensSubs`. */
|
|
150
|
+
_linkedBack: boolean;
|
|
137
151
|
constructor(initial: T, opts?: CellOptions<T>);
|
|
138
152
|
readonly value: T;
|
|
139
|
-
|
|
140
|
-
/** Source write (alien's signal setter). Self-excludes the active
|
|
141
|
-
* network so a body writing its own dep doesn't re-trigger itself. */
|
|
153
|
+
/** @internal Single write-commit point; self-excludes the active network. */
|
|
142
154
|
_writeSource(next: T): void;
|
|
155
|
+
/** @internal */
|
|
143
156
|
_update(): boolean;
|
|
157
|
+
/** @internal */
|
|
144
158
|
_notify(): void;
|
|
159
|
+
/** @internal */
|
|
145
160
|
_unwatched(): void;
|
|
146
161
|
peek(): T;
|
|
147
|
-
/** Guard: silent coercion to string/number is almost always a bug. */
|
|
148
|
-
[Symbol.toPrimitive](hint: string): never;
|
|
149
162
|
/** Endomorphic lens. A 2-arg `bwd(view, current)` consults the current
|
|
150
163
|
* source; a 1-arg `bwd(view)` reconstructs it from the view alone. */
|
|
151
164
|
lens(this: Cell<T>, fwd: (v: T) => T, bwd: (target: T, current: T) => T): this;
|
|
152
165
|
/** Read-only same-type view: the RO dual of the endo `.lens`. For a cross-type view use the typed static
|
|
153
166
|
* `Target.derive(src, fn)`. */
|
|
154
167
|
derive(this: Cell<T>, fn: (v: T) => T): this;
|
|
155
|
-
/** Backward-
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
|
|
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. */
|
|
172
|
+
merge(this: Cell<T>, fold?: MergeFold<T>): Cell<T>;
|
|
159
173
|
/** Read-only typed view. `Cls.derive(parent, fn)` (1-input),
|
|
160
174
|
* `Cls.derive(parents, fn)` (N-input), or `Cls.derive(fn)` (closure).
|
|
161
175
|
* Polymorphic-`this`: `Vec.derive(...)` → `Vec`. */
|
|
@@ -173,9 +187,9 @@ export declare class Cell<T = unknown> implements ReactiveNode {
|
|
|
173
187
|
[K in keyof P]: P[K] extends Read<infer V> ? V : never;
|
|
174
188
|
}) => Inner<InstanceType<C>>, bwd: (target: Inner<InstanceType<C>>, vals: {
|
|
175
189
|
[K in keyof P]: P[K] extends Read<infer V> ? V : never;
|
|
176
|
-
}) => {
|
|
177
|
-
[K in keyof P]
|
|
178
|
-
}): Writable<InstanceType<C>>;
|
|
190
|
+
}) => BackUpdates<{
|
|
191
|
+
[K in keyof P]: (P[K] extends Read<infer V> ? V : never) | Skip;
|
|
192
|
+
}>): Writable<InstanceType<C>>;
|
|
179
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>>;
|
|
180
194
|
static lens<C extends new (...args: never[]) => Cell<any>, P extends readonly Read<unknown>[], Cm>(this: C, parents: P, spec: StatefulLensSpec<{
|
|
181
195
|
[K in keyof P]: P[K] extends Read<infer V> ? V : never;
|
|
@@ -183,21 +197,22 @@ export declare class Cell<T = unknown> implements ReactiveNode {
|
|
|
183
197
|
/** Type predicate against this class: `Vec.is(x)` narrows `x` to `Vec`.
|
|
184
198
|
* Inherited static; works for any subclass via polymorphic `this`. */
|
|
185
199
|
static is<C extends new (...args: never[]) => Cell<any>>(this: C, v: unknown): v is InstanceType<C>;
|
|
186
|
-
/**
|
|
200
|
+
/** Coerce `Val<Inner<Cls>>` → `Cls`: instance → identity, RO cell →
|
|
187
201
|
* tracked `derive`, literal → fresh seed. */
|
|
188
|
-
static
|
|
202
|
+
static coerce<C extends new (...args: never[]) => Cell<any>>(this: C, v: Val<Inner<InstanceType<C>>>): InstanceType<C>;
|
|
189
203
|
/** Writable-shaped constant: always reads `v`, absorbs writes
|
|
190
204
|
* (parentless sink lens), for APIs demanding bidirectionality. */
|
|
191
205
|
static pin<C extends new (...args: never[]) => Cell<any>>(this: C, v: Inner<InstanceType<C>>): Writable<InstanceType<C>>;
|
|
192
|
-
/** Typed field lens onto `parent.value[key]`. A read-only computed
|
|
193
|
-
* parent yields a RO derive view; any writable parent yields a
|
|
194
|
-
* bidirectional field lens with spread-replace `put`. */
|
|
195
|
-
static fieldOf<C extends new (...args: never[]) => Cell<any>>(parent: Cell<any>, key: string | number | symbol, Cls: C): InstanceType<C>;
|
|
196
206
|
}
|
|
207
|
+
/** Typed field lens onto `parent.value[key]`. RO parent → RO derive;
|
|
208
|
+
* 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>;
|
|
197
210
|
export interface StatefulBwd<S extends readonly unknown[], C> {
|
|
198
|
-
updates:
|
|
199
|
-
|
|
200
|
-
|
|
211
|
+
/** Per-parent updates: a value (written verbatim, `undefined` included) or
|
|
212
|
+
* `SKIP` to leave that parent. A short array skips the trailing parents. */
|
|
213
|
+
updates: BackUpdates<{
|
|
214
|
+
[K in keyof S]: S[K] | Skip;
|
|
215
|
+
}>;
|
|
201
216
|
complement: C;
|
|
202
217
|
}
|
|
203
218
|
export interface StatefulLensSpec<S extends readonly unknown[], V, C> {
|
|
@@ -224,13 +239,21 @@ export declare function lens<P extends readonly Read<unknown>[], R>(parents: P,
|
|
|
224
239
|
}) => R, bwd: (target: R, vals: {
|
|
225
240
|
[K in keyof P]: P[K] extends Read<infer V> ? V : never;
|
|
226
241
|
}) => {
|
|
227
|
-
[K in keyof P]
|
|
242
|
+
[K in keyof P]: (P[K] extends Read<infer V> ? V : never) | Skip;
|
|
228
243
|
}): Writable<Cell<R>>;
|
|
229
244
|
export declare function lens<P, R, C>(parent: Read<P>, spec: StatefulLensSpec<readonly [P], R, C>): Writable<Cell<R>>;
|
|
230
245
|
export declare function lens<P extends readonly Read<unknown>[], R, C>(parents: P, spec: StatefulLensSpec<{
|
|
231
246
|
[K in keyof P]: P[K] extends Read<infer V> ? V : never;
|
|
232
247
|
}, R, C>): Writable<Cell<R>>;
|
|
233
248
|
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. */
|
|
252
|
+
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()`). */
|
|
234
257
|
export declare function batch<R>(fn: () => R): R;
|
|
235
258
|
export declare function untracked<R>(fn: () => R): R;
|
|
236
259
|
/** Handle to a `network` invocation. */
|
|
@@ -257,8 +280,8 @@ export declare function network(deps: readonly Cell<any>[], body: (dirty: Readon
|
|
|
257
280
|
* replaces the composite. Cached per (instance, key). Return type is
|
|
258
281
|
* conditional: `Writable<Cls>` on a writable parent, bare `Cls` on RO.
|
|
259
282
|
*
|
|
260
|
-
* get x() { return
|
|
261
|
-
export declare function
|
|
283
|
+
* get x() { return fieldLens(this, "x", Num); } */
|
|
284
|
+
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>;
|
|
262
285
|
/** Read-only derived view via `Cls.derive(parent, fn)`, memoized per
|
|
263
286
|
* (instance, key); always bare `Cls` (RO). The cache is the point — the
|
|
264
287
|
* getter form, not a new kind of cell.
|