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
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
// relations.ts — propagator combinators (the solver-role layer).
|
|
2
|
-
//
|
|
3
|
-
// Where lenses define values, these propagators impose relations
|
|
4
|
-
// between cells that already exist for other reasons (handles,
|
|
5
|
-
// animation targets, external signals). Each combinator returns
|
|
6
|
-
// `Propagator`s for `p.add(...)`.
|
|
7
|
-
//
|
|
8
|
-
// Arithmetic combinators dispatch on the value class's `linear`
|
|
9
|
-
// trait, so `add(a, b, c)` works for `Num`, `Vec`, `Box`, `Pose`,
|
|
10
|
-
// anything `Linear<T>`.
|
|
11
|
-
import { isCell, reader, requireLinear } from "../core/index.js";
|
|
12
|
-
import { propagator } from "./propagator.js";
|
|
13
|
-
/** `a + b = c`. Three propagators (any two derive the third). */
|
|
14
|
-
export function add(a, b, c) {
|
|
15
|
-
const L = requireLinear(a);
|
|
16
|
-
return [
|
|
17
|
-
propagator([a, b], [c], () => {
|
|
18
|
-
c.value = L.add(a.value, b.value);
|
|
19
|
-
}),
|
|
20
|
-
propagator([a, c], [b], () => {
|
|
21
|
-
b.value = L.sub(c.value, a.value);
|
|
22
|
-
}),
|
|
23
|
-
propagator([b, c], [a], () => {
|
|
24
|
-
a.value = L.sub(c.value, b.value);
|
|
25
|
-
}),
|
|
26
|
-
];
|
|
27
|
-
}
|
|
28
|
-
/** `a - b = c`. b-deriving propagator listed before a-deriving so
|
|
29
|
-
* drag-on-c updates b first (matches "c changed because b changed"). */
|
|
30
|
-
export function sub(a, b, c) {
|
|
31
|
-
const L = requireLinear(a);
|
|
32
|
-
return [
|
|
33
|
-
propagator([a, b], [c], () => {
|
|
34
|
-
c.value = L.sub(a.value, b.value);
|
|
35
|
-
}),
|
|
36
|
-
propagator([a, c], [b], () => {
|
|
37
|
-
b.value = L.sub(a.value, c.value);
|
|
38
|
-
}),
|
|
39
|
-
propagator([b, c], [a], () => {
|
|
40
|
-
a.value = L.add(b.value, c.value);
|
|
41
|
-
}),
|
|
42
|
-
];
|
|
43
|
-
}
|
|
44
|
-
/** `(a + b) / 2 = m` (midpoint). Drag m → both a and b translate
|
|
45
|
-
* by the delta; drag a or b → m re-derives. */
|
|
46
|
-
export function mid(a, b, m) {
|
|
47
|
-
const L = requireLinear(a);
|
|
48
|
-
return [
|
|
49
|
-
propagator([a, b], [m], () => {
|
|
50
|
-
m.value = L.scale(L.add(a.value, b.value), 0.5);
|
|
51
|
-
}),
|
|
52
|
-
propagator([m], [a, b], () => {
|
|
53
|
-
const cur = L.scale(L.add(a.value, b.value), 0.5);
|
|
54
|
-
const delta = L.sub(m.value, cur);
|
|
55
|
-
a.value = L.add(a.value, delta);
|
|
56
|
-
b.value = L.add(b.value, delta);
|
|
57
|
-
}),
|
|
58
|
-
];
|
|
59
|
-
}
|
|
60
|
-
/** Centroid of N values: `c = mean(...vs)`. Drag any vertex →
|
|
61
|
-
* centroid follows; drag centroid → all vertices translate by the
|
|
62
|
-
* delta (rigid translation of the cluster). */
|
|
63
|
-
export function centroid(c, ...vs) {
|
|
64
|
-
if (vs.length === 0)
|
|
65
|
-
return [];
|
|
66
|
-
const L = requireLinear(c);
|
|
67
|
-
const inv = 1 / vs.length;
|
|
68
|
-
const computeMean = () => {
|
|
69
|
-
let acc = vs[0].value;
|
|
70
|
-
for (let i = 1; i < vs.length; i++)
|
|
71
|
-
acc = L.add(acc, vs[i].value);
|
|
72
|
-
return L.scale(acc, inv);
|
|
73
|
-
};
|
|
74
|
-
return [
|
|
75
|
-
propagator(vs, [c], () => {
|
|
76
|
-
c.value = computeMean();
|
|
77
|
-
}),
|
|
78
|
-
propagator([c], vs, () => {
|
|
79
|
-
const cur = computeMean();
|
|
80
|
-
const delta = L.sub(c.value, cur);
|
|
81
|
-
for (const v of vs)
|
|
82
|
-
v.value = L.add(v.value, delta);
|
|
83
|
-
}),
|
|
84
|
-
];
|
|
85
|
-
}
|
|
86
|
-
/** `a * b = c` (scalar). Three propagators; division-by-zero skips
|
|
87
|
-
* the inverse direction. */
|
|
88
|
-
export function mul(a, b, c) {
|
|
89
|
-
return [
|
|
90
|
-
propagator([a, b], [c], () => {
|
|
91
|
-
c.value = a.value * b.value;
|
|
92
|
-
}),
|
|
93
|
-
propagator([a, c], [b], () => {
|
|
94
|
-
const av = a.value;
|
|
95
|
-
if (av !== 0)
|
|
96
|
-
b.value = c.value / av;
|
|
97
|
-
}),
|
|
98
|
-
propagator([b, c], [a], () => {
|
|
99
|
-
const bv = b.value;
|
|
100
|
-
if (bv !== 0)
|
|
101
|
-
a.value = c.value / bv;
|
|
102
|
-
}),
|
|
103
|
-
];
|
|
104
|
-
}
|
|
105
|
-
/** `a / b = k` constant aspect ratio (scalar). */
|
|
106
|
-
export function aspectRatio(a, b, k) {
|
|
107
|
-
return [
|
|
108
|
-
propagator([a], [b], () => {
|
|
109
|
-
b.value = a.value / k;
|
|
110
|
-
}),
|
|
111
|
-
propagator([b], [a], () => {
|
|
112
|
-
a.value = b.value * k;
|
|
113
|
-
}),
|
|
114
|
-
];
|
|
115
|
-
}
|
|
116
|
-
/** `a₁ + a₂ + … + aₙ = total` (scalar). N+1 propagators: parts → total,
|
|
117
|
-
* and total + (n-1 parts) → missing part for each i. */
|
|
118
|
-
export function sum(parts, total) {
|
|
119
|
-
if (parts.length === 0)
|
|
120
|
-
return [];
|
|
121
|
-
if (parts.length === 1)
|
|
122
|
-
return eq(parts[0], total);
|
|
123
|
-
const props = [];
|
|
124
|
-
props.push(propagator(parts, [total], () => {
|
|
125
|
-
let s = 0;
|
|
126
|
-
for (const p of parts)
|
|
127
|
-
s += p.value;
|
|
128
|
-
total.value = s;
|
|
129
|
-
}));
|
|
130
|
-
for (let i = 0; i < parts.length; i++) {
|
|
131
|
-
const missing = parts[i];
|
|
132
|
-
const others = parts.filter((_, j) => j !== i);
|
|
133
|
-
props.push(propagator([total, ...others], [missing], () => {
|
|
134
|
-
let s = 0;
|
|
135
|
-
for (const o of others)
|
|
136
|
-
s += o.value;
|
|
137
|
-
missing.value = total.value - s;
|
|
138
|
-
}));
|
|
139
|
-
}
|
|
140
|
-
return props;
|
|
141
|
-
}
|
|
142
|
-
/** `a = b`. Bidirectional. Works for any value type. */
|
|
143
|
-
export function eq(a, b) {
|
|
144
|
-
return [
|
|
145
|
-
propagator([a], [b], () => {
|
|
146
|
-
b.value = a.value;
|
|
147
|
-
}),
|
|
148
|
-
propagator([b], [a], () => {
|
|
149
|
-
a.value = b.value;
|
|
150
|
-
}),
|
|
151
|
-
];
|
|
152
|
-
}
|
|
153
|
-
/** Pin a signal to a fixed value. Subscribes to its own target so
|
|
154
|
-
* external writes that diverge from the constant get restored. */
|
|
155
|
-
export function constant(s, v) {
|
|
156
|
-
return propagator([s], [s], () => {
|
|
157
|
-
s.value = v;
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
/** Variadic mutual equality: all cells share the same value. Drag
|
|
161
|
-
* any one → others follow. N(N-1) propagators. */
|
|
162
|
-
export function align(...cells) {
|
|
163
|
-
const props = [];
|
|
164
|
-
for (let i = 0; i < cells.length; i++) {
|
|
165
|
-
for (let j = 0; j < cells.length; j++) {
|
|
166
|
-
if (i === j)
|
|
167
|
-
continue;
|
|
168
|
-
const src = cells[i];
|
|
169
|
-
const dst = cells[j];
|
|
170
|
-
props.push(propagator([src], [dst], () => {
|
|
171
|
-
dst.value = src.value;
|
|
172
|
-
}));
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return props;
|
|
176
|
-
}
|
|
177
|
-
/** Point at parameter `t ∈ [0,1]` along segment a → b.
|
|
178
|
-
*
|
|
179
|
-
* Drag p (default): project p onto the segment, update t (clamped).
|
|
180
|
-
* Drag p with `freeze: 'a'`: a stays, b moves to fit.
|
|
181
|
-
* Drag p with `freeze: 'b'`: b stays, a moves to fit. */
|
|
182
|
-
export function between(a, b, t, p, freeze) {
|
|
183
|
-
const props = [];
|
|
184
|
-
// Forward: p = a + t * (b - a).
|
|
185
|
-
props.push(propagator([a.x, a.y, b.x, b.y, t], [p.x, p.y], () => {
|
|
186
|
-
const tv = t.value;
|
|
187
|
-
p.x.value = a.x.value + tv * (b.x.value - a.x.value);
|
|
188
|
-
p.y.value = a.y.value + tv * (b.y.value - a.y.value);
|
|
189
|
-
}));
|
|
190
|
-
if (freeze === "b") {
|
|
191
|
-
props.push(propagator([p.x, p.y, t, b.x, b.y], [a.x, a.y], () => {
|
|
192
|
-
const tv = t.value;
|
|
193
|
-
if (tv === 1)
|
|
194
|
-
return;
|
|
195
|
-
a.x.value = (p.x.value - tv * b.x.value) / (1 - tv);
|
|
196
|
-
a.y.value = (p.y.value - tv * b.y.value) / (1 - tv);
|
|
197
|
-
}));
|
|
198
|
-
}
|
|
199
|
-
else if (freeze === "a") {
|
|
200
|
-
props.push(propagator([p.x, p.y, t, a.x, a.y], [b.x, b.y], () => {
|
|
201
|
-
const tv = t.value;
|
|
202
|
-
if (tv === 0)
|
|
203
|
-
return;
|
|
204
|
-
b.x.value = (p.x.value - (1 - tv) * a.x.value) / tv;
|
|
205
|
-
b.y.value = (p.y.value - (1 - tv) * a.y.value) / tv;
|
|
206
|
-
}));
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
props.push(propagator([p.x, p.y, a.x, a.y, b.x, b.y], [t], () => {
|
|
210
|
-
const dx = b.x.value - a.x.value;
|
|
211
|
-
const dy = b.y.value - a.y.value;
|
|
212
|
-
const len2 = dx * dx + dy * dy;
|
|
213
|
-
if (len2 < 1e-12)
|
|
214
|
-
return;
|
|
215
|
-
const px = p.x.value - a.x.value;
|
|
216
|
-
const py = p.y.value - a.y.value;
|
|
217
|
-
t.value = Math.max(0, Math.min(1, (px * dx + py * dy) / len2));
|
|
218
|
-
}));
|
|
219
|
-
}
|
|
220
|
-
return props;
|
|
221
|
-
}
|
|
222
|
-
/** Keep `|a − b| = d`. Drag a → b moves along (b−a) to maintain
|
|
223
|
-
* distance; drag b → symmetric. `d` may be a number, a Num signal,
|
|
224
|
-
* a computed (e.g. `|p − q|` driven by other points), or a closure. */
|
|
225
|
-
export function keepDistance(a, b, d) {
|
|
226
|
-
const dRead = reader(d);
|
|
227
|
-
const dDeps = isCell(d) ? [d] : [];
|
|
228
|
-
return [
|
|
229
|
-
propagator([a.x, a.y, ...dDeps], [b.x, b.y], () => {
|
|
230
|
-
const dx = b.x.value - a.x.value;
|
|
231
|
-
const dy = b.y.value - a.y.value;
|
|
232
|
-
const cur = Math.hypot(dx, dy);
|
|
233
|
-
if (cur < 1e-12)
|
|
234
|
-
return;
|
|
235
|
-
const k = dRead() / cur;
|
|
236
|
-
b.x.value = a.x.value + dx * k;
|
|
237
|
-
b.y.value = a.y.value + dy * k;
|
|
238
|
-
}),
|
|
239
|
-
propagator([b.x, b.y, ...dDeps], [a.x, a.y], () => {
|
|
240
|
-
const dx = a.x.value - b.x.value;
|
|
241
|
-
const dy = a.y.value - b.y.value;
|
|
242
|
-
const cur = Math.hypot(dx, dy);
|
|
243
|
-
if (cur < 1e-12)
|
|
244
|
-
return;
|
|
245
|
-
const k = dRead() / cur;
|
|
246
|
-
a.x.value = b.x.value + dx * k;
|
|
247
|
-
a.y.value = b.y.value + dy * k;
|
|
248
|
-
}),
|
|
249
|
-
];
|
|
250
|
-
}
|
|
251
|
-
/** Project `p` onto the line through `a → b`. p sticks to the line. */
|
|
252
|
-
export function onLine(p, a, b) {
|
|
253
|
-
return propagator([p.x, p.y, a.x, a.y, b.x, b.y], [p.x, p.y], () => {
|
|
254
|
-
const dx = b.x.value - a.x.value;
|
|
255
|
-
const dy = b.y.value - a.y.value;
|
|
256
|
-
const len2 = dx * dx + dy * dy;
|
|
257
|
-
if (len2 < 1e-12)
|
|
258
|
-
return;
|
|
259
|
-
const px = p.x.value - a.x.value;
|
|
260
|
-
const py = p.y.value - a.y.value;
|
|
261
|
-
const t = (px * dx + py * dy) / len2;
|
|
262
|
-
const newX = a.x.value + t * dx;
|
|
263
|
-
const newY = a.y.value + t * dy;
|
|
264
|
-
if (Math.abs(newX - p.x.value) > 1e-9 || Math.abs(newY - p.y.value) > 1e-9) {
|
|
265
|
-
p.x.value = newX;
|
|
266
|
-
p.y.value = newY;
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
/** Keep `p` on a circle of radius `r` around `c`. `r` may be a
|
|
271
|
-
* number, a Num signal, a computed, or a closure. */
|
|
272
|
-
export function onCircle(p, c, r) {
|
|
273
|
-
const rRead = reader(r);
|
|
274
|
-
const rDeps = isCell(r) ? [r] : [];
|
|
275
|
-
return propagator([p.x, p.y, c.x, c.y, ...rDeps], [p.x, p.y], () => {
|
|
276
|
-
const dx = p.x.value - c.x.value;
|
|
277
|
-
const dy = p.y.value - c.y.value;
|
|
278
|
-
const cur = Math.hypot(dx, dy);
|
|
279
|
-
if (cur < 1e-12)
|
|
280
|
-
return;
|
|
281
|
-
const k = rRead() / cur;
|
|
282
|
-
const newX = c.x.value + dx * k;
|
|
283
|
-
const newY = c.y.value + dy * k;
|
|
284
|
-
if (Math.abs(newX - p.x.value) > 1e-9 || Math.abs(newY - p.y.value) > 1e-9) {
|
|
285
|
-
p.x.value = newX;
|
|
286
|
-
p.y.value = newY;
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
}
|
|
290
|
-
/** Reflect `src` across the line through `a → b` to get `dst`.
|
|
291
|
-
* Bidirectional. */
|
|
292
|
-
export function reflect(src, a, b, dst) {
|
|
293
|
-
const reflectPt = (px, py, ax, ay, bx, by) => {
|
|
294
|
-
const dx = bx - ax;
|
|
295
|
-
const dy = by - ay;
|
|
296
|
-
const len2 = dx * dx + dy * dy;
|
|
297
|
-
if (len2 < 1e-12)
|
|
298
|
-
return [px, py];
|
|
299
|
-
const t = ((px - ax) * dx + (py - ay) * dy) / len2;
|
|
300
|
-
const cx = ax + t * dx;
|
|
301
|
-
const cy = ay + t * dy;
|
|
302
|
-
return [2 * cx - px, 2 * cy - py];
|
|
303
|
-
};
|
|
304
|
-
return [
|
|
305
|
-
propagator([src.x, src.y, a.x, a.y, b.x, b.y], [dst.x, dst.y], () => {
|
|
306
|
-
const [x, y] = reflectPt(src.x.value, src.y.value, a.x.value, a.y.value, b.x.value, b.y.value);
|
|
307
|
-
dst.x.value = x;
|
|
308
|
-
dst.y.value = y;
|
|
309
|
-
}),
|
|
310
|
-
propagator([dst.x, dst.y, a.x, a.y, b.x, b.y], [src.x, src.y], () => {
|
|
311
|
-
const [x, y] = reflectPt(dst.x.value, dst.y.value, a.x.value, a.y.value, b.x.value, b.y.value);
|
|
312
|
-
src.x.value = x;
|
|
313
|
-
src.y.value = y;
|
|
314
|
-
}),
|
|
315
|
-
];
|
|
316
|
-
}
|
|
317
|
-
/** "These cells must contain DIFFERENT values." If any cell is a
|
|
318
|
-
* singleton {v}, eliminate v from the others. */
|
|
319
|
-
export function allDifferent(...cells) {
|
|
320
|
-
const props = [];
|
|
321
|
-
for (let i = 0; i < cells.length; i++) {
|
|
322
|
-
for (let j = 0; j < cells.length; j++) {
|
|
323
|
-
if (i === j)
|
|
324
|
-
continue;
|
|
325
|
-
const src = cells[i];
|
|
326
|
-
const dst = cells[j];
|
|
327
|
-
props.push(propagator([src], [dst], () => {
|
|
328
|
-
const sv = src.value;
|
|
329
|
-
if (sv.size !== 1)
|
|
330
|
-
return;
|
|
331
|
-
const [only] = sv;
|
|
332
|
-
const dv = dst.value;
|
|
333
|
-
if (!dv.has(only))
|
|
334
|
-
return;
|
|
335
|
-
const next = new Set(dv);
|
|
336
|
-
next.delete(only);
|
|
337
|
-
if (next.size !== dv.size)
|
|
338
|
-
dst.value = next;
|
|
339
|
-
}));
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
return props;
|
|
343
|
-
}
|