bireactive 0.2.0 → 0.2.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 (82) hide show
  1. package/README.md +7 -7
  2. package/dist/{core/anim.d.ts → animation/animators.d.ts} +5 -3
  3. package/dist/{core/anim.js → animation/animators.js} +8 -5
  4. package/dist/animation/index.d.ts +1 -0
  5. package/dist/animation/index.js +1 -0
  6. package/dist/constraints/cluster.js +1 -1
  7. package/dist/constraints/expose.d.ts +17 -0
  8. package/dist/constraints/expose.js +61 -0
  9. package/dist/constraints/index.d.ts +1 -0
  10. package/dist/constraints/index.js +1 -0
  11. package/dist/constraints/linalg.d.ts +1 -8
  12. package/dist/constraints/linalg.js +5 -108
  13. package/dist/core/{signal.d.ts → cell.d.ts} +29 -6
  14. package/dist/core/{signal.js → cell.js} +134 -53
  15. package/dist/core/derived-geometry.d.ts +11 -0
  16. package/dist/core/derived-geometry.js +32 -0
  17. package/dist/core/index.d.ts +5 -10
  18. package/dist/core/index.js +5 -10
  19. package/dist/core/{aggregates.d.ts → lenses/aggregates.d.ts} +3 -14
  20. package/dist/core/{aggregates.js → lenses/aggregates.js} +5 -78
  21. package/dist/core/lenses/closed-form-policies.d.ts +6 -13
  22. package/dist/core/lenses/closed-form-policies.js +14 -24
  23. package/dist/core/lenses/decompositions.d.ts +14 -0
  24. package/dist/core/lenses/decompositions.js +224 -0
  25. package/dist/core/lenses/domain-aggregates.d.ts +10 -22
  26. package/dist/core/lenses/domain-aggregates.js +25 -39
  27. package/dist/core/{new-primitives.d.ts → lenses/geometry.d.ts} +11 -14
  28. package/dist/core/{new-primitives.js → lenses/geometry.js} +23 -37
  29. package/dist/core/lenses/index.d.ts +6 -4
  30. package/dist/core/lenses/index.js +6 -15
  31. package/dist/core/lenses/typed-factor.d.ts +1 -6
  32. package/dist/core/lenses/typed-factor.js +12 -114
  33. package/dist/core/{network-utils.d.ts → lifecycle.d.ts} +1 -1
  34. package/dist/core/{network-utils.js → lifecycle.js} +2 -2
  35. package/dist/core/linalg.d.ts +10 -0
  36. package/dist/core/linalg.js +109 -0
  37. package/dist/core/values/anchor.d.ts +1 -1
  38. package/dist/core/values/audio.d.ts +1 -1
  39. package/dist/core/values/audio.js +1 -1
  40. package/dist/core/values/bool.d.ts +1 -1
  41. package/dist/core/values/bool.js +1 -1
  42. package/dist/core/values/box.d.ts +2 -3
  43. package/dist/core/values/box.js +5 -6
  44. package/dist/core/values/canvas.d.ts +1 -1
  45. package/dist/core/values/canvas.js +2 -3
  46. package/dist/core/values/color.d.ts +2 -3
  47. package/dist/core/values/color.js +3 -4
  48. package/dist/core/values/flags.d.ts +1 -1
  49. package/dist/core/values/flags.js +1 -1
  50. package/dist/core/values/matrix.d.ts +1 -1
  51. package/dist/core/values/matrix.js +2 -3
  52. package/dist/core/values/num.d.ts +8 -3
  53. package/dist/core/values/num.js +22 -2
  54. package/dist/core/values/pose.d.ts +5 -1
  55. package/dist/core/values/pose.js +11 -1
  56. package/dist/core/values/range.d.ts +6 -4
  57. package/dist/core/values/range.js +16 -11
  58. package/dist/core/values/str.d.ts +1 -1
  59. package/dist/core/values/str.js +1 -1
  60. package/dist/core/values/template.d.ts +1 -1
  61. package/dist/core/values/transform.d.ts +2 -3
  62. package/dist/core/values/transform.js +2 -3
  63. package/dist/core/values/tri.d.ts +10 -8
  64. package/dist/core/values/tri.js +12 -12
  65. package/dist/core/values/vec.d.ts +10 -4
  66. package/dist/core/values/vec.js +30 -21
  67. package/dist/ext/timeline.js +3 -3
  68. package/dist/index.d.ts +1 -0
  69. package/dist/index.js +1 -0
  70. package/dist/propagators/layout.js +1 -1
  71. package/dist/shapes/handle.js +4 -4
  72. package/dist/shapes/shape.js +7 -7
  73. package/dist/shapes/transitions.js +2 -2
  74. package/package.json +7 -2
  75. package/dist/core/introspect.d.ts +0 -5
  76. package/dist/core/introspect.js +0 -31
  77. package/dist/core/lenses/factor-lens.d.ts +0 -42
  78. package/dist/core/lenses/factor-lens.js +0 -419
  79. package/dist/core/writable.d.ts +0 -15
  80. package/dist/core/writable.js +0 -29
  81. /package/dist/{core/tree.d.ts → tree.d.ts} +0 -0
  82. /package/dist/{core/tree.js → tree.js} +0 -0
@@ -1,4 +1,4 @@
1
- // signal.ts — symmetric bidirectional reactive engine.
1
+ // cell.ts — symmetric bidirectional reactive engine.
2
2
  //
3
3
  // Forward propagation is alien-signals verbatim (link/propagate/
4
4
  // checkDirty/shallowPropagate, Dirty/Pending/Recursed flags, lazy pull).
@@ -25,7 +25,7 @@
25
25
  //
26
26
  // Mode table — a cell's role is fully determined by which fields are set:
27
27
  // source getter undefined (truth in currentValue)
28
- // computed getter, no _bwd (read-only derived)
28
+ // derived getter, no _bwd (read-only derived)
29
29
  // lens 1→1 getter + _bwd{ put, parent: Cell }
30
30
  // multi-out getter + _bwd{ put, parent: Cell[] } (1→N / N→M bwd)
31
31
  // merge getter + _bwd{ merge } (N→1 backward fold)
@@ -411,8 +411,8 @@ export function lazy(self, key, make) {
411
411
  export const isCell = (v) => v instanceof Cell;
412
412
  /** Lens mode: a derived cell that can be written back (has a backward sidecar). */
413
413
  export const isLens = (v) => v instanceof Cell && v.getter !== undefined && v._bwd !== undefined;
414
- /** Computed mode: derived + read-only (no backward path). */
415
- export const isComputed = (v) => v instanceof Cell && v.getter !== undefined && v._bwd === undefined;
414
+ /** Read-only mode: derived with no backward path. */
415
+ export const isReadonly = (v) => v instanceof Cell && v.getter !== undefined && v._bwd === undefined;
416
416
  export class Cell {
417
417
  flags = F.Mutable;
418
418
  subs;
@@ -540,6 +540,11 @@ export class Cell {
540
540
  lens(fwd, bwd) {
541
541
  return buildLens1(this.constructor, this, fwd, bwd, bwd.length >= 2);
542
542
  }
543
+ /** Read-only same-type view: the RO dual of the endo `.lens`. For a cross-type view use the typed static
544
+ * `Target.derive(src, fn)`. */
545
+ derive(fn) {
546
+ return buildDerived(this.constructor, () => fn(this.value));
547
+ }
543
548
  /** Backward-aggregating node — bwd dual of computed. Forward, the
544
549
  * identity view of its parent; backward, folds contributions from
545
550
  * upstream lenses (slot-keyed) and direct writes (DIRECT_SLOT). */
@@ -558,22 +563,11 @@ export class Cell {
558
563
  }
559
564
  // biome-ignore lint/suspicious/noExplicitAny: dispatch
560
565
  static derive(...args) {
561
- if (args.length === 1)
562
- return buildComputed(this, args[0]);
563
- const [parent, fn] = args;
564
- if (Array.isArray(parent))
565
- return buildLensN(this, parent, fn, undefined, false);
566
- return buildComputed(this, () => fn(parent.value));
566
+ return dispatchDerive(this, args);
567
567
  }
568
568
  // biome-ignore lint/suspicious/noExplicitAny: dispatch
569
569
  static lens(...args) {
570
- const [parent, a, b] = args;
571
- if (args.length === 2)
572
- return buildStateful(this, Array.isArray(parent) ? parent : [parent], a);
573
- const readsSource = b.length >= 2;
574
- if (Array.isArray(parent))
575
- return buildLensN(this, parent, a, b, readsSource);
576
- return buildLens1(this, parent, a, b, readsSource);
570
+ return dispatchLens(this, args);
577
571
  }
578
572
  /** Type predicate against this class: `Vec.is(x)` narrows `x` to `Vec`.
579
573
  * Inherited static; works for any subclass via polymorphic `this`. */
@@ -616,14 +610,14 @@ export class Cell {
616
610
  // Read-only ⇔ computed: a getter with no backward sidecar.
617
611
  const ro = parent.getter !== undefined && parent._bwd === undefined;
618
612
  if (ro) {
619
- return buildComputed(ctor, () => get(parent.value));
613
+ return buildDerived(ctor, () => get(parent.value));
620
614
  }
621
615
  // Spread-replace reads the current source ⇒ source-reading (lens) form.
622
616
  return buildLens1(ctor, parent, get, (v, s) => ({ ...s, [key]: v }), true);
623
617
  }
624
618
  }
625
619
  // biome-ignore lint/suspicious/noExplicitAny: variance escape
626
- function buildComputed(Cls, getter) {
620
+ function buildDerived(Cls, getter) {
627
621
  const cell = new Cls();
628
622
  cell.getter = getter;
629
623
  cell.flags = F.Mutable | F.Dirty;
@@ -701,7 +695,58 @@ spec) {
701
695
  });
702
696
  return cell;
703
697
  }
704
- // Install `value` on the prototype (V8 JITs it better than a class get/set).
698
+ // Single-source stateful lens: the `buildLens1` of the complement path.
699
+ // Drops the per-read copy/external loops to direct index-0 access; the
700
+ // spec stays array-shaped (`init: ([s]) => …`), so a reused length-1
701
+ // `vals` still feeds the closures and `b.parent` stays an array for the
702
+ // shared split backward path.
703
+ // biome-ignore lint/suspicious/noExplicitAny: variance escape
704
+ function buildStateful1(Cls, parent,
705
+ // biome-ignore lint/suspicious/noExplicitAny: opaque spec
706
+ spec) {
707
+ const cell = new Cls();
708
+ cell.flags = F.Mutable | F.Dirty;
709
+ const b = (cell._bwd = new BwdSpec());
710
+ const sc = (b.stateful = new StatefulCore(spec.init([parent.peek()]), spec.fwd, spec.step));
711
+ b.put = spec.bwd;
712
+ b.parent = [parent];
713
+ const vals = [undefined];
714
+ cell.getter = (() => {
715
+ const v = (vals[0] = parent.value);
716
+ const lb = sc.lastBwd;
717
+ const external = lb === undefined || lb[0] !== v;
718
+ sc.complement = sc.step(vals, sc.complement, external);
719
+ return sc.fwd(vals, sc.complement);
720
+ });
721
+ return cell;
722
+ }
723
+ // Shared runtime dispatch for `derive`/`lens`, parameterized by the cell
724
+ // constructor: the polymorphic-`this` statics pass the typed subclass
725
+ // (`Vec.derive` → Vec), the free functions pass the plain `Cell`. One body
726
+ // each so the static and free forms can't drift (typed overloads live at
727
+ // the call sites; only these `any` runtime bodies are shared).
728
+ // biome-ignore lint/suspicious/noExplicitAny: dispatch
729
+ function dispatchDerive(ctor, args) {
730
+ if (args.length === 1)
731
+ return buildDerived(ctor, args[0]);
732
+ const [parent, fn] = args;
733
+ if (Array.isArray(parent))
734
+ return buildLensN(ctor, parent, fn, undefined, false);
735
+ return buildDerived(ctor, () => fn(parent.value));
736
+ }
737
+ // biome-ignore lint/suspicious/noExplicitAny: dispatch
738
+ function dispatchLens(ctor, args) {
739
+ const [parent, a, b] = args;
740
+ if (args.length === 2) {
741
+ const ps = Array.isArray(parent) ? parent : [parent];
742
+ return ps.length === 1 ? buildStateful1(ctor, ps[0], a) : buildStateful(ctor, ps, a);
743
+ }
744
+ const readsSource = b.length >= 2;
745
+ if (Array.isArray(parent))
746
+ return buildLensN(ctor, parent, a, b, readsSource);
747
+ return buildLens1(ctor, parent, a, b, readsSource);
748
+ }
749
+ // Install `value` on the prototype (for silly TypeScript inference reasons I'd like to avoid if we can figure it out).
705
750
  Object.defineProperty(Cell.prototype, "value", {
706
751
  get() {
707
752
  const flags = this.flags;
@@ -986,35 +1031,17 @@ export function cell(initial, opts) {
986
1031
  return initial;
987
1032
  return new Cell(initial, opts);
988
1033
  }
989
- export function computed(fn) {
990
- const cell = new Cell(undefined);
991
- cell.flags = F.Mutable | F.Dirty;
992
- cell.getter = fn;
993
- return cell;
994
- }
995
1034
  // Bare (untyped) factories. Construct a plain `Cell`, inferring `R`
996
1035
  // from the closures (the polymorphic-`this` statics are for typed
997
1036
  // subclasses like `Vec.lens`).
998
1037
  const CELL_CTOR = Cell;
999
1038
  // biome-ignore lint/suspicious/noExplicitAny: dispatch
1000
1039
  export function derive(...args) {
1001
- if (args.length === 1)
1002
- return buildComputed(CELL_CTOR, args[0]);
1003
- const [parent, fn] = args;
1004
- if (Array.isArray(parent))
1005
- return buildLensN(CELL_CTOR, parent, fn, undefined, false);
1006
- return buildComputed(CELL_CTOR, () => fn(parent.value));
1040
+ return dispatchDerive(CELL_CTOR, args);
1007
1041
  }
1008
1042
  // biome-ignore lint/suspicious/noExplicitAny: dispatch
1009
1043
  export function lens(...args) {
1010
- const [parent, a, b] = args;
1011
- if (args.length === 2) {
1012
- return buildStateful(CELL_CTOR, Array.isArray(parent) ? parent : [parent], a);
1013
- }
1014
- const readsSource = b.length >= 2;
1015
- if (Array.isArray(parent))
1016
- return buildLensN(CELL_CTOR, parent, a, b, readsSource);
1017
- return buildLens1(CELL_CTOR, parent, a, b, readsSource);
1044
+ return dispatchLens(CELL_CTOR, args);
1018
1045
  }
1019
1046
  // Effect — alien-signals verbatim.
1020
1047
  class Effect {
@@ -1240,11 +1267,11 @@ class _NetworkNode {
1240
1267
  }
1241
1268
  _computeDirty() {
1242
1269
  let dirty;
1243
- for (const [sig, lastVal] of this.lastValues) {
1244
- if (sig.peek() !== lastVal) {
1270
+ for (const [cell, lastVal] of this.lastValues) {
1271
+ if (cell.peek() !== lastVal) {
1245
1272
  if (dirty === undefined)
1246
1273
  dirty = new Set();
1247
- dirty.add(sig);
1274
+ dirty.add(cell);
1248
1275
  }
1249
1276
  }
1250
1277
  return dirty ?? EMPTY_DIRTY;
@@ -1273,8 +1300,8 @@ class _NetworkNode {
1273
1300
  this.lastValues.clear();
1274
1301
  let l = this.deps;
1275
1302
  while (l !== undefined) {
1276
- const sig = l.dep;
1277
- this.lastValues.set(sig, sig.peek());
1303
+ const cell = l.dep;
1304
+ this.lastValues.set(cell, cell.peek());
1278
1305
  l = l.nextDep;
1279
1306
  }
1280
1307
  }
@@ -1289,16 +1316,16 @@ class _NetworkNode {
1289
1316
  }
1290
1317
  this._runBody(this._computeDirty());
1291
1318
  }
1292
- subscribe(sigs) {
1319
+ subscribe(cells) {
1293
1320
  if (this.disposed)
1294
1321
  return;
1295
- this._linkBatch(sigs);
1322
+ this._linkBatch(cells);
1296
1323
  }
1297
- unsubscribe(sigs) {
1324
+ unsubscribe(cells) {
1298
1325
  if (this.disposed)
1299
1326
  return;
1300
1327
  const set = this._depsSet;
1301
- for (const s of sigs) {
1328
+ for (const s of cells) {
1302
1329
  if (!set.has(s))
1303
1330
  continue;
1304
1331
  set.delete(s);
@@ -1312,7 +1339,7 @@ class _NetworkNode {
1312
1339
  }
1313
1340
  }
1314
1341
  }
1315
- _linkBatch(sigs) {
1342
+ _linkBatch(cells) {
1316
1343
  const set = this._depsSet;
1317
1344
  let tail = this.deps;
1318
1345
  if (tail !== undefined) {
@@ -1320,7 +1347,7 @@ class _NetworkNode {
1320
1347
  tail = tail.nextDep;
1321
1348
  }
1322
1349
  this.depsTail = tail;
1323
- for (const s of sigs) {
1350
+ for (const s of cells) {
1324
1351
  if (set.has(s))
1325
1352
  continue;
1326
1353
  set.add(s);
@@ -1341,9 +1368,63 @@ deps, body, opts) {
1341
1368
  const handle = {
1342
1369
  dispose: () => node._unwatched(),
1343
1370
  flush: () => node.flush(),
1344
- subscribe: (...sigs) => node.subscribe(sigs),
1345
- unsubscribe: (...sigs) => node.unsubscribe(sigs),
1371
+ subscribe: (...cells) => node.subscribe(cells),
1372
+ unsubscribe: (...cells) => node.unsubscribe(cells),
1346
1373
  };
1347
1374
  node._initWithHandle(handle, deps);
1348
1375
  return handle;
1349
1376
  }
1377
+ // MISC stuff used by a few places, to revisit...
1378
+ // ── value-class authoring helpers ──────────────────────────────────
1379
+ //
1380
+ // `field`/`cachedDerive` are the two getter forms a value class declares.
1381
+ // The choice between them IS the local declaration of writability at each
1382
+ // getter (mirroring `: this` invertible method returns). For arbitrary
1383
+ // cached views, use `lazy()` directly.
1384
+ /** Bidirectional field lens onto `parent.value[key]`; write spread-
1385
+ * replaces the composite. Cached per (instance, key). Return type is
1386
+ * conditional: `Writable<Cls>` on a writable parent, bare `Cls` on RO.
1387
+ *
1388
+ * get x() { return field(this, "x", Num); } */
1389
+ export function field(parent, key, Cls) {
1390
+ return lazy(parent, key, () => Cell.fieldOf(parent, key, Cls));
1391
+ }
1392
+ /** Read-only derived view via `Cls.derive(parent, fn)`, memoized per
1393
+ * (instance, key); always bare `Cls` (RO). The cache is the point — the
1394
+ * getter form, not a new kind of cell.
1395
+ *
1396
+ * get magnitude() {
1397
+ * return cachedDerive(this, "magnitude", Num, v => Math.hypot(v.x, v.y));
1398
+ * } */
1399
+ // biome-ignore lint/suspicious/noExplicitAny: variance escape, mirrors Cls.derive
1400
+ export function cachedDerive(parent, key, Cls, fn) {
1401
+ // biome-ignore lint/suspicious/noExplicitAny: variance escape on Cls.derive
1402
+ return lazy(parent, key, () => Cls.derive(parent, fn));
1403
+ }
1404
+ /** Every cell `s` transitively depends on, including itself. Raw cells
1405
+ * return `{s}`; lens chains return the chain plus all parents. BFS,
1406
+ * peeking each Computed to populate deps; the `seen` set breaks cycles.
1407
+ * Used by `Propagators` to expand declared reads into their transitive
1408
+ * parent set. Inspection is safe: it only reads engine state and peeks
1409
+ * `.value` (idempotent for lazy Computeds). */
1410
+ export function transitiveDeps(s) {
1411
+ const seen = new Set();
1412
+ const queue = [s];
1413
+ while (queue.length > 0) {
1414
+ const cur = queue.shift();
1415
+ if (seen.has(cur))
1416
+ continue;
1417
+ seen.add(cur);
1418
+ // Cast to reach engine fields the typed Cell<T> shape doesn't surface.
1419
+ const c = cur;
1420
+ if (c.getter !== undefined) {
1421
+ void cur.value;
1422
+ let l = c.deps;
1423
+ while (l !== undefined) {
1424
+ queue.push(l.dep);
1425
+ l = l.nextDep;
1426
+ }
1427
+ }
1428
+ }
1429
+ return seen;
1430
+ }
@@ -0,0 +1,11 @@
1
+ import type { Cell } from "./cell.js";
2
+ import { Vec } from "./values/vec.js";
3
+ type V = {
4
+ x: number;
5
+ y: number;
6
+ };
7
+ /** Quadratic Bézier point at parameter `t`. RO. */
8
+ export declare function bezier2(p0: Cell<V>, p1: Cell<V>, p2: Cell<V>, t: Cell<number>): Vec;
9
+ /** Cubic Bézier point at parameter `t`. RO. */
10
+ export declare function bezier3(p0: Cell<V>, p1: Cell<V>, p2: Cell<V>, p3: Cell<V>, t: Cell<number>): Vec;
11
+ export {};
@@ -0,0 +1,32 @@
1
+ // derived-geometry.ts — read-only geometric readouts over `Cls.derive`.
2
+ //
3
+ // One-way derives whose inverse is genuinely under-determined (a point
4
+ // sampled at parameter `t` constrains the curve at one point, but the
5
+ // control points have many DOF). They live here, off the lens surface,
6
+ // to keep `lenses/` exclusively bidirectional. For the writable bezier
7
+ // shape decomposition see `bezierGestalt` in `lenses/domain-aggregates`.
8
+ import { Vec } from "./values/vec.js";
9
+ /** Quadratic Bézier point at parameter `t`. RO. */
10
+ export function bezier2(p0, p1, p2, t) {
11
+ return Vec.derive([p0, p1, p2, t], vals => {
12
+ const [a, b, c, tv] = vals;
13
+ const u = 1 - tv;
14
+ return {
15
+ x: u * u * a.x + 2 * u * tv * b.x + tv * tv * c.x,
16
+ y: u * u * a.y + 2 * u * tv * b.y + tv * tv * c.y,
17
+ };
18
+ });
19
+ }
20
+ /** Cubic Bézier point at parameter `t`. RO. */
21
+ export function bezier3(p0, p1, p2, p3, t) {
22
+ return Vec.derive([p0, p1, p2, p3, t], vals => {
23
+ const [a, b, c, d, tv] = vals;
24
+ const u = 1 - tv;
25
+ const u2 = u * u;
26
+ const t2 = tv * tv;
27
+ return {
28
+ x: u2 * u * a.x + 3 * u2 * tv * b.x + 3 * u * t2 * c.x + t2 * tv * d.x,
29
+ y: u2 * u * a.y + 3 * u2 * tv * b.y + 3 * u * t2 * c.y + t2 * tv * d.y,
30
+ };
31
+ });
32
+ }
@@ -1,25 +1,21 @@
1
- export { argminNum, argminVec, centroidLens, clampToDisc, meanLens, midpointLens, } from "./aggregates.js";
2
- export { type Animatable, attract, driven, every, loop, not, type Play, play, type SpringOpts, spring, Tween, toward, tween, untilChange, wave, when, } from "./anim.js";
3
- export { transitiveDeps } from "./introspect.js";
1
+ export { batch, Cell, type CellOptions, cachedDerive, cell, derive, effect, field, type Init, type Inner, isCell, isLens, isReadonly, lazy, lens, type Network, network, type Read, reader, readNow, type StatefulBwd, type StatefulLensSpec, setCellWriteHook, transitiveDeps, untracked, type Val, type Writable, type WritableBrand, } from "./cell.js";
2
+ export { bezier2, bezier3 } from "./derived-geometry.js";
4
3
  export * from "./lenses/index.js";
5
- export { each, type Lifecycle } from "./network-utils.js";
6
- export { reflectionLens } from "./new-primitives.js";
7
- export { batch, Cell, type CellOptions, cell, derive, effect, type Init, type Inner, isCell, isComputed, isLens, lazy, lens, type Network, network, type Read, reader, readNow, type StatefulBwd, type StatefulLensSpec, setCellWriteHook, untracked, type Val, type Writable, type WritableBrand, } from "./signal.js";
4
+ export { each, type Lifecycle } from "./lifecycle.js";
8
5
  export { type Equals, type Lerp, type Linear, type Metric, type Pack, type Pivotal, requireEquals, requireLerp, requireLinear, requireMetric, requirePack, requirePivotal, type TraitDict, type Traits, } from "./traits.js";
9
- export { allNodes, atPath, isLeaf, leavesOf, node as treeNode, nodeCount, type TreeNode, walkTree, } from "./tree.js";
10
6
  export { Anchor, Dir } from "./values/anchor.js";
11
7
  export { Audio, type AudioClip, audio, stamp as audioStamp } from "./values/audio.js";
12
8
  export * as BoolMath from "./values/bool.js";
13
9
  export { Bool, bool } from "./values/bool.js";
14
10
  export * as BoxMath from "./values/box.js";
15
- export { Box, box, edgeFrom, union as boxUnion } from "./values/box.js";
11
+ export { Box, box } from "./values/box.js";
16
12
  export { Canvas, canvas, type Raster, stamp as canvasStamp } from "./values/canvas.js";
17
13
  export * as ColorMath from "./values/color.js";
18
14
  export { Color, rgb, rgba } from "./values/color.js";
19
15
  export { Flags, flags } from "./values/flags.js";
20
16
  export { blit as gpuBlit, brush as gpuBrush, copy as gpuCopy, newTex as gpuNewTex, Spring, scratch2 as gpuScratch2, type Tex, } from "./values/gpu.js";
21
17
  export * as MatrixMath from "./values/matrix.js";
22
- export { compose, determinant, fromRotate, fromScale, fromTranslate, identity, invert, isIdentity, Matrix, matrix, multiply, toMatrixString, transformBox, transformPoint, } from "./values/matrix.js";
18
+ export { Matrix, matrix, transformBox, transformPoint } from "./values/matrix.js";
23
19
  export * as NumMath from "./values/num.js";
24
20
  export { Num, num } from "./values/num.js";
25
21
  export * as PoseMath from "./values/pose.js";
@@ -35,4 +31,3 @@ export * as TriMath from "./values/tri.js";
35
31
  export { Tri, tri } from "./values/tri.js";
36
32
  export * as VecMath from "./values/vec.js";
37
33
  export { type PolarPolicy, polar, tangentPoint, Vec, vec } from "./values/vec.js";
38
- export { derived, field } from "./writable.js";
@@ -1,25 +1,21 @@
1
- export { argminNum, argminVec, centroidLens, clampToDisc, meanLens, midpointLens, } from "./aggregates.js";
2
- export { attract, driven, every, loop, not, play, spring, Tween, toward, tween, untilChange, wave, when, } from "./anim.js";
3
- export { transitiveDeps } from "./introspect.js";
1
+ export { batch, Cell, cachedDerive, cell, derive, effect, field, isCell, isLens, isReadonly, lazy, lens, network, reader, readNow, setCellWriteHook, transitiveDeps, untracked, } from "./cell.js";
2
+ export { bezier2, bezier3 } from "./derived-geometry.js";
4
3
  export * from "./lenses/index.js";
5
- export { each } from "./network-utils.js";
6
- export { reflectionLens } from "./new-primitives.js";
7
- export { batch, Cell, cell, derive, effect, isCell, isComputed, isLens, lazy, lens, network, reader, readNow, setCellWriteHook, untracked, } from "./signal.js";
4
+ export { each } from "./lifecycle.js";
8
5
  export { requireEquals, requireLerp, requireLinear, requireMetric, requirePack, requirePivotal, } from "./traits.js";
9
- export { allNodes, atPath, isLeaf, leavesOf, node as treeNode, nodeCount, walkTree, } from "./tree.js";
10
6
  export { Anchor, Dir } from "./values/anchor.js";
11
7
  export { Audio, audio, stamp as audioStamp } from "./values/audio.js";
12
8
  export * as BoolMath from "./values/bool.js";
13
9
  export { Bool, bool } from "./values/bool.js";
14
10
  export * as BoxMath from "./values/box.js";
15
- export { Box, box, edgeFrom, union as boxUnion } from "./values/box.js";
11
+ export { Box, box } from "./values/box.js";
16
12
  export { Canvas, canvas, stamp as canvasStamp } from "./values/canvas.js";
17
13
  export * as ColorMath from "./values/color.js";
18
14
  export { Color, rgb, rgba } from "./values/color.js";
19
15
  export { Flags, flags } from "./values/flags.js";
20
16
  export { blit as gpuBlit, brush as gpuBrush, copy as gpuCopy, newTex as gpuNewTex, Spring, scratch2 as gpuScratch2, } from "./values/gpu.js";
21
17
  export * as MatrixMath from "./values/matrix.js";
22
- export { compose, determinant, fromRotate, fromScale, fromTranslate, identity, invert, isIdentity, Matrix, matrix, multiply, toMatrixString, transformBox, transformPoint, } from "./values/matrix.js";
18
+ export { Matrix, matrix, transformBox, transformPoint } from "./values/matrix.js";
23
19
  export * as NumMath from "./values/num.js";
24
20
  export { Num, num } from "./values/num.js";
25
21
  export * as PoseMath from "./values/pose.js";
@@ -35,4 +31,3 @@ export * as TriMath from "./values/tri.js";
35
31
  export { Tri, tri } from "./values/tri.js";
36
32
  export * as VecMath from "./values/vec.js";
37
33
  export { polar, tangentPoint, Vec, vec } from "./values/vec.js";
38
- export { derived, field } from "./writable.js";
@@ -1,16 +1,6 @@
1
- import type { Cell, Writable } from "./signal.js";
2
- import { Num } from "./values/num.js";
3
- import { Vec } from "./values/vec.js";
4
- type V = {
5
- x: number;
6
- y: number;
7
- };
8
- /** Equal-weight mean of N Linear values; writes distribute the delta evenly. */
9
- export declare function meanLens<T, C extends new (...args: never[]) => Cell<any>>(Cls: C, parents: readonly Cell<T>[]): Writable<InstanceType<C>>;
10
- /** Midpoint of two writable Vecs. Drag-translates both endpoints. */
11
- export declare function midpointLens(a: Cell<V>, b: Cell<V>): Writable<Vec>;
12
- /** Centroid of N writable Vecs. Drag-translates all members. */
13
- export declare function centroidLens(parents: readonly Cell<V>[]): Writable<Vec>;
1
+ import type { Writable } from "../cell.js";
2
+ import { Num } from "../values/num.js";
3
+ import { Vec } from "../values/vec.js";
14
4
  export interface ArgminOpts {
15
5
  /** Finite-difference epsilon for the Jacobian. Default 1e-4. */
16
6
  eps?: number;
@@ -61,4 +51,3 @@ export declare function argminVec(inputs: readonly Num[], forward: (xs: readonly
61
51
  x: number;
62
52
  y: number;
63
53
  }, weights: readonly number[], opts?: ArgminVecOpts): Writable<Vec>;
64
- export {};
@@ -1,85 +1,12 @@
1
- // aggregates.ts — N→1 aggregate lens primitives over `Cls.lens` /
2
- // `Cls.derive`.
1
+ // aggregates.ts — numerical N→1 / N→M argmin lens primitives over
2
+ // `Cls.lens`. For the closed-form equal-weight `mean` and `spread`
3
+ // aggregates see `domain-aggregates.ts`.
3
4
  //
4
5
  // All route through the engine's N-input lens path. Stateless-bwd
5
6
  // (`(target) => updates`) skips the peek loop on the hot path;
6
7
  // stateful-bwd (`(target, vals) => updates`) reads the scratch.
7
- import { Num } from "./values/num.js";
8
- import { Vec } from "./values/vec.js";
9
- /** Equal-weight mean of N Linear values; writes distribute the delta evenly. */
10
- // biome-ignore lint/suspicious/noExplicitAny: variance escape, mirrors Cls.lens
11
- export function meanLens(Cls, parents) {
12
- const lin = (Cls.traits?.linear ??
13
- (() => {
14
- throw new Error("meanLens: value class has no 'linear' trait");
15
- })());
16
- const n = parents.length;
17
- const inv = 1 / n;
18
- // biome-ignore lint/suspicious/noExplicitAny: variance escape on Cls.lens
19
- return Cls.lens(parents,
20
- // biome-ignore lint/suspicious/noExplicitAny: tuple-vs-array variance
21
- (vals) => {
22
- let acc = vals[0];
23
- for (let i = 1; i < n; i++)
24
- acc = lin.add(acc, vals[i]);
25
- return lin.scale(acc, inv);
26
- },
27
- // biome-ignore lint/suspicious/noExplicitAny: tuple-vs-array variance
28
- (target, vals) => {
29
- let cur = vals[0];
30
- for (let i = 1; i < n; i++)
31
- cur = lin.add(cur, vals[i]);
32
- cur = lin.scale(cur, inv);
33
- const delta = lin.sub(target, cur);
34
- const out = new Array(n);
35
- for (let i = 0; i < n; i++)
36
- out[i] = lin.add(vals[i], delta);
37
- return out;
38
- });
39
- }
40
- /** Midpoint of two writable Vecs. Drag-translates both endpoints. */
41
- export function midpointLens(a, b) {
42
- return Vec.lens([a, b], vals => {
43
- const [av, bv] = vals;
44
- return { x: (av.x + bv.x) / 2, y: (av.y + bv.y) / 2 };
45
- }, (target, vals) => {
46
- const [av, bv] = vals;
47
- const dx = target.x - (av.x + bv.x) / 2;
48
- const dy = target.y - (av.y + bv.y) / 2;
49
- return [
50
- { x: av.x + dx, y: av.y + dy },
51
- { x: bv.x + dx, y: bv.y + dy },
52
- ];
53
- });
54
- }
55
- /** Centroid of N writable Vecs. Drag-translates all members. */
56
- export function centroidLens(parents) {
57
- const n = parents.length;
58
- const inv = 1 / n;
59
- return Vec.lens(parents, vals => {
60
- const arr = vals;
61
- let sx = 0, sy = 0;
62
- for (let i = 0; i < n; i++) {
63
- sx += arr[i].x;
64
- sy += arr[i].y;
65
- }
66
- return { x: sx * inv, y: sy * inv };
67
- }, (target, vals) => {
68
- const arr = vals;
69
- let sx = 0, sy = 0;
70
- for (let i = 0; i < n; i++) {
71
- sx += arr[i].x;
72
- sy += arr[i].y;
73
- }
74
- const dx = target.x - sx * inv;
75
- const dy = target.y - sy * inv;
76
- const out = new Array(n);
77
- for (let i = 0; i < n; i++) {
78
- out[i] = { x: arr[i].x + dx, y: arr[i].y + dy };
79
- }
80
- return out;
81
- });
82
- }
8
+ import { Num } from "../values/num.js";
9
+ import { Vec } from "../values/vec.js";
83
10
  /** Project `p` into the closed disc of radius `r` centred on `c` (points
84
11
  * inside pass through). Use as `argminVec`'s `clampTarget` to fix IK
85
12
  * explosion at maximum reach. */
@@ -4,7 +4,7 @@ type V = {
4
4
  y: number;
5
5
  };
6
6
  /** Writable centroid; on write, translates every point by the delta.
7
- * Alias of `centroidLens` under the "policy" naming. */
7
+ * The Vec-specific group-action reading of `mean`. */
8
8
  export declare function rigidTranslate(points: readonly Writable<Vec>[]): Writable<Vec>;
9
9
  /** Writable angle from `pivot` to `points[0]`; write rotates every input
10
10
  * about `pivot` by (target − current) via its `Pivotal` trait.
@@ -12,7 +12,7 @@ export declare function rigidTranslate(points: readonly Writable<Vec>[]): Writab
12
12
  * Trait-generic: Vec rotates position; Pose rotates position AND
13
13
  * orientation. Rotation-about-pivot fixes the pivot and preserves radial
14
14
  * distances, so scale-about-pivot reads unchanged. `pivot` is reactive
15
- * (re-read per write); pass `centroidLens(points)` for rotation about
15
+ * (re-read per write); pass `rigidTranslate(points)` for rotation about
16
16
  * the cluster's own centroid. */
17
17
  export declare function rotateAbout<T extends {
18
18
  x: number;
@@ -35,22 +35,15 @@ export declare function scaleAbout<T extends {
35
35
  * point 0's offset, so a per-axis collapse is recoverable (cf.
36
36
  * `bboxLens.size`). */
37
37
  export declare function scaleAboutXY(points: readonly Writable<Vec>[], pivot: Read<V>): Writable<Vec>;
38
- /** Same semantics as `factor-lens.ts`'s `procrustesLens`, decomposed
39
- * into three building-block lenses sharing a centroid. */
40
- export declare function procrustesViaBuildingBlocks(points: readonly Writable<Vec>[]): {
41
- centroid: Writable<Vec>;
42
- rotation: Writable<Num>;
43
- scale: Writable<Num>;
44
- };
45
- export declare function bestFitLineLens(points: readonly Writable<Vec>[]): {
38
+ export declare function bestFitLine(points: readonly Writable<Vec>[]): {
46
39
  point: Writable<Vec>;
47
40
  direction: Writable<Num>;
48
41
  };
49
- export declare function bestFitCircleLens(points: readonly Writable<Vec>[]): {
42
+ export declare function bestFitCircle(points: readonly Writable<Vec>[]): {
50
43
  center: Writable<Vec>;
51
44
  radius: Writable<Num>;
52
45
  };
53
- export declare function pcaLens(points: readonly Writable<Vec>[]): {
46
+ export declare function pca(points: readonly Writable<Vec>[]): {
54
47
  mean: Writable<Vec>;
55
48
  rotation: Writable<Num>;
56
49
  majorLength: Writable<Num>;
@@ -60,5 +53,5 @@ export declare function pcaLens(points: readonly Writable<Vec>[]): {
60
53
  * preserving their ratios. A `remember` anchored at zero with a signed
61
54
  * sum feature: a collapse to zero reinflates the stored ratios, seeded
62
55
  * uniform so an all-zero start splits evenly. */
63
- export declare function totalLens(parts: readonly Writable<Num>[]): Writable<Num>;
56
+ export declare function total(parts: readonly Writable<Num>[]): Writable<Num>;
64
57
  export {};