@vibecook/ice 0.8.1 → 0.10.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/{chunk-VITC7U3J.js → chunk-5FQS7V2C.js} +82 -7
- package/dist/chunk-5FQS7V2C.js.map +1 -0
- package/dist/{chunk-M5SFRVMH.js → chunk-JWRHAM7L.js} +2 -2
- package/dist/{chunk-4BOR42FZ.js → chunk-MFTMPJUF.js} +9 -4
- package/dist/{chunk-4BOR42FZ.js.map → chunk-MFTMPJUF.js.map} +1 -1
- package/dist/devtools.js +1 -1
- package/dist/dom.js +2 -2
- package/dist/ground.js +646 -148
- package/dist/ground.js.map +1 -1
- package/dist/index.js +3 -1
- package/dist/r3f.js +3 -3
- package/dist/react.js +3 -3
- package/dist/types/packages/core/src/behavior/define-behavior.d.ts +11 -0
- package/dist/types/packages/core/src/behavior/types.d.ts +21 -0
- package/dist/types/packages/core/src/index.d.ts +1 -1
- package/dist/types/packages/core/src/settings/ground-config.d.ts +49 -1
- package/dist/types/packages/ground/src/index.d.ts +18 -1
- package/dist/types/packages/ground/src/passes/grid-classic.d.ts +30 -0
- package/dist/types/packages/ground/src/passes/grid-magnet.d.ts +31 -0
- package/dist/types/packages/ground/src/passes/grid.d.ts +19 -12
- package/dist/types/packages/ground/src/passes/magnet-collect.d.ts +63 -0
- package/dist/types/packages/ground/src/passes/wires-collect.d.ts +5 -1
- package/dist/types/packages/ground/src/poles.d.ts +47 -0
- package/dist/types/packages/react/src/infinite-canvas.d.ts +18 -1
- package/package.json +1 -1
- package/dist/chunk-VITC7U3J.js.map +0 -1
- /package/dist/{chunk-M5SFRVMH.js.map → chunk-JWRHAM7L.js.map} +0 -0
|
@@ -1623,6 +1623,10 @@ function defaultsOf(schema) {
|
|
|
1623
1623
|
for (const [name, spec] of Object.entries(schema)) out[name] = defaultValueOf(spec);
|
|
1624
1624
|
return out;
|
|
1625
1625
|
}
|
|
1626
|
+
var utf8 = new TextEncoder();
|
|
1627
|
+
function facetBytesOf(cell) {
|
|
1628
|
+
return utf8.encode(JSON.stringify(cell)).length;
|
|
1629
|
+
}
|
|
1626
1630
|
function signatureOf(spec, phase2) {
|
|
1627
1631
|
const schema = spec.schema ?? {};
|
|
1628
1632
|
return JSON.stringify({
|
|
@@ -1632,6 +1636,11 @@ function signatureOf(spec, phase2) {
|
|
|
1632
1636
|
version: spec.version ?? 1,
|
|
1633
1637
|
phase: phase2,
|
|
1634
1638
|
tickWhile: spec.tick?.while ?? "all",
|
|
1639
|
+
// The I19 byte claim is IDENTITY-BEARING: a redefinition that changes only
|
|
1640
|
+
// the claim is a different declaration (hosts compare descriptors; the
|
|
1641
|
+
// ensure-cache must agree). `?? null` because JSON.stringify drops
|
|
1642
|
+
// undefined-valued keys, which would alias "no claim" with "absent field".
|
|
1643
|
+
maxFacetBytes: spec.maxFacetBytes ?? null,
|
|
1635
1644
|
// Field ORDER is part of the shape: it is the generated component's column
|
|
1636
1645
|
// order, which the durable cell layout depends on.
|
|
1637
1646
|
schema: Object.entries(schema).map(([k, s]) => [k, s.kind, defaultValueOf(s)]),
|
|
@@ -1679,6 +1688,17 @@ function validate(name, spec, phase2) {
|
|
|
1679
1688
|
if (spec.budgetMs !== void 0 && (!Number.isFinite(spec.budgetMs) || spec.budgetMs <= 0)) {
|
|
1680
1689
|
fail2(name, `budgetMs must be a positive number (got ${String(spec.budgetMs)}).`);
|
|
1681
1690
|
}
|
|
1691
|
+
if (spec.maxFacetBytes !== void 0) {
|
|
1692
|
+
if (spec.store !== "ephemeral") {
|
|
1693
|
+
fail2(
|
|
1694
|
+
name,
|
|
1695
|
+
`"maxFacetBytes" is ephemeral-only \u2014 it bounds the published presence facet, and only ephemeral behaviors publish one (petition I19).`
|
|
1696
|
+
);
|
|
1697
|
+
}
|
|
1698
|
+
if (!Number.isSafeInteger(spec.maxFacetBytes) || spec.maxFacetBytes <= 0) {
|
|
1699
|
+
fail2(name, `maxFacetBytes must be a positive integer byte count (got ${String(spec.maxFacetBytes)}).`);
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1682
1702
|
for (const [fieldName, s] of Object.entries(spec.schema ?? {})) {
|
|
1683
1703
|
if (fieldName.length === 0) fail2(name, "schema field names must be non-empty.");
|
|
1684
1704
|
if (typeof s !== "object" || s === null || typeof s.kind !== "string") {
|
|
@@ -1817,6 +1837,7 @@ function describeBehavior(behavior) {
|
|
|
1817
1837
|
version: behavior.version,
|
|
1818
1838
|
phase: behavior.phase,
|
|
1819
1839
|
...behavior.budgetMs === void 0 ? {} : { budgetMs: behavior.budgetMs },
|
|
1840
|
+
...behavior.maxFacetBytes === void 0 ? {} : { maxFacetBytes: behavior.maxFacetBytes },
|
|
1820
1841
|
tickWhile: behavior.tickWhile,
|
|
1821
1842
|
schema: Object.entries(behavior.schema).map(([name, spec]) => ({
|
|
1822
1843
|
name,
|
|
@@ -1845,6 +1866,15 @@ function defineBehavior(name, spec) {
|
|
|
1845
1866
|
return existing;
|
|
1846
1867
|
}
|
|
1847
1868
|
const schema = spec.schema ?? {};
|
|
1869
|
+
const defaults = defaultsOf(schema);
|
|
1870
|
+
if (spec.maxFacetBytes !== void 0 && spec.store === "ephemeral") {
|
|
1871
|
+
const bytes = facetBytesOf(defaults);
|
|
1872
|
+
if (bytes > spec.maxFacetBytes) {
|
|
1873
|
+
throw new Error(
|
|
1874
|
+
`ice: defineBehavior("${name}") \u2014 the default facet is ${bytes} bytes, over the behavior's own maxFacetBytes=${spec.maxFacetBytes} claim. Nothing was registered.`
|
|
1875
|
+
);
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1848
1878
|
const raw = {};
|
|
1849
1879
|
for (const [fieldName, s] of Object.entries(schema)) raw[fieldName] = strataFieldOf(name, fieldName, s);
|
|
1850
1880
|
const component = ensureComponent(behaviorComponentName(name), raw);
|
|
@@ -1857,9 +1887,10 @@ function defineBehavior(name, spec) {
|
|
|
1857
1887
|
version: spec.version ?? 1,
|
|
1858
1888
|
phase: phase2,
|
|
1859
1889
|
budgetMs: spec.budgetMs,
|
|
1890
|
+
maxFacetBytes: spec.maxFacetBytes,
|
|
1860
1891
|
schema,
|
|
1861
1892
|
component,
|
|
1862
|
-
defaults
|
|
1893
|
+
defaults,
|
|
1863
1894
|
reads: spec.reads ?? [],
|
|
1864
1895
|
writes: spec.writes ?? [],
|
|
1865
1896
|
migrate: spec.migrate ?? {},
|
|
@@ -8486,6 +8517,15 @@ function createBehaviorRuntime(opts) {
|
|
|
8486
8517
|
if (!world.isAlive(peer)) return;
|
|
8487
8518
|
if (this.hookEntity !== void 0 && this.hookEntity !== peer) return;
|
|
8488
8519
|
const cell = cellForBehavior(world, this.b, peer, patch);
|
|
8520
|
+
const bound = this.b.maxFacetBytes;
|
|
8521
|
+
if (bound !== void 0) {
|
|
8522
|
+
const bytes = facetBytesOf(cell);
|
|
8523
|
+
if (bytes > bound) {
|
|
8524
|
+
throw new Error(
|
|
8525
|
+
`ice: behavior "${this.b.name}" ctx.write produced a ${bytes}-byte facet, over its declared maxFacetBytes=${bound} \u2014 the write was refused and the prior facet left intact.`
|
|
8526
|
+
);
|
|
8527
|
+
}
|
|
8528
|
+
}
|
|
8489
8529
|
if (world.has(peer, this.own)) presence.eph.edit(peer).set(this.own, cell);
|
|
8490
8530
|
else presence.eph.addComponent(peer, this.own, cell);
|
|
8491
8531
|
}
|
|
@@ -8627,6 +8667,11 @@ function createBehaviorRuntime(opts) {
|
|
|
8627
8667
|
},
|
|
8628
8668
|
attach(e, behavior, data) {
|
|
8629
8669
|
const other = behavior;
|
|
8670
|
+
if (other.store === "ephemeral") {
|
|
8671
|
+
throw new Error(
|
|
8672
|
+
`ice: behavior "${node.b.name}" called tx.attach("${other.name}") \u2014 an ephemeral behavior's facet is presence data and cannot be attached into the document.`
|
|
8673
|
+
);
|
|
8674
|
+
}
|
|
8630
8675
|
const cell = cellForBehavior(world, other, e, data ?? {});
|
|
8631
8676
|
if (world.has(e, other.component)) {
|
|
8632
8677
|
tx.edit(e).set(other.component, cell);
|
|
@@ -8635,6 +8680,11 @@ function createBehaviorRuntime(opts) {
|
|
|
8635
8680
|
}
|
|
8636
8681
|
},
|
|
8637
8682
|
detach(e, behavior) {
|
|
8683
|
+
if (behavior.store === "ephemeral") {
|
|
8684
|
+
throw new Error(
|
|
8685
|
+
`ice: behavior "${node.b.name}" called tx.detach("${behavior.name}") \u2014 ephemeral facets are withdrawn by the runtime (I17) or the presence layer's tombstones, never through the document.`
|
|
8686
|
+
);
|
|
8687
|
+
}
|
|
8638
8688
|
tx.removeComponent(e, behavior.component);
|
|
8639
8689
|
}
|
|
8640
8690
|
};
|
|
@@ -8710,6 +8760,11 @@ function createBehaviorRuntime(opts) {
|
|
|
8710
8760
|
`ice: engine.behaviors.attach("${b.name}") \u2014 durable attachment is a DOCUMENT op: use tx.attach inside a transaction so it syncs and undoes.`
|
|
8711
8761
|
);
|
|
8712
8762
|
}
|
|
8763
|
+
if (b.store === "ephemeral") {
|
|
8764
|
+
throw new Error(
|
|
8765
|
+
`ice: engine.behaviors.attach("${b.name}") \u2014 an ephemeral behavior's facet is minted by the runtime on the local peer; it cannot be attached to an entity.`
|
|
8766
|
+
);
|
|
8767
|
+
}
|
|
8713
8768
|
const cell = cellForBehavior(world, b, e, data ?? {});
|
|
8714
8769
|
if (world.has(e, b.component)) world.edit(e).set(b.component, cell);
|
|
8715
8770
|
else world.addComponent(e, b.component, cell);
|
|
@@ -8720,6 +8775,11 @@ function createBehaviorRuntime(opts) {
|
|
|
8720
8775
|
`ice: engine.behaviors.detach("${b.name}") \u2014 durable detachment is a DOCUMENT op: use tx.detach inside a transaction.`
|
|
8721
8776
|
);
|
|
8722
8777
|
}
|
|
8778
|
+
if (b.store === "ephemeral") {
|
|
8779
|
+
throw new Error(
|
|
8780
|
+
`ice: engine.behaviors.detach("${b.name}") \u2014 ephemeral facets are withdrawn by the runtime (I17) or the presence layer's tombstones, never detached through the world.`
|
|
8781
|
+
);
|
|
8782
|
+
}
|
|
8723
8783
|
if (world.has(e, b.component)) world.removeComponent(e, b.component);
|
|
8724
8784
|
},
|
|
8725
8785
|
has: (e, b) => world.isAlive(e) && world.has(e, b.component),
|
|
@@ -9430,6 +9490,20 @@ function installWidgetRuntime(engine, opts = {}) {
|
|
|
9430
9490
|
}
|
|
9431
9491
|
|
|
9432
9492
|
// ../core/src/settings/ground-config.ts
|
|
9493
|
+
var DEFAULT_GRID_MAGNET_CONFIG = {
|
|
9494
|
+
enabled: false,
|
|
9495
|
+
glyph: "needle",
|
|
9496
|
+
reach: 60,
|
|
9497
|
+
polarity: 1,
|
|
9498
|
+
widgets: true,
|
|
9499
|
+
widgetStrength: 1,
|
|
9500
|
+
widgetRadius: 12,
|
|
9501
|
+
alwaysAlign: false,
|
|
9502
|
+
needleLength: 5,
|
|
9503
|
+
needleWidth: 0.55,
|
|
9504
|
+
maxSources: 256,
|
|
9505
|
+
fadeZoom: 0
|
|
9506
|
+
};
|
|
9433
9507
|
var DEFAULT_GRID_CONFIG = {
|
|
9434
9508
|
spacings: [20, 100, 500],
|
|
9435
9509
|
dotColor: [0.75, 0.77, 0.8],
|
|
@@ -9986,7 +10060,7 @@ var K_SNAPSHOT_OFFER = 2;
|
|
|
9986
10060
|
var K_SNAPSHOT = 3;
|
|
9987
10061
|
var K_UPDATE = 4;
|
|
9988
10062
|
var K_PRESENCE = 5;
|
|
9989
|
-
var
|
|
10063
|
+
var utf82 = new TextEncoder();
|
|
9990
10064
|
var fromUtf8 = new TextDecoder();
|
|
9991
10065
|
var defaultClock = {
|
|
9992
10066
|
setTimeout: (fn, ms) => setTimeout(fn, ms),
|
|
@@ -10000,7 +10074,7 @@ function frame(kind, payload) {
|
|
|
10000
10074
|
return out;
|
|
10001
10075
|
}
|
|
10002
10076
|
function frameSnapshot(targetId, snapshot) {
|
|
10003
|
-
const id =
|
|
10077
|
+
const id = utf82.encode(targetId);
|
|
10004
10078
|
const out = new Uint8Array(1 + 2 + id.length + snapshot.length);
|
|
10005
10079
|
out[0] = K_SNAPSHOT;
|
|
10006
10080
|
out[1] = id.length & 255;
|
|
@@ -10174,7 +10248,7 @@ function joinDoc(world, channel, opts = {}) {
|
|
|
10174
10248
|
active = false;
|
|
10175
10249
|
buffered.length = 0;
|
|
10176
10250
|
opts.onSession?.(void 0);
|
|
10177
|
-
send(frame(K_HELLO,
|
|
10251
|
+
send(frame(K_HELLO, utf82.encode(joinerId)));
|
|
10178
10252
|
armTimeout();
|
|
10179
10253
|
};
|
|
10180
10254
|
const onFrame = (bytes) => {
|
|
@@ -10222,7 +10296,7 @@ function joinDoc(world, channel, opts = {}) {
|
|
|
10222
10296
|
if (unsubPresence !== void 0) roomSubs.push(unsubPresence);
|
|
10223
10297
|
const begin = () => {
|
|
10224
10298
|
if (left) return;
|
|
10225
|
-
send(frame(K_HELLO,
|
|
10299
|
+
send(frame(K_HELLO, utf82.encode(joinerId)));
|
|
10226
10300
|
if (left) return;
|
|
10227
10301
|
armTimeout();
|
|
10228
10302
|
};
|
|
@@ -10844,7 +10918,7 @@ import {
|
|
|
10844
10918
|
Local as Local3
|
|
10845
10919
|
} from "@vibecook/strata-ecs";
|
|
10846
10920
|
import { DurableUndoStatus } from "@vibecook/strata-ecs/durable";
|
|
10847
|
-
var CORE_VERSION = "0.
|
|
10921
|
+
var CORE_VERSION = "0.10.0";
|
|
10848
10922
|
|
|
10849
10923
|
export {
|
|
10850
10924
|
defineSchemaOnce,
|
|
@@ -11098,6 +11172,7 @@ export {
|
|
|
11098
11172
|
createMeasureIngest,
|
|
11099
11173
|
createWidgetRuntime,
|
|
11100
11174
|
installWidgetRuntime,
|
|
11175
|
+
DEFAULT_GRID_MAGNET_CONFIG,
|
|
11101
11176
|
DEFAULT_GRID_CONFIG,
|
|
11102
11177
|
DEFAULT_WIRES_CONFIG,
|
|
11103
11178
|
DEFAULT_SNAP_GUIDES_CONFIG,
|
|
@@ -11129,4 +11204,4 @@ export {
|
|
|
11129
11204
|
Local3 as Local,
|
|
11130
11205
|
DurableUndoStatus
|
|
11131
11206
|
};
|
|
11132
|
-
//# sourceMappingURL=chunk-
|
|
11207
|
+
//# sourceMappingURL=chunk-5FQS7V2C.js.map
|