bireactive 0.2.4 → 0.3.1

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 (132) hide show
  1. package/dist/animation/anim.js +4 -0
  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/coll.d.ts +7 -7
  9. package/dist/core/_counts.d.ts +48 -0
  10. package/dist/core/_counts.js +58 -0
  11. package/dist/core/cell.d.ts +182 -123
  12. package/dist/core/cell.js +1140 -721
  13. package/dist/core/debug.d.ts +25 -0
  14. package/dist/core/debug.js +121 -0
  15. package/dist/core/index.d.ts +9 -14
  16. package/dist/core/index.js +9 -14
  17. package/dist/core/lenses/aggregates.d.ts +1 -1
  18. package/dist/core/lenses/aggregates.js +4 -3
  19. package/dist/core/lenses/closed-form-policies.js +14 -9
  20. package/dist/core/lenses/decompositions.js +3 -3
  21. package/dist/core/lenses/domain-aggregates.js +5 -5
  22. package/dist/core/lenses/geometry.d.ts +1 -1
  23. package/dist/core/lenses/geometry.js +6 -7
  24. package/dist/core/lenses/index.d.ts +1 -0
  25. package/dist/core/lenses/index.js +1 -0
  26. package/dist/core/lenses/memory.d.ts +2 -2
  27. package/dist/core/lenses/memory.js +3 -3
  28. package/dist/core/lenses/snap.d.ts +18 -0
  29. package/dist/core/lenses/snap.js +145 -0
  30. package/dist/core/lenses/typed-factor.js +4 -3
  31. package/dist/core/optic.d.ts +13 -0
  32. package/dist/core/optic.js +44 -0
  33. package/dist/core/optics.d.ts +10 -0
  34. package/dist/core/optics.js +30 -0
  35. package/dist/core/store.d.ts +10 -0
  36. package/dist/core/store.js +85 -0
  37. package/dist/core/traits.d.ts +1 -0
  38. package/dist/core/values/audio.js +4 -5
  39. package/dist/core/values/box.js +7 -7
  40. package/dist/core/values/canvas.js +15 -18
  41. package/dist/core/values/color.js +5 -5
  42. package/dist/core/values/field.d.ts +70 -0
  43. package/dist/core/values/field.js +230 -0
  44. package/dist/core/values/gpu.d.ts +4 -2
  45. package/dist/core/values/gpu.js +11 -4
  46. package/dist/core/values/matrix.js +7 -7
  47. package/dist/core/values/num.d.ts +1 -1
  48. package/dist/core/values/num.js +1 -1
  49. package/dist/core/values/pose.js +4 -4
  50. package/dist/core/values/range.js +6 -6
  51. package/dist/core/values/str.js +8 -8
  52. package/dist/core/values/template.d.ts +1 -1
  53. package/dist/core/values/template.js +2 -1
  54. package/dist/core/values/transform.js +7 -7
  55. package/dist/core/values/tri.js +3 -3
  56. package/dist/core/values/vec.js +8 -12
  57. package/dist/ext/timeline.js +2 -2
  58. package/dist/formats/cst.d.ts +127 -0
  59. package/dist/formats/cst.js +280 -0
  60. package/dist/formats/edn.d.ts +2 -0
  61. package/dist/formats/edn.js +301 -0
  62. package/dist/formats/index.d.ts +6 -0
  63. package/dist/formats/index.js +8 -0
  64. package/dist/formats/json.d.ts +2 -0
  65. package/dist/formats/json.js +332 -0
  66. package/dist/formats/lens.d.ts +8 -0
  67. package/dist/formats/lens.js +51 -0
  68. package/dist/formats/toml.d.ts +2 -0
  69. package/dist/formats/toml.js +526 -0
  70. package/dist/formats/yaml.d.ts +2 -0
  71. package/dist/formats/yaml.js +661 -0
  72. package/dist/index.d.ts +10 -0
  73. package/dist/index.js +10 -0
  74. package/dist/jsx-dev-runtime.d.ts +2 -0
  75. package/dist/jsx-dev-runtime.js +5 -0
  76. package/dist/jsx-runtime.d.ts +54 -0
  77. package/dist/jsx-runtime.js +219 -0
  78. package/dist/learn/data.d.ts +49 -0
  79. package/dist/learn/data.js +181 -0
  80. package/dist/learn/index.d.ts +3 -0
  81. package/dist/learn/index.js +6 -0
  82. package/dist/learn/lens-net.d.ts +63 -0
  83. package/dist/learn/lens-net.js +219 -0
  84. package/dist/learn/mlp.d.ts +77 -0
  85. package/dist/learn/mlp.js +292 -0
  86. package/dist/propagators/csp.d.ts +13 -0
  87. package/dist/propagators/csp.js +52 -0
  88. package/dist/propagators/flex.d.ts +31 -0
  89. package/dist/propagators/flex.js +189 -0
  90. package/dist/propagators/graph.d.ts +73 -0
  91. package/dist/propagators/graph.js +543 -0
  92. package/dist/propagators/index.d.ts +8 -6
  93. package/dist/propagators/index.js +15 -6
  94. package/dist/propagators/lattice.d.ts +45 -0
  95. package/dist/propagators/lattice.js +113 -0
  96. package/dist/propagators/layout.d.ts +1 -27
  97. package/dist/propagators/layout.js +6 -175
  98. package/dist/propagators/numeric.d.ts +17 -0
  99. package/dist/propagators/numeric.js +93 -0
  100. package/dist/propagators/solver.d.ts +51 -0
  101. package/dist/propagators/solver.js +175 -0
  102. package/dist/schema/index.d.ts +1 -0
  103. package/dist/schema/index.js +3 -0
  104. package/dist/schema/lens.d.ts +121 -0
  105. package/dist/schema/lens.js +429 -0
  106. package/dist/shapes/annular-sector.js +4 -4
  107. package/dist/shapes/button.js +1 -1
  108. package/dist/shapes/circle.js +1 -1
  109. package/dist/shapes/drag-behaviors.d.ts +56 -0
  110. package/dist/shapes/drag-behaviors.js +102 -0
  111. package/dist/shapes/drag-spec.d.ts +52 -0
  112. package/dist/shapes/drag-spec.js +112 -0
  113. package/dist/shapes/handle.js +2 -2
  114. package/dist/shapes/index.d.ts +3 -1
  115. package/dist/shapes/index.js +3 -1
  116. package/dist/shapes/interaction.d.ts +2 -3
  117. package/dist/shapes/interaction.js +77 -56
  118. package/dist/shapes/label.js +7 -1
  119. package/dist/shapes/layout.d.ts +47 -1
  120. package/dist/shapes/layout.js +60 -2
  121. package/dist/shapes/rect.js +7 -7
  122. package/dist/shapes/shape.js +8 -8
  123. package/dist/web/diagram.js +2 -2
  124. package/package.json +24 -2
  125. package/dist/propagators/network.d.ts +0 -52
  126. package/dist/propagators/network.js +0 -185
  127. package/dist/propagators/propagator.d.ts +0 -12
  128. package/dist/propagators/propagator.js +0 -16
  129. package/dist/propagators/range.d.ts +0 -45
  130. package/dist/propagators/range.js +0 -147
  131. package/dist/propagators/relations.d.ts +0 -60
  132. package/dist/propagators/relations.js +0 -343
@@ -0,0 +1,189 @@
1
+ // flex.ts — flexbox as interval propagation.
2
+ //
3
+ // A flex line is two phases, both grounded in the interval lattice:
4
+ //
5
+ // 1. FEASIBILITY (narrowing). Given the container's content size and
6
+ // each item's [min, max], the `total` relation narrows every item
7
+ // to the band it could occupy: `wᵢ ∈ content − Σ(others)`. If any
8
+ // band comes back empty the line can't fit — that's a real lattice
9
+ // contradiction, reported, not a silent overflow.
10
+ //
11
+ // 2. RESOLUTION (point pick). Within the feasible bands, grow/shrink
12
+ // weights distribute the slack to a single size per item. This is
13
+ // the one place a *preference* (not a constraint) enters, so it's
14
+ // kept out of the narrowing.
15
+ //
16
+ // The line operates on plain `Box` cells — zero ceremony, nothing is
17
+ // coloured. Nesting composes through the ordinary reactive graph: a
18
+ // child container is just an item of its parent, so resizing the root
19
+ // re-runs each line top-down. `row`/`col` are the only public surface;
20
+ // everything else is the two phases above.
21
+ import { isCell, readNow, } from "../core/index.js";
22
+ import { interval } from "./lattice.js";
23
+ import { propagator } from "./solver.js";
24
+ const asW = (n) => n;
25
+ function readDeps(...vs) {
26
+ return vs.filter(isCell);
27
+ }
28
+ const clamp = (v, lo, hi) => Math.min(Math.max(v, lo), hi);
29
+ function specs(items) {
30
+ return items.map(it => "box" in it
31
+ ? {
32
+ box: it.box,
33
+ grow: it.grow ?? 1,
34
+ shrink: it.shrink ?? 1,
35
+ min: it.min ?? 0,
36
+ max: it.max ?? Number.POSITIVE_INFINITY,
37
+ basis: it.basis,
38
+ }
39
+ : { box: it, grow: 1, shrink: 1, min: 0, max: Number.POSITIVE_INFINITY });
40
+ }
41
+ /** Horizontal flex line over plain `Box` cells. */
42
+ export function row(c, items, opts = {}) {
43
+ return line(c, items, opts, "x");
44
+ }
45
+ /** Vertical flex line over plain `Box` cells. */
46
+ export function col(c, items, opts = {}) {
47
+ return line(c, items, opts, "y");
48
+ }
49
+ function line(c, rawItems, opts, main) {
50
+ const items = specs(rawItems);
51
+ const horizontal = main === "x";
52
+ const mainPos = (b) => asW(horizontal ? b.x : b.y);
53
+ const mainSize = (b) => asW(horizontal ? b.w : b.h);
54
+ const crossPos = (b) => asW(horizontal ? b.y : b.x);
55
+ const crossSize = (b) => asW(horizontal ? b.h : b.w);
56
+ const align = opts.align ?? "stretch";
57
+ const reads = [
58
+ mainPos(c),
59
+ mainSize(c),
60
+ crossPos(c),
61
+ crossSize(c),
62
+ ...items.map(it => crossSize(it.box)),
63
+ ...readDeps(opts.gap ?? 0, opts.padding ?? 0),
64
+ ];
65
+ const writes = [];
66
+ for (const it of items) {
67
+ writes.push(mainPos(it.box), mainSize(it.box), crossPos(it.box));
68
+ if (align === "stretch")
69
+ writes.push(crossSize(it.box));
70
+ }
71
+ if (typeof opts.report !== "function" && opts.report)
72
+ writes.push(opts.report);
73
+ return propagator(reads, writes, () => {
74
+ const gap = readNow(opts.gap ?? 0);
75
+ const pad = readNow(opts.padding ?? 0);
76
+ const n = items.length;
77
+ if (n === 0)
78
+ return;
79
+ const content = mainSize(c).value - 2 * pad - (n - 1) * gap;
80
+ const mins = items.map(it => it.min);
81
+ const maxs = items.map(it => it.max);
82
+ const sumMin = mins.reduce((a, b) => a + b, 0);
83
+ const sumMax = maxs.reduce((a, b) => a + b, 0);
84
+ // Phase 1 — feasibility. Per-item band from the `total` relation:
85
+ // wᵢ ∈ [content − Σmax(others), content − Σmin(others)] ∩ [minᵢ, maxᵢ].
86
+ const bands = items.map((_, i) => {
87
+ const lo = content - (sumMax - maxs[i]);
88
+ const hi = content - (sumMin - mins[i]);
89
+ return interval.meet([Math.max(lo, mins[i]), Math.min(hi, maxs[i])], [mins[i], maxs[i]]);
90
+ });
91
+ const infeasible = content < sumMin - 1e-9 || bands.some(interval.isBottom);
92
+ report(opts, infeasible);
93
+ // Phase 2 — resolution. Distribute slack from the basis sizes,
94
+ // weighted by grow (free > 0) / shrink (free < 0), clamped into the
95
+ // feasible band each pass and redistributed.
96
+ const base = items.map((it, i) => clamp(it.basis ?? mainSize(it.box).value, mins[i], maxs[i]));
97
+ const sizes = distribute(base, items, mins, maxs, content);
98
+ let cursor = mainPos(c).value + pad;
99
+ for (let i = 0; i < n; i++) {
100
+ mainPos(items[i].box).value = cursor;
101
+ mainSize(items[i].box).value = sizes[i];
102
+ cursor += sizes[i] + gap;
103
+ }
104
+ const cBase = crossPos(c).value + pad;
105
+ const cAvail = crossSize(c).value - 2 * pad;
106
+ for (const it of items) {
107
+ const itSize = crossSize(it.box).value;
108
+ switch (align) {
109
+ case "start":
110
+ crossPos(it.box).value = cBase;
111
+ break;
112
+ case "center":
113
+ crossPos(it.box).value = cBase + (cAvail - itSize) / 2;
114
+ break;
115
+ case "end":
116
+ crossPos(it.box).value = cBase + cAvail - itSize;
117
+ break;
118
+ case "stretch":
119
+ crossPos(it.box).value = cBase;
120
+ crossSize(it.box).value = cAvail;
121
+ break;
122
+ }
123
+ }
124
+ });
125
+ }
126
+ /** CSS-flex slack distribution, clamped into [min, max] with overflow
127
+ * redistributed across still-eligible items. */
128
+ function distribute(base, items, mins, maxs, content) {
129
+ const n = base.length;
130
+ const sizes = base.slice();
131
+ const free = content - base.reduce((a, b) => a + b, 0);
132
+ if (free > 1e-9) {
133
+ let remaining = free;
134
+ const eligible = new Set();
135
+ for (let i = 0; i < n; i++)
136
+ if (items[i].grow > 0 && sizes[i] < maxs[i])
137
+ eligible.add(i);
138
+ while (remaining > 1e-9 && eligible.size > 0) {
139
+ let weight = 0;
140
+ for (const i of eligible)
141
+ weight += items[i].grow;
142
+ if (weight === 0)
143
+ break;
144
+ let absorbed = 0;
145
+ for (const i of [...eligible]) {
146
+ const next = Math.min(sizes[i] + (remaining * items[i].grow) / weight, maxs[i]);
147
+ absorbed += next - sizes[i];
148
+ sizes[i] = next;
149
+ if (next >= maxs[i])
150
+ eligible.delete(i);
151
+ }
152
+ if (absorbed < 1e-9)
153
+ break;
154
+ remaining -= absorbed;
155
+ }
156
+ }
157
+ else if (free < -1e-9) {
158
+ let remaining = -free;
159
+ const eligible = new Set();
160
+ for (let i = 0; i < n; i++)
161
+ if (items[i].shrink > 0 && sizes[i] > mins[i])
162
+ eligible.add(i);
163
+ while (remaining > 1e-9 && eligible.size > 0) {
164
+ let weight = 0;
165
+ for (const i of eligible)
166
+ weight += items[i].shrink;
167
+ if (weight === 0)
168
+ break;
169
+ let absorbed = 0;
170
+ for (const i of [...eligible]) {
171
+ const next = Math.max(sizes[i] - (remaining * items[i].shrink) / weight, mins[i]);
172
+ absorbed += sizes[i] - next;
173
+ sizes[i] = next;
174
+ if (next <= mins[i])
175
+ eligible.delete(i);
176
+ }
177
+ if (absorbed < 1e-9)
178
+ break;
179
+ remaining -= absorbed;
180
+ }
181
+ }
182
+ return sizes;
183
+ }
184
+ function report(opts, infeasible) {
185
+ if (typeof opts.report === "function")
186
+ opts.report(infeasible);
187
+ else if (opts.report)
188
+ asW(opts.report).value = infeasible ? 1 : 0;
189
+ }
@@ -0,0 +1,73 @@
1
+ /** A directed graph. Edges are `[from, to]`; nodes carry any identity. */
2
+ export interface Graph<N> {
3
+ readonly nodes: readonly N[];
4
+ readonly edges: readonly (readonly [N, N])[];
5
+ }
6
+ export type Direction = "TB" | "BT" | "LR" | "RL";
7
+ /** Intrinsic size of a node's box. */
8
+ export interface Size {
9
+ w: number;
10
+ h: number;
11
+ }
12
+ /** Top-left placement of a node's box. */
13
+ export interface Placement {
14
+ x: number;
15
+ y: number;
16
+ w: number;
17
+ h: number;
18
+ }
19
+ export interface LayeredOpts<N> {
20
+ direction?: Direction;
21
+ /** Centre-to-centre distance between adjacent layers. Default 90. */
22
+ layerGap?: number;
23
+ /** Minimum edge-to-edge distance within a layer. Default 28. */
24
+ nodeGap?: number;
25
+ /** Intrinsic node size. Default 46×34. */
26
+ sizeOf?: (n: N) => Size;
27
+ /** Crossing-reduction sweeps. Default 6. */
28
+ sweeps?: number;
29
+ /** Barycenter source: "both" (DAG), "down" (parents over children,
30
+ * the tree look), "up". Default "both". */
31
+ align?: "both" | "down" | "up";
32
+ }
33
+ /** Assign each node an integer layer so every edge increases layer by
34
+ * ≥1. Cycles are broken (back edges reversed for ranking only). The
35
+ * value is the longest path from a source — computed as the lower
36
+ * bound the `order` atoms narrow each layer cell to. */
37
+ export declare function rank<N>(g: Graph<N>): Map<N, number>;
38
+ /** Strongly-connected components (Tarjan), each a list of mutually
39
+ * reachable nodes, in reverse-topological order of the condensation.
40
+ * Singletons are size-1 components; a self-loop still reports size 1.
41
+ * The cyclic cores of a graph are exactly the components of size > 1. */
42
+ export declare function scc<N>(g: Graph<N>): N[][];
43
+ /** Count edge crossings given per-layer orderings (for tests / quality). */
44
+ export declare function crossings<N>(g: Graph<N>, layer: Map<N, number>, layers: N[][]): number;
45
+ /** Full layered layout → top-left placement per node. */
46
+ export declare function layered<N>(g: Graph<N>, opts?: LayeredOpts<N>): Map<N, Placement>;
47
+ /** Tree layout: parents centred over their children. A `layered` with
48
+ * downward barycenter and tighter defaults. */
49
+ export declare function tree<N>(g: Graph<N>, opts?: LayeredOpts<N>): Map<N, Placement>;
50
+ /** Radial layout: layers become concentric rings, cross-axis position
51
+ * becomes angle. Reads a `layered` (TB) result and re-maps to polar. */
52
+ export declare function radial<N>(g: Graph<N>, opts?: LayeredOpts<N>): Map<N, Placement>;
53
+ /** Recurrent-hierarchy layout: decompose into strongly-connected
54
+ * components, lay the condensation (a DAG of SCCs) out hierarchically,
55
+ * and draw every cyclic component as a ring centred on its condensation
56
+ * slot. The cycle closes by going around the circle — no backward edge.
57
+ * Singleton components are placed as ordinary nodes. */
58
+ export declare function recurrent<N>(g: Graph<N>, opts?: LayeredOpts<N>): Map<N, Placement>;
59
+ export interface LanesOpts<N> {
60
+ /** Row height (topological order axis). Default 56. */
61
+ rowGap?: number;
62
+ /** Lane width (column axis). Default 46. */
63
+ laneGap?: number;
64
+ sizeOf?: (n: N) => Size;
65
+ }
66
+ /** Git-style lane packing: nodes flow top-to-bottom in topological
67
+ * order (one row each), each assigned the first free column ("lane")
68
+ * that no live edge occupies. Branch points open lanes, merges free
69
+ * them. Expects a DAG whose `nodes` are in commit order (parents
70
+ * before children). */
71
+ export declare function lanes<N>(g: Graph<N>, opts?: LanesOpts<N>): Map<N, Placement>;
72
+ /** Bounding size of a placement map. */
73
+ export declare function extent<N>(p: Map<N, Placement>): Size;