@yagejs/core 0.4.0 → 0.6.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/index.cjs +581 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +378 -17
- package/dist/index.d.ts +378 -17
- package/dist/index.js +563 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -110,6 +110,8 @@ __export(index_exports, {
|
|
|
110
110
|
Sequence: () => Sequence,
|
|
111
111
|
SerializableRegistry: () => SerializableRegistry,
|
|
112
112
|
ServiceKey: () => ServiceKey,
|
|
113
|
+
StoreMigrationMissingError: () => StoreMigrationMissingError,
|
|
114
|
+
StoreVersionTooNewError: () => StoreVersionTooNewError,
|
|
113
115
|
System: () => System,
|
|
114
116
|
SystemScheduler: () => SystemScheduler,
|
|
115
117
|
SystemSchedulerKey: () => SystemSchedulerKey,
|
|
@@ -119,16 +121,25 @@ __export(index_exports, {
|
|
|
119
121
|
Tween: () => Tween,
|
|
120
122
|
VERSION: () => VERSION,
|
|
121
123
|
Vec2: () => Vec2,
|
|
124
|
+
_clearStoreRegistryForTesting: () => _clearStoreRegistryForTesting,
|
|
125
|
+
_resetAllStoresForTesting: () => _resetAllStoresForTesting,
|
|
122
126
|
_resetEntityIdCounter: () => _resetEntityIdCounter,
|
|
123
127
|
advanceFrames: () => advanceFrames,
|
|
128
|
+
createAtom: () => createAtom,
|
|
124
129
|
createDefaultRandomSeed: () => createDefaultRandomSeed,
|
|
125
130
|
createKeyframeTrack: () => createKeyframeTrack,
|
|
126
131
|
createMockEntity: () => createMockEntity,
|
|
127
132
|
createMockScene: () => createMockScene,
|
|
128
133
|
createRandomService: () => createRandomService,
|
|
134
|
+
createStore: () => createStore,
|
|
129
135
|
createTestEngine: () => createTestEngine,
|
|
136
|
+
dateCodec: () => dateCodec,
|
|
130
137
|
defineBlueprint: () => defineBlueprint,
|
|
138
|
+
defineCounter: () => defineCounter,
|
|
131
139
|
defineEvent: () => defineEvent,
|
|
140
|
+
defineMap: () => defineMap,
|
|
141
|
+
defineSet: () => defineSet,
|
|
142
|
+
defineStore: () => defineStore,
|
|
132
143
|
defineTrait: () => defineTrait,
|
|
133
144
|
easeInOutQuad: () => easeInOutQuad,
|
|
134
145
|
easeInQuad: () => easeInQuad,
|
|
@@ -139,14 +150,20 @@ __export(index_exports, {
|
|
|
139
150
|
getSerializableType: () => getSerializableType,
|
|
140
151
|
globalRandom: () => globalRandom,
|
|
141
152
|
interpolate: () => interpolate,
|
|
153
|
+
isPointerConsumeContainer: () => isPointerConsumeContainer,
|
|
142
154
|
isSerializable: () => isSerializable,
|
|
155
|
+
jsonCodec: () => jsonCodec,
|
|
143
156
|
makeEntityScopedQueue: () => makeEntityScopedQueue,
|
|
144
157
|
makeGlobalScopedQueue: () => makeGlobalScopedQueue,
|
|
145
158
|
makeSceneScopedQueue: () => makeSceneScopedQueue,
|
|
159
|
+
mapCodec: () => mapCodec,
|
|
160
|
+
markPointerConsumeContainer: () => markPointerConsumeContainer,
|
|
146
161
|
normalizeSeed: () => normalizeSeed,
|
|
147
162
|
resolveTransition: () => resolveTransition,
|
|
148
163
|
serializable: () => serializable,
|
|
149
|
-
|
|
164
|
+
setCodec: () => setCodec,
|
|
165
|
+
trait: () => trait,
|
|
166
|
+
unmarkPointerConsumeContainer: () => unmarkPointerConsumeContainer
|
|
150
167
|
});
|
|
151
168
|
module.exports = __toCommonJS(index_exports);
|
|
152
169
|
|
|
@@ -1240,6 +1257,13 @@ var Entity = class {
|
|
|
1240
1257
|
name;
|
|
1241
1258
|
/** Tags for group queries. */
|
|
1242
1259
|
tags;
|
|
1260
|
+
/**
|
|
1261
|
+
* Stable identity key, scene-scoped. Set at spawn-time when
|
|
1262
|
+
* `options.key` is passed to `scene.spawn` / `entity.spawnChild`;
|
|
1263
|
+
* `undefined` otherwise. Used with `scene.findByKey` and as a stable
|
|
1264
|
+
* id in persistent stores (e.g. `defineSet<string>("world.opened")`).
|
|
1265
|
+
*/
|
|
1266
|
+
key;
|
|
1243
1267
|
components = /* @__PURE__ */ new Map();
|
|
1244
1268
|
_destroyed = false;
|
|
1245
1269
|
_scene = null;
|
|
@@ -1310,17 +1334,21 @@ var Entity = class {
|
|
|
1310
1334
|
this._scene._addExistingEntity(child);
|
|
1311
1335
|
}
|
|
1312
1336
|
}
|
|
1313
|
-
spawnChild(name,
|
|
1337
|
+
spawnChild(name, classOrBlueprintOrOptions, paramsOrOptions, maybeOptions) {
|
|
1314
1338
|
const scene = this.scene;
|
|
1315
1339
|
if (this._children?.has(name)) {
|
|
1316
1340
|
throw new Error(
|
|
1317
1341
|
`Entity "${this.name}" already has a child named "${name}".`
|
|
1318
1342
|
);
|
|
1319
1343
|
}
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
)
|
|
1344
|
+
let child;
|
|
1345
|
+
if (classOrBlueprintOrOptions === void 0) {
|
|
1346
|
+
child = scene.spawn(name);
|
|
1347
|
+
} else if (typeof classOrBlueprintOrOptions === "object" && !("build" in classOrBlueprintOrOptions)) {
|
|
1348
|
+
child = scene.spawn(name, classOrBlueprintOrOptions);
|
|
1349
|
+
} else {
|
|
1350
|
+
child = scene.spawn(classOrBlueprintOrOptions, paramsOrOptions, maybeOptions);
|
|
1351
|
+
}
|
|
1324
1352
|
this.addChild(name, child);
|
|
1325
1353
|
return child;
|
|
1326
1354
|
}
|
|
@@ -1463,6 +1491,19 @@ var Entity = class {
|
|
|
1463
1491
|
}
|
|
1464
1492
|
return false;
|
|
1465
1493
|
}
|
|
1494
|
+
/**
|
|
1495
|
+
* Return the stable key, or throw if this entity was spawned without one.
|
|
1496
|
+
* Use inside component `setup()` when the component depends on identity
|
|
1497
|
+
* (e.g. reading from a `defineSet` keyed by entity id).
|
|
1498
|
+
*/
|
|
1499
|
+
requireKey() {
|
|
1500
|
+
if (this.key === void 0) {
|
|
1501
|
+
throw new Error(
|
|
1502
|
+
`Entity "${this.name}" (id=${this.id}) has no stable key. Pass { key: "..." } to scene.spawn(...) or entity.spawnChild(...).`
|
|
1503
|
+
);
|
|
1504
|
+
}
|
|
1505
|
+
return this.key;
|
|
1506
|
+
}
|
|
1466
1507
|
/**
|
|
1467
1508
|
* Internal: set the scene and callbacks. Called by Scene.spawn().
|
|
1468
1509
|
* @internal
|
|
@@ -1471,6 +1512,20 @@ var Entity = class {
|
|
|
1471
1512
|
this._scene = scene;
|
|
1472
1513
|
this.callbacks = callbacks;
|
|
1473
1514
|
}
|
|
1515
|
+
/**
|
|
1516
|
+
* Internal: assign the stable identity key. Called by `Scene._registerKey`
|
|
1517
|
+
* during spawn. Throws if the entity already has a key — keys are
|
|
1518
|
+
* immutable for an entity's lifetime.
|
|
1519
|
+
* @internal
|
|
1520
|
+
*/
|
|
1521
|
+
_setKey(key) {
|
|
1522
|
+
if (this.key !== void 0) {
|
|
1523
|
+
throw new Error(
|
|
1524
|
+
`Entity "${this.name}" already has key "${this.key}".`
|
|
1525
|
+
);
|
|
1526
|
+
}
|
|
1527
|
+
this.key = key;
|
|
1528
|
+
}
|
|
1474
1529
|
};
|
|
1475
1530
|
|
|
1476
1531
|
// src/QueryCache.ts
|
|
@@ -1907,11 +1962,30 @@ var Inspector = class {
|
|
|
1907
1962
|
mouseUp: /* @__PURE__ */ __name((button = 0) => {
|
|
1908
1963
|
this.requireInputManager().firePointerUp(button);
|
|
1909
1964
|
}, "mouseUp"),
|
|
1910
|
-
|
|
1911
|
-
|
|
1965
|
+
/**
|
|
1966
|
+
* Inject a synthetic pointer-move with full pointer addressing. Pass `opts`
|
|
1967
|
+
* with `id` / `type: "touch"` to drive a specific finger; defaults match
|
|
1968
|
+
* the primary mouse pointer (same as `mouseMove`).
|
|
1969
|
+
*/
|
|
1970
|
+
pointerMove: /* @__PURE__ */ __name((x, y, opts) => {
|
|
1971
|
+
this.requireInputManager().firePointerMove(x, y, opts);
|
|
1972
|
+
}, "pointerMove"),
|
|
1973
|
+
/**
|
|
1974
|
+
* Inject a synthetic pointer-down. With `opts.id` and `opts.type: "touch"`
|
|
1975
|
+
* this drives a multi-touch contact, exercising `getPointers()`,
|
|
1976
|
+
* per-pointer event hooks, and the any-pointer aggregate for `MouseLeft`.
|
|
1977
|
+
*/
|
|
1978
|
+
pointerDown: /* @__PURE__ */ __name((button = 0, opts) => {
|
|
1979
|
+
this.requireInputManager().firePointerDown(button, opts);
|
|
1980
|
+
}, "pointerDown"),
|
|
1981
|
+
pointerUp: /* @__PURE__ */ __name((button = 0, opts) => {
|
|
1982
|
+
this.requireInputManager().firePointerUp(button, opts);
|
|
1983
|
+
}, "pointerUp"),
|
|
1984
|
+
gamepadButton: /* @__PURE__ */ __name((code, pressed) => {
|
|
1985
|
+
this.requireInputManager().fireGamepadButton(code, pressed);
|
|
1912
1986
|
}, "gamepadButton"),
|
|
1913
|
-
gamepadAxis: /* @__PURE__ */ __name((
|
|
1914
|
-
this.requireInputManager().fireGamepadAxis(
|
|
1987
|
+
gamepadAxis: /* @__PURE__ */ __name((side, value) => {
|
|
1988
|
+
this.requireInputManager().fireGamepadAxis(side, value);
|
|
1915
1989
|
}, "gamepadAxis"),
|
|
1916
1990
|
tap: /* @__PURE__ */ __name((code, frames = 1) => {
|
|
1917
1991
|
this.assertNonNegativeInteger(frames, "Inspector.input.tap(frames)");
|
|
@@ -2470,6 +2544,7 @@ var Inspector = class {
|
|
|
2470
2544
|
keys: [],
|
|
2471
2545
|
actions: [],
|
|
2472
2546
|
mouse: { x: 0, y: 0, buttons: [], down: false },
|
|
2547
|
+
pointers: [],
|
|
2473
2548
|
gamepad: { buttons: [], axes: [] }
|
|
2474
2549
|
};
|
|
2475
2550
|
}
|
|
@@ -2633,6 +2708,17 @@ function decodeBase64(base64) {
|
|
|
2633
2708
|
__name(decodeBase64, "decodeBase64");
|
|
2634
2709
|
|
|
2635
2710
|
// src/Scene.ts
|
|
2711
|
+
var _SPAWN_OPTION_KEYS = /* @__PURE__ */ new Set(["key"]);
|
|
2712
|
+
function _looksLikeSpawnOptions(v) {
|
|
2713
|
+
if (typeof v !== "object" || v === null || Array.isArray(v)) return false;
|
|
2714
|
+
const keys = Object.keys(v);
|
|
2715
|
+
if (keys.length === 0) return false;
|
|
2716
|
+
for (const k of keys) {
|
|
2717
|
+
if (!_SPAWN_OPTION_KEYS.has(k)) return false;
|
|
2718
|
+
}
|
|
2719
|
+
return true;
|
|
2720
|
+
}
|
|
2721
|
+
__name(_looksLikeSpawnOptions, "_looksLikeSpawnOptions");
|
|
2636
2722
|
var Scene = class {
|
|
2637
2723
|
static {
|
|
2638
2724
|
__name(this, "Scene");
|
|
@@ -2658,6 +2744,7 @@ var Scene = class {
|
|
|
2658
2744
|
_entityEventHandlers;
|
|
2659
2745
|
_entityEventObserver;
|
|
2660
2746
|
_scopedServices;
|
|
2747
|
+
_identityIndex;
|
|
2661
2748
|
/** Access the EngineContext. */
|
|
2662
2749
|
get context() {
|
|
2663
2750
|
return this._context;
|
|
@@ -2706,10 +2793,26 @@ var Scene = class {
|
|
|
2706
2793
|
}, "set")
|
|
2707
2794
|
});
|
|
2708
2795
|
}
|
|
2709
|
-
spawn(nameOrBlueprintOrClass,
|
|
2796
|
+
spawn(nameOrBlueprintOrClass, paramsOrOptions, maybeOptions) {
|
|
2710
2797
|
if (typeof nameOrBlueprintOrClass === "function") {
|
|
2711
|
-
const
|
|
2798
|
+
const Ctor = nameOrBlueprintOrClass;
|
|
2799
|
+
const hasSetup = typeof Ctor.prototype.setup === "function";
|
|
2800
|
+
let params;
|
|
2801
|
+
let options2;
|
|
2802
|
+
if (maybeOptions !== void 0) {
|
|
2803
|
+
params = paramsOrOptions;
|
|
2804
|
+
options2 = maybeOptions;
|
|
2805
|
+
} else if (paramsOrOptions === void 0) {
|
|
2806
|
+
} else if (!hasSetup) {
|
|
2807
|
+
options2 = paramsOrOptions;
|
|
2808
|
+
} else if (_looksLikeSpawnOptions(paramsOrOptions)) {
|
|
2809
|
+
options2 = paramsOrOptions;
|
|
2810
|
+
} else {
|
|
2811
|
+
params = paramsOrOptions;
|
|
2812
|
+
}
|
|
2813
|
+
const entity2 = new Ctor();
|
|
2712
2814
|
entity2._setScene(this, this.entityCallbacks);
|
|
2815
|
+
if (options2?.key !== void 0) this._registerKey(entity2, options2.key);
|
|
2713
2816
|
this.entities.add(entity2);
|
|
2714
2817
|
this.bus?.emit("entity:created", { entity: entity2 });
|
|
2715
2818
|
entity2.setup?.(params);
|
|
@@ -2717,15 +2820,59 @@ var Scene = class {
|
|
|
2717
2820
|
}
|
|
2718
2821
|
const isBlueprint = typeof nameOrBlueprintOrClass === "object" && nameOrBlueprintOrClass !== null && "build" in nameOrBlueprintOrClass;
|
|
2719
2822
|
const name = isBlueprint ? nameOrBlueprintOrClass.name : nameOrBlueprintOrClass;
|
|
2823
|
+
let blueprintParams;
|
|
2824
|
+
let options;
|
|
2825
|
+
if (isBlueprint) {
|
|
2826
|
+
if (maybeOptions !== void 0) {
|
|
2827
|
+
blueprintParams = paramsOrOptions;
|
|
2828
|
+
options = maybeOptions;
|
|
2829
|
+
} else if (paramsOrOptions !== void 0 && _looksLikeSpawnOptions(paramsOrOptions)) {
|
|
2830
|
+
options = paramsOrOptions;
|
|
2831
|
+
} else {
|
|
2832
|
+
blueprintParams = paramsOrOptions;
|
|
2833
|
+
}
|
|
2834
|
+
} else {
|
|
2835
|
+
options = paramsOrOptions;
|
|
2836
|
+
}
|
|
2720
2837
|
const entity = new Entity(name);
|
|
2721
2838
|
entity._setScene(this, this.entityCallbacks);
|
|
2839
|
+
if (options?.key !== void 0) this._registerKey(entity, options.key);
|
|
2722
2840
|
this.entities.add(entity);
|
|
2723
2841
|
this.bus?.emit("entity:created", { entity });
|
|
2724
2842
|
if (isBlueprint) {
|
|
2725
|
-
nameOrBlueprintOrClass.build(
|
|
2843
|
+
nameOrBlueprintOrClass.build(
|
|
2844
|
+
entity,
|
|
2845
|
+
blueprintParams
|
|
2846
|
+
);
|
|
2726
2847
|
}
|
|
2727
2848
|
return entity;
|
|
2728
2849
|
}
|
|
2850
|
+
/**
|
|
2851
|
+
* Look up an entity by its stable identity key, scoped to this scene.
|
|
2852
|
+
* Returns `undefined` for unknown or already-destroyed entities.
|
|
2853
|
+
*/
|
|
2854
|
+
findByKey(key) {
|
|
2855
|
+
const entity = this._identityIndex?.get(key);
|
|
2856
|
+
if (!entity || entity.isDestroyed) return void 0;
|
|
2857
|
+
return entity;
|
|
2858
|
+
}
|
|
2859
|
+
/**
|
|
2860
|
+
* Internal: register a key on a freshly spawned entity. Throws on
|
|
2861
|
+
* duplicate so callers (Scene.spawn) can abort before adding to
|
|
2862
|
+
* `this.entities` or emitting `entity:created`.
|
|
2863
|
+
* @internal
|
|
2864
|
+
*/
|
|
2865
|
+
_registerKey(entity, key) {
|
|
2866
|
+
this._identityIndex ??= /* @__PURE__ */ new Map();
|
|
2867
|
+
const existing = this._identityIndex.get(key);
|
|
2868
|
+
if (existing && !existing.isDestroyed) {
|
|
2869
|
+
throw new Error(
|
|
2870
|
+
`Scene "${this.name}" already has an entity with key "${key}". Destroy it before spawning a duplicate.`
|
|
2871
|
+
);
|
|
2872
|
+
}
|
|
2873
|
+
entity._setKey(key);
|
|
2874
|
+
this._identityIndex.set(key, entity);
|
|
2875
|
+
}
|
|
2729
2876
|
/**
|
|
2730
2877
|
* Add an existing entity to this scene (used by Entity.addChild for auto-scene-membership).
|
|
2731
2878
|
* @internal
|
|
@@ -2876,12 +3023,17 @@ var Scene = class {
|
|
|
2876
3023
|
entity._performDestroy();
|
|
2877
3024
|
this.queryCache?.onEntityDestroyed(entity);
|
|
2878
3025
|
this.entities.delete(entity);
|
|
3026
|
+
if (entity.key !== void 0 && this._identityIndex?.get(entity.key) === entity) {
|
|
3027
|
+
this._identityIndex.delete(entity.key);
|
|
3028
|
+
}
|
|
2879
3029
|
this.bus?.emit("entity:destroyed", { entity });
|
|
2880
3030
|
}
|
|
2881
3031
|
this.destroyQueue.length = 0;
|
|
2882
3032
|
}
|
|
2883
3033
|
/**
|
|
2884
|
-
* Destroy all entities — used during scene exit.
|
|
3034
|
+
* Destroy all entities — used during scene exit. Clears the identity
|
|
3035
|
+
* index in bulk; per-entity key removal in `_flushDestroyQueue` is the
|
|
3036
|
+
* in-game path.
|
|
2885
3037
|
* @internal
|
|
2886
3038
|
*/
|
|
2887
3039
|
_destroyAllEntities() {
|
|
@@ -2892,6 +3044,7 @@ var Scene = class {
|
|
|
2892
3044
|
this.entities.clear();
|
|
2893
3045
|
this.destroyQueue.length = 0;
|
|
2894
3046
|
this._entityEventHandlers?.clear();
|
|
3047
|
+
this._identityIndex?.clear();
|
|
2895
3048
|
}
|
|
2896
3049
|
};
|
|
2897
3050
|
|
|
@@ -4493,6 +4646,21 @@ var RendererAdapterKey = new ServiceKey(
|
|
|
4493
4646
|
"rendererAdapter"
|
|
4494
4647
|
);
|
|
4495
4648
|
|
|
4649
|
+
// src/ui-consume-registry.ts
|
|
4650
|
+
var registry2 = /* @__PURE__ */ new WeakSet();
|
|
4651
|
+
function markPointerConsumeContainer(container) {
|
|
4652
|
+
registry2.add(container);
|
|
4653
|
+
}
|
|
4654
|
+
__name(markPointerConsumeContainer, "markPointerConsumeContainer");
|
|
4655
|
+
function unmarkPointerConsumeContainer(container) {
|
|
4656
|
+
registry2.delete(container);
|
|
4657
|
+
}
|
|
4658
|
+
__name(unmarkPointerConsumeContainer, "unmarkPointerConsumeContainer");
|
|
4659
|
+
function isPointerConsumeContainer(container) {
|
|
4660
|
+
return registry2.has(container);
|
|
4661
|
+
}
|
|
4662
|
+
__name(isPointerConsumeContainer, "isPointerConsumeContainer");
|
|
4663
|
+
|
|
4496
4664
|
// src/test-utils.ts
|
|
4497
4665
|
var _TestScene = class extends Scene {
|
|
4498
4666
|
static {
|
|
@@ -4540,6 +4708,387 @@ function advanceFrames(engine, n, dtMs = 1e3 / 60) {
|
|
|
4540
4708
|
}
|
|
4541
4709
|
__name(advanceFrames, "advanceFrames");
|
|
4542
4710
|
|
|
4711
|
+
// src/state/Atom.ts
|
|
4712
|
+
function createAtom(initial) {
|
|
4713
|
+
let value = initial;
|
|
4714
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
4715
|
+
return {
|
|
4716
|
+
get() {
|
|
4717
|
+
return value;
|
|
4718
|
+
},
|
|
4719
|
+
set(next) {
|
|
4720
|
+
if (Object.is(value, next)) return;
|
|
4721
|
+
value = next;
|
|
4722
|
+
for (const fn of listeners) fn(value);
|
|
4723
|
+
},
|
|
4724
|
+
subscribe(listener) {
|
|
4725
|
+
listeners.add(listener);
|
|
4726
|
+
return () => {
|
|
4727
|
+
listeners.delete(listener);
|
|
4728
|
+
};
|
|
4729
|
+
}
|
|
4730
|
+
};
|
|
4731
|
+
}
|
|
4732
|
+
__name(createAtom, "createAtom");
|
|
4733
|
+
|
|
4734
|
+
// src/state/Store.ts
|
|
4735
|
+
function createStore(initial) {
|
|
4736
|
+
let snapshot = { ...initial };
|
|
4737
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
4738
|
+
return {
|
|
4739
|
+
get() {
|
|
4740
|
+
return snapshot;
|
|
4741
|
+
},
|
|
4742
|
+
set(partial) {
|
|
4743
|
+
let changed = false;
|
|
4744
|
+
for (const key of Object.keys(partial)) {
|
|
4745
|
+
if (!Object.is(snapshot[key], partial[key])) {
|
|
4746
|
+
changed = true;
|
|
4747
|
+
break;
|
|
4748
|
+
}
|
|
4749
|
+
}
|
|
4750
|
+
if (!changed) return;
|
|
4751
|
+
snapshot = { ...snapshot, ...partial };
|
|
4752
|
+
for (const fn of listeners) fn();
|
|
4753
|
+
},
|
|
4754
|
+
subscribe(listener) {
|
|
4755
|
+
listeners.add(listener);
|
|
4756
|
+
return () => {
|
|
4757
|
+
listeners.delete(listener);
|
|
4758
|
+
};
|
|
4759
|
+
}
|
|
4760
|
+
};
|
|
4761
|
+
}
|
|
4762
|
+
__name(createStore, "createStore");
|
|
4763
|
+
|
|
4764
|
+
// src/state/codecs.ts
|
|
4765
|
+
function jsonCodec() {
|
|
4766
|
+
return {
|
|
4767
|
+
encode: /* @__PURE__ */ __name((value) => value, "encode"),
|
|
4768
|
+
decode: /* @__PURE__ */ __name((raw) => raw, "decode")
|
|
4769
|
+
};
|
|
4770
|
+
}
|
|
4771
|
+
__name(jsonCodec, "jsonCodec");
|
|
4772
|
+
function setCodec() {
|
|
4773
|
+
return {
|
|
4774
|
+
encode: /* @__PURE__ */ __name((value) => Array.from(value), "encode"),
|
|
4775
|
+
decode: /* @__PURE__ */ __name((raw) => {
|
|
4776
|
+
if (!Array.isArray(raw)) {
|
|
4777
|
+
throw new Error("setCodec.decode: expected an array");
|
|
4778
|
+
}
|
|
4779
|
+
return new Set(raw);
|
|
4780
|
+
}, "decode")
|
|
4781
|
+
};
|
|
4782
|
+
}
|
|
4783
|
+
__name(setCodec, "setCodec");
|
|
4784
|
+
function mapCodec() {
|
|
4785
|
+
return {
|
|
4786
|
+
encode: /* @__PURE__ */ __name((value) => Array.from(value.entries()), "encode"),
|
|
4787
|
+
decode: /* @__PURE__ */ __name((raw) => {
|
|
4788
|
+
if (!Array.isArray(raw)) {
|
|
4789
|
+
throw new Error("mapCodec.decode: expected an array of entries");
|
|
4790
|
+
}
|
|
4791
|
+
return new Map(raw);
|
|
4792
|
+
}, "decode")
|
|
4793
|
+
};
|
|
4794
|
+
}
|
|
4795
|
+
__name(mapCodec, "mapCodec");
|
|
4796
|
+
function dateCodec() {
|
|
4797
|
+
return {
|
|
4798
|
+
encode: /* @__PURE__ */ __name((value) => value.toISOString(), "encode"),
|
|
4799
|
+
decode: /* @__PURE__ */ __name((raw) => {
|
|
4800
|
+
if (typeof raw !== "string") {
|
|
4801
|
+
throw new Error("dateCodec.decode: expected an ISO string");
|
|
4802
|
+
}
|
|
4803
|
+
const d = new Date(raw);
|
|
4804
|
+
if (Number.isNaN(d.getTime())) {
|
|
4805
|
+
throw new Error(`dateCodec.decode: invalid ISO string ${JSON.stringify(raw)}`);
|
|
4806
|
+
}
|
|
4807
|
+
return d;
|
|
4808
|
+
}, "decode")
|
|
4809
|
+
};
|
|
4810
|
+
}
|
|
4811
|
+
__name(dateCodec, "dateCodec");
|
|
4812
|
+
|
|
4813
|
+
// src/state/persistent.ts
|
|
4814
|
+
var registry3 = /* @__PURE__ */ new Map();
|
|
4815
|
+
function register(entry) {
|
|
4816
|
+
registry3.set(entry.id, entry);
|
|
4817
|
+
}
|
|
4818
|
+
__name(register, "register");
|
|
4819
|
+
function _resetAllStoresForTesting() {
|
|
4820
|
+
for (const entry of registry3.values()) entry.reset();
|
|
4821
|
+
}
|
|
4822
|
+
__name(_resetAllStoresForTesting, "_resetAllStoresForTesting");
|
|
4823
|
+
function _clearStoreRegistryForTesting() {
|
|
4824
|
+
registry3.clear();
|
|
4825
|
+
}
|
|
4826
|
+
__name(_clearStoreRegistryForTesting, "_clearStoreRegistryForTesting");
|
|
4827
|
+
var StoreVersionTooNewError = class extends Error {
|
|
4828
|
+
static {
|
|
4829
|
+
__name(this, "StoreVersionTooNewError");
|
|
4830
|
+
}
|
|
4831
|
+
storeId;
|
|
4832
|
+
storedVersion;
|
|
4833
|
+
currentVersion;
|
|
4834
|
+
constructor(storeId, storedVersion, currentVersion) {
|
|
4835
|
+
super(
|
|
4836
|
+
`Store "${storeId}" was saved at version ${storedVersion}, but this build is at version ${currentVersion}. Cannot downgrade.`
|
|
4837
|
+
);
|
|
4838
|
+
this.name = "StoreVersionTooNewError";
|
|
4839
|
+
this.storeId = storeId;
|
|
4840
|
+
this.storedVersion = storedVersion;
|
|
4841
|
+
this.currentVersion = currentVersion;
|
|
4842
|
+
}
|
|
4843
|
+
};
|
|
4844
|
+
var StoreMigrationMissingError = class extends Error {
|
|
4845
|
+
static {
|
|
4846
|
+
__name(this, "StoreMigrationMissingError");
|
|
4847
|
+
}
|
|
4848
|
+
storeId;
|
|
4849
|
+
storedVersion;
|
|
4850
|
+
currentVersion;
|
|
4851
|
+
constructor(storeId, storedVersion, currentVersion) {
|
|
4852
|
+
super(
|
|
4853
|
+
`Store "${storeId}" needs migration from version ${storedVersion} to ${currentVersion}, but no migrate() was provided.`
|
|
4854
|
+
);
|
|
4855
|
+
this.name = "StoreMigrationMissingError";
|
|
4856
|
+
this.storeId = storeId;
|
|
4857
|
+
this.storedVersion = storedVersion;
|
|
4858
|
+
this.currentVersion = currentVersion;
|
|
4859
|
+
}
|
|
4860
|
+
};
|
|
4861
|
+
function defineStore(id, opts) {
|
|
4862
|
+
const version = opts.version ?? 1;
|
|
4863
|
+
const codec = opts.codec ?? jsonCodec();
|
|
4864
|
+
const defaults = opts.defaults;
|
|
4865
|
+
const inner = createStore(defaults());
|
|
4866
|
+
const replaceAll = /* @__PURE__ */ __name((next) => {
|
|
4867
|
+
inner.set({ ...next });
|
|
4868
|
+
}, "replaceAll");
|
|
4869
|
+
const store = {
|
|
4870
|
+
id,
|
|
4871
|
+
version,
|
|
4872
|
+
get: inner.get,
|
|
4873
|
+
set: inner.set,
|
|
4874
|
+
subscribe: inner.subscribe,
|
|
4875
|
+
reset() {
|
|
4876
|
+
replaceAll(defaults());
|
|
4877
|
+
},
|
|
4878
|
+
serialize() {
|
|
4879
|
+
return { version, data: codec.encode(inner.get()) };
|
|
4880
|
+
},
|
|
4881
|
+
hydrate(payload) {
|
|
4882
|
+
if (payload.version > version) {
|
|
4883
|
+
throw new StoreVersionTooNewError(id, payload.version, version);
|
|
4884
|
+
}
|
|
4885
|
+
let next;
|
|
4886
|
+
if (payload.version < version) {
|
|
4887
|
+
if (!opts.migrate) {
|
|
4888
|
+
throw new StoreMigrationMissingError(id, payload.version, version);
|
|
4889
|
+
}
|
|
4890
|
+
next = opts.migrate(payload.data, payload.version);
|
|
4891
|
+
} else {
|
|
4892
|
+
next = codec.decode(payload.data);
|
|
4893
|
+
}
|
|
4894
|
+
replaceAll(next);
|
|
4895
|
+
}
|
|
4896
|
+
};
|
|
4897
|
+
register({ id, reset: /* @__PURE__ */ __name(() => store.reset(), "reset") });
|
|
4898
|
+
return store;
|
|
4899
|
+
}
|
|
4900
|
+
__name(defineStore, "defineStore");
|
|
4901
|
+
function defineSet(id, opts) {
|
|
4902
|
+
const version = opts?.version ?? 1;
|
|
4903
|
+
const defaults = /* @__PURE__ */ __name(() => new Set(opts?.defaults?.() ?? []), "defaults");
|
|
4904
|
+
const codec = setCodec();
|
|
4905
|
+
const atom = createAtom(defaults());
|
|
4906
|
+
const replace = /* @__PURE__ */ __name((next) => {
|
|
4907
|
+
atom.set(next);
|
|
4908
|
+
}, "replace");
|
|
4909
|
+
const store = {
|
|
4910
|
+
id,
|
|
4911
|
+
version,
|
|
4912
|
+
has(key) {
|
|
4913
|
+
return atom.get().has(key);
|
|
4914
|
+
},
|
|
4915
|
+
add(key) {
|
|
4916
|
+
const current = atom.get();
|
|
4917
|
+
if (current.has(key)) return;
|
|
4918
|
+
const next = new Set(current);
|
|
4919
|
+
next.add(key);
|
|
4920
|
+
replace(next);
|
|
4921
|
+
},
|
|
4922
|
+
remove(key) {
|
|
4923
|
+
const current = atom.get();
|
|
4924
|
+
if (!current.has(key)) return;
|
|
4925
|
+
const next = new Set(current);
|
|
4926
|
+
next.delete(key);
|
|
4927
|
+
replace(next);
|
|
4928
|
+
},
|
|
4929
|
+
clear() {
|
|
4930
|
+
if (atom.get().size === 0) return;
|
|
4931
|
+
replace(/* @__PURE__ */ new Set());
|
|
4932
|
+
},
|
|
4933
|
+
size() {
|
|
4934
|
+
return atom.get().size;
|
|
4935
|
+
},
|
|
4936
|
+
values() {
|
|
4937
|
+
return atom.get().values();
|
|
4938
|
+
},
|
|
4939
|
+
subscribe(listener) {
|
|
4940
|
+
return atom.subscribe(() => listener());
|
|
4941
|
+
},
|
|
4942
|
+
reset() {
|
|
4943
|
+
replace(defaults());
|
|
4944
|
+
},
|
|
4945
|
+
serialize() {
|
|
4946
|
+
return { version, data: codec.encode(atom.get()) };
|
|
4947
|
+
},
|
|
4948
|
+
hydrate(payload) {
|
|
4949
|
+
if (payload.version > version) {
|
|
4950
|
+
throw new StoreVersionTooNewError(id, payload.version, version);
|
|
4951
|
+
}
|
|
4952
|
+
if (payload.version < version) {
|
|
4953
|
+
if (!opts?.migrate) {
|
|
4954
|
+
throw new StoreMigrationMissingError(id, payload.version, version);
|
|
4955
|
+
}
|
|
4956
|
+
replace(opts.migrate(payload.data, payload.version));
|
|
4957
|
+
return;
|
|
4958
|
+
}
|
|
4959
|
+
replace(codec.decode(payload.data));
|
|
4960
|
+
}
|
|
4961
|
+
};
|
|
4962
|
+
register({ id, reset: /* @__PURE__ */ __name(() => store.reset(), "reset") });
|
|
4963
|
+
return store;
|
|
4964
|
+
}
|
|
4965
|
+
__name(defineSet, "defineSet");
|
|
4966
|
+
function defineMap(id, opts) {
|
|
4967
|
+
const version = opts?.version ?? 1;
|
|
4968
|
+
const defaults = /* @__PURE__ */ __name(() => new Map(opts?.defaults?.() ?? []), "defaults");
|
|
4969
|
+
const codec = mapCodec();
|
|
4970
|
+
const atom = createAtom(defaults());
|
|
4971
|
+
const replace = /* @__PURE__ */ __name((next) => {
|
|
4972
|
+
atom.set(next);
|
|
4973
|
+
}, "replace");
|
|
4974
|
+
const store = {
|
|
4975
|
+
id,
|
|
4976
|
+
version,
|
|
4977
|
+
has(key) {
|
|
4978
|
+
return atom.get().has(key);
|
|
4979
|
+
},
|
|
4980
|
+
get(key) {
|
|
4981
|
+
return atom.get().get(key);
|
|
4982
|
+
},
|
|
4983
|
+
set(key, value) {
|
|
4984
|
+
const current = atom.get();
|
|
4985
|
+
if (current.has(key) && Object.is(current.get(key), value)) return;
|
|
4986
|
+
const next = new Map(current);
|
|
4987
|
+
next.set(key, value);
|
|
4988
|
+
replace(next);
|
|
4989
|
+
},
|
|
4990
|
+
remove(key) {
|
|
4991
|
+
const current = atom.get();
|
|
4992
|
+
if (!current.has(key)) return;
|
|
4993
|
+
const next = new Map(current);
|
|
4994
|
+
next.delete(key);
|
|
4995
|
+
replace(next);
|
|
4996
|
+
},
|
|
4997
|
+
clear() {
|
|
4998
|
+
if (atom.get().size === 0) return;
|
|
4999
|
+
replace(/* @__PURE__ */ new Map());
|
|
5000
|
+
},
|
|
5001
|
+
size() {
|
|
5002
|
+
return atom.get().size;
|
|
5003
|
+
},
|
|
5004
|
+
entries() {
|
|
5005
|
+
return atom.get().entries();
|
|
5006
|
+
},
|
|
5007
|
+
subscribe(listener) {
|
|
5008
|
+
return atom.subscribe(() => listener());
|
|
5009
|
+
},
|
|
5010
|
+
reset() {
|
|
5011
|
+
replace(defaults());
|
|
5012
|
+
},
|
|
5013
|
+
serialize() {
|
|
5014
|
+
return { version, data: codec.encode(atom.get()) };
|
|
5015
|
+
},
|
|
5016
|
+
hydrate(payload) {
|
|
5017
|
+
if (payload.version > version) {
|
|
5018
|
+
throw new StoreVersionTooNewError(id, payload.version, version);
|
|
5019
|
+
}
|
|
5020
|
+
if (payload.version < version) {
|
|
5021
|
+
if (!opts?.migrate) {
|
|
5022
|
+
throw new StoreMigrationMissingError(id, payload.version, version);
|
|
5023
|
+
}
|
|
5024
|
+
replace(opts.migrate(payload.data, payload.version));
|
|
5025
|
+
return;
|
|
5026
|
+
}
|
|
5027
|
+
replace(codec.decode(payload.data));
|
|
5028
|
+
}
|
|
5029
|
+
};
|
|
5030
|
+
register({ id, reset: /* @__PURE__ */ __name(() => store.reset(), "reset") });
|
|
5031
|
+
return store;
|
|
5032
|
+
}
|
|
5033
|
+
__name(defineMap, "defineMap");
|
|
5034
|
+
function defineCounter(id, opts) {
|
|
5035
|
+
const version = opts?.version ?? 1;
|
|
5036
|
+
const defaults = /* @__PURE__ */ __name(() => opts?.defaults?.() ?? 0, "defaults");
|
|
5037
|
+
const atom = createAtom(defaults());
|
|
5038
|
+
const store = {
|
|
5039
|
+
id,
|
|
5040
|
+
version,
|
|
5041
|
+
value() {
|
|
5042
|
+
return atom.get();
|
|
5043
|
+
},
|
|
5044
|
+
set(n) {
|
|
5045
|
+
atom.set(n);
|
|
5046
|
+
},
|
|
5047
|
+
increment(by = 1) {
|
|
5048
|
+
atom.set(atom.get() + by);
|
|
5049
|
+
},
|
|
5050
|
+
decrement(by = 1) {
|
|
5051
|
+
atom.set(atom.get() - by);
|
|
5052
|
+
},
|
|
5053
|
+
subscribe(listener) {
|
|
5054
|
+
return atom.subscribe(() => listener());
|
|
5055
|
+
},
|
|
5056
|
+
reset() {
|
|
5057
|
+
atom.set(defaults());
|
|
5058
|
+
},
|
|
5059
|
+
serialize() {
|
|
5060
|
+
return { version, data: atom.get() };
|
|
5061
|
+
},
|
|
5062
|
+
hydrate(payload) {
|
|
5063
|
+
if (payload.version > version) {
|
|
5064
|
+
throw new StoreVersionTooNewError(id, payload.version, version);
|
|
5065
|
+
}
|
|
5066
|
+
if (payload.version < version) {
|
|
5067
|
+
if (!opts?.migrate) {
|
|
5068
|
+
throw new StoreMigrationMissingError(id, payload.version, version);
|
|
5069
|
+
}
|
|
5070
|
+
const migrated = opts.migrate(payload.data, payload.version);
|
|
5071
|
+
if (typeof migrated !== "number") {
|
|
5072
|
+
throw new Error(
|
|
5073
|
+
`defineCounter "${id}".hydrate: migrate returned non-number ${typeof migrated}`
|
|
5074
|
+
);
|
|
5075
|
+
}
|
|
5076
|
+
atom.set(migrated);
|
|
5077
|
+
return;
|
|
5078
|
+
}
|
|
5079
|
+
if (typeof payload.data !== "number") {
|
|
5080
|
+
throw new Error(
|
|
5081
|
+
`defineCounter "${id}".hydrate: expected number, got ${typeof payload.data}`
|
|
5082
|
+
);
|
|
5083
|
+
}
|
|
5084
|
+
atom.set(payload.data);
|
|
5085
|
+
}
|
|
5086
|
+
};
|
|
5087
|
+
register({ id, reset: /* @__PURE__ */ __name(() => store.reset(), "reset") });
|
|
5088
|
+
return store;
|
|
5089
|
+
}
|
|
5090
|
+
__name(defineCounter, "defineCounter");
|
|
5091
|
+
|
|
4543
5092
|
// src/index.ts
|
|
4544
5093
|
var VERSION = "0.0.0";
|
|
4545
5094
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -4589,6 +5138,8 @@ var VERSION = "0.0.0";
|
|
|
4589
5138
|
Sequence,
|
|
4590
5139
|
SerializableRegistry,
|
|
4591
5140
|
ServiceKey,
|
|
5141
|
+
StoreMigrationMissingError,
|
|
5142
|
+
StoreVersionTooNewError,
|
|
4592
5143
|
System,
|
|
4593
5144
|
SystemScheduler,
|
|
4594
5145
|
SystemSchedulerKey,
|
|
@@ -4598,16 +5149,25 @@ var VERSION = "0.0.0";
|
|
|
4598
5149
|
Tween,
|
|
4599
5150
|
VERSION,
|
|
4600
5151
|
Vec2,
|
|
5152
|
+
_clearStoreRegistryForTesting,
|
|
5153
|
+
_resetAllStoresForTesting,
|
|
4601
5154
|
_resetEntityIdCounter,
|
|
4602
5155
|
advanceFrames,
|
|
5156
|
+
createAtom,
|
|
4603
5157
|
createDefaultRandomSeed,
|
|
4604
5158
|
createKeyframeTrack,
|
|
4605
5159
|
createMockEntity,
|
|
4606
5160
|
createMockScene,
|
|
4607
5161
|
createRandomService,
|
|
5162
|
+
createStore,
|
|
4608
5163
|
createTestEngine,
|
|
5164
|
+
dateCodec,
|
|
4609
5165
|
defineBlueprint,
|
|
5166
|
+
defineCounter,
|
|
4610
5167
|
defineEvent,
|
|
5168
|
+
defineMap,
|
|
5169
|
+
defineSet,
|
|
5170
|
+
defineStore,
|
|
4611
5171
|
defineTrait,
|
|
4612
5172
|
easeInOutQuad,
|
|
4613
5173
|
easeInQuad,
|
|
@@ -4618,13 +5178,19 @@ var VERSION = "0.0.0";
|
|
|
4618
5178
|
getSerializableType,
|
|
4619
5179
|
globalRandom,
|
|
4620
5180
|
interpolate,
|
|
5181
|
+
isPointerConsumeContainer,
|
|
4621
5182
|
isSerializable,
|
|
5183
|
+
jsonCodec,
|
|
4622
5184
|
makeEntityScopedQueue,
|
|
4623
5185
|
makeGlobalScopedQueue,
|
|
4624
5186
|
makeSceneScopedQueue,
|
|
5187
|
+
mapCodec,
|
|
5188
|
+
markPointerConsumeContainer,
|
|
4625
5189
|
normalizeSeed,
|
|
4626
5190
|
resolveTransition,
|
|
4627
5191
|
serializable,
|
|
4628
|
-
|
|
5192
|
+
setCodec,
|
|
5193
|
+
trait,
|
|
5194
|
+
unmarkPointerConsumeContainer
|
|
4629
5195
|
});
|
|
4630
5196
|
//# sourceMappingURL=index.cjs.map
|