@vworlds/vecs 1.0.45 → 1.0.46

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 (136) hide show
  1. package/README.md +7 -1
  2. package/dist/component.d.ts +57 -60
  3. package/dist/component.js +24 -17
  4. package/dist/component.js.map +1 -1
  5. package/dist/component_meta.d.ts +67 -79
  6. package/dist/component_meta.js +331 -37
  7. package/dist/component_meta.js.map +1 -1
  8. package/dist/dsl.js +1 -1
  9. package/dist/dsl.js.map +1 -1
  10. package/dist/entity/entity.base.js +4 -0
  11. package/dist/entity/entity.base.js.map +1 -1
  12. package/dist/entity/entity.components.d.ts +39 -41
  13. package/dist/entity/entity.components.js +249 -82
  14. package/dist/entity/entity.components.js.map +1 -1
  15. package/dist/entity/entity.d.ts +1 -2
  16. package/dist/entity/entity.js +2 -3
  17. package/dist/entity/entity.js.map +1 -1
  18. package/dist/entity/entity.lifecycle.d.ts +7 -1
  19. package/dist/entity/entity.lifecycle.js +40 -50
  20. package/dist/entity/entity.lifecycle.js.map +1 -1
  21. package/dist/entity/entity.queries.js +30 -0
  22. package/dist/entity/entity.queries.js.map +1 -1
  23. package/dist/entity/entity.relationships.d.ts +4 -0
  24. package/dist/entity/entity.relationships.js +18 -10
  25. package/dist/entity/entity.relationships.js.map +1 -1
  26. package/dist/index.d.ts +7 -4
  27. package/dist/index.js +4 -2
  28. package/dist/index.js.map +1 -1
  29. package/dist/inject.d.ts +63 -14
  30. package/dist/inject.js +165 -89
  31. package/dist/inject.js.map +1 -1
  32. package/dist/modules/identity.js +2 -2
  33. package/dist/modules/identity.js.map +1 -1
  34. package/dist/modules/implements.js +2 -2
  35. package/dist/modules/implements.js.map +1 -1
  36. package/dist/modules/pipeline.js +5 -5
  37. package/dist/modules/pipeline.js.map +1 -1
  38. package/dist/modules/relationship_types.d.ts +70 -6
  39. package/dist/modules/relationship_types.js +70 -6
  40. package/dist/modules/relationship_types.js.map +1 -1
  41. package/dist/modules/relationships.d.ts +31 -9
  42. package/dist/modules/relationships.js +120 -44
  43. package/dist/modules/relationships.js.map +1 -1
  44. package/dist/modules/singleton.js +2 -2
  45. package/dist/modules/singleton.js.map +1 -1
  46. package/dist/modules/snapshot.d.ts +26 -0
  47. package/dist/modules/snapshot.js +45 -0
  48. package/dist/modules/snapshot.js.map +1 -0
  49. package/dist/modules/snapshot_types.d.ts +85 -0
  50. package/dist/modules/snapshot_types.js +130 -0
  51. package/dist/modules/snapshot_types.js.map +1 -0
  52. package/dist/package.json +2 -2
  53. package/dist/query/callbacks.d.ts +9 -7
  54. package/dist/query/callbacks.js +27 -41
  55. package/dist/query/callbacks.js.map +1 -1
  56. package/dist/query/grouped_query.js +7 -7
  57. package/dist/query/grouped_query.js.map +1 -1
  58. package/dist/query/grouping.d.ts +6 -2
  59. package/dist/query/grouping.js +84 -15
  60. package/dist/query/grouping.js.map +1 -1
  61. package/dist/query/query.d.ts +4 -4
  62. package/dist/query/query.js +37 -14
  63. package/dist/query/query.js.map +1 -1
  64. package/dist/snapshot/capture.d.ts +1 -0
  65. package/dist/snapshot/capture.js +212 -0
  66. package/dist/snapshot/capture.js.map +1 -0
  67. package/dist/snapshot/clone.d.ts +1 -0
  68. package/dist/snapshot/clone.js +107 -0
  69. package/dist/snapshot/clone.js.map +1 -0
  70. package/dist/snapshot/index.d.ts +5 -0
  71. package/dist/snapshot/index.js +21 -0
  72. package/dist/snapshot/index.js.map +1 -0
  73. package/dist/snapshot/preflight.d.ts +1 -0
  74. package/dist/snapshot/preflight.js +40 -0
  75. package/dist/snapshot/preflight.js.map +1 -0
  76. package/dist/snapshot/restore.d.ts +1 -0
  77. package/dist/snapshot/restore.js +111 -0
  78. package/dist/snapshot/restore.js.map +1 -0
  79. package/dist/snapshot/types.d.ts +135 -0
  80. package/dist/snapshot/types.js +26 -0
  81. package/dist/snapshot/types.js.map +1 -0
  82. package/dist/system.d.ts +3 -1
  83. package/dist/system.js +33 -23
  84. package/dist/system.js.map +1 -1
  85. package/dist/terms/all_term.js +19 -0
  86. package/dist/terms/all_term.js.map +1 -1
  87. package/dist/terms/any_term.js +19 -0
  88. package/dist/terms/any_term.js.map +1 -1
  89. package/dist/terms/not_term.js +4 -0
  90. package/dist/terms/not_term.js.map +1 -1
  91. package/dist/terms/target_term.d.ts +1 -2
  92. package/dist/terms/target_term.js +2 -4
  93. package/dist/terms/target_term.js.map +1 -1
  94. package/dist/terms/term.d.ts +2 -0
  95. package/dist/terms/term.js +59 -10
  96. package/dist/terms/term.js.map +1 -1
  97. package/dist/util/array_map.d.ts +43 -12
  98. package/dist/util/array_map.js +90 -41
  99. package/dist/util/array_map.js.map +1 -1
  100. package/dist/util/dense_set.js +26 -0
  101. package/dist/util/dense_set.js.map +1 -1
  102. package/dist/world/world.base.js +12 -0
  103. package/dist/world/world.base.js.map +1 -1
  104. package/dist/world/world.d.ts +7 -0
  105. package/dist/world/world.deferred.js +17 -0
  106. package/dist/world/world.deferred.js.map +1 -1
  107. package/dist/world/world.entities.d.ts +13 -2
  108. package/dist/world/world.entities.js +16 -2
  109. package/dist/world/world.entities.js.map +1 -1
  110. package/dist/world/world.js +15 -3
  111. package/dist/world/world.js.map +1 -1
  112. package/dist/world/world.pipeline.d.ts +2 -2
  113. package/dist/world/world.pipeline.js +4 -2
  114. package/dist/world/world.pipeline.js.map +1 -1
  115. package/dist/world/world.queries.d.ts +7 -0
  116. package/dist/world/world.queries.js +52 -0
  117. package/dist/world/world.queries.js.map +1 -1
  118. package/dist/world/world.transfers.d.ts +137 -0
  119. package/dist/world/world.transfers.js +188 -0
  120. package/dist/world/world.transfers.js.map +1 -0
  121. package/docs/README.md +18 -6
  122. package/docs/components.md +90 -53
  123. package/docs/concepts.md +21 -17
  124. package/docs/design-guide.md +125 -94
  125. package/docs/entities.md +62 -76
  126. package/docs/execution-model.md +26 -10
  127. package/docs/getting-started.md +6 -6
  128. package/docs/glossary.md +19 -10
  129. package/docs/modules.md +8 -8
  130. package/docs/queries-and-filters.md +15 -10
  131. package/docs/relationships.md +245 -124
  132. package/docs/snapshots.md +181 -0
  133. package/docs/systems.md +64 -21
  134. package/docs/utilities.md +10 -6
  135. package/package.json +2 -2
  136. package/skills/vecs/SKILL.md +5 -4
@@ -36,7 +36,14 @@ export class Entities extends Deferred {
36
36
  }
37
37
  return e;
38
38
  }
39
- /** Look up an entity by component ref or identity name. */
39
+ /**
40
+ * Look up an entity by component ref or identity name.
41
+ *
42
+ * A foreign `Entity` (one whose `world` is not this world) throws: passing an
43
+ * entity from another world is a programming error, not a miss. An `Entity`
44
+ * whose world matches but whose eid is unknown (e.g. after destruction)
45
+ * returns `undefined`.
46
+ */
40
47
  getEntity(ref) {
41
48
  if (typeof ref === "string") {
42
49
  return this._identityNameIndex.get(ref);
@@ -51,7 +58,14 @@ export class Entities extends Deferred {
51
58
  const entity = this._entities.get(ref);
52
59
  return entity ?? (this.deferred ? this._deferredEntities.get(ref) : undefined);
53
60
  }
54
- return ref.world === this && this._entities.get(ref.eid) === ref ? ref : undefined;
61
+ if (ref.world !== this) {
62
+ throw new Error("Entity belongs to a different World");
63
+ }
64
+ return this._entities.get(ref.eid) === ref
65
+ ? ref
66
+ : this.deferred
67
+ ? this._deferredEntities.get(ref.eid)
68
+ : undefined;
55
69
  }
56
70
  entity(ref) {
57
71
  if (ref === undefined) {
@@ -1 +1 @@
1
- {"version":3,"file":"world.entities.js","sourceRoot":"","sources":["../../src/world/world.entities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"world.entities.js","sourceRoot":"","sources":["../../src/world/world.entities.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { ImplementsModule } from "../modules/implements.js";
4
4
  import { PipelineModule } from "../modules/pipeline.js";
5
5
  import { RelationshipsModule } from "../modules/relationships.js";
6
6
  import { SingletonModule } from "../modules/singleton.js";
7
+ import { SnapshotModule } from "../modules/snapshot.js";
7
8
  import { Query } from "../query/index.js";
8
9
  import { System } from "../system.js";
9
10
  import { Pipeline } from "./world.pipeline.js";
@@ -27,18 +28,29 @@ import { Pipeline } from "./world.pipeline.js";
27
28
  * deferred scope; user code can wrap arbitrary blocks with
28
29
  * {@link beginDefer} / {@link endDefer} or {@link defer}. {@link flush}
29
30
  * drains the queue at top level.
31
+ *
32
+ * ## Cross-world transfer
33
+ *
34
+ * {@link snapshotSubtree}, {@link restoreSubtree}, and {@link moveSubtree}
35
+ * capture and recreate an entity forest in a second world. They reject calls
36
+ * while either world is deferred, because cross-world scheduling is the
37
+ * application's job.
30
38
  */
31
39
  export class World extends Pipeline {
32
40
  constructor(options = {}) {
33
41
  super(options);
34
- this.component(SilenceSource).onRemove((entity) => entity.get(Query)?._clearSilence());
35
- this.component(Query).onRemove((_entity, query) => query.destroy());
36
- this.component(System).onRemove((_entity, system) => system.destroy());
42
+ this.component(SilenceSource).on("remove", (entity) => entity.get(Query)?._clearSilence());
43
+ this.component(Query).on("remove", (_entity, query) => query.destroy());
44
+ this.component(System).on("remove", (_entity, system) => system.destroy());
37
45
  [
38
46
  IdentityModule,
39
47
  ImplementsModule,
40
48
  SingletonModule,
41
49
  RelationshipsModule,
50
+ // Registration order is not load-bearing: a capture binds the materializer
51
+ // its policy resolved to, so `SnapshotModule` may install or change a
52
+ // policy after entities already carry the component.
53
+ SnapshotModule,
42
54
  PipelineModule,
43
55
  ].forEach((mod) => this.module(mod));
44
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"world.js","sourceRoot":"","sources":["../../src/world/world.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,KAAM,SAAQ,QAAQ;IACjC,YAAmB,UAAwB,EAAE;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC;QACvF,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QACvE;YACE,cAAc;YACd,gBAAgB;YAChB,eAAe;YACf,mBAAmB;YACnB,cAAc;SACf,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,CAAC;CACF"}
1
+ {"version":3,"file":"world.js","sourceRoot":"","sources":["../../src/world/world.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,OAAO,KAAM,SAAQ,QAAQ;IACjC,YAAmB,UAAwB,EAAE;QAC3C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC;QAC3F,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC3E;YACE,cAAc;YACd,gBAAgB;YAChB,eAAe;YACf,mBAAmB;YACnB,2EAA2E;YAC3E,sEAAsE;YACtE,qDAAqD;YACrD,cAAc;YACd,cAAc;SACf,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,CAAC;CACF"}
@@ -2,8 +2,8 @@ import { type QuerySpec } from "../dsl.js";
2
2
  import { Query } from "../query/index.js";
3
3
  import { System } from "../system.js";
4
4
  import type { WorldOptions } from "./world.base.js";
5
- import { Modules } from "./world.modules.js";
6
- export declare class Pipeline extends Modules {
5
+ import { Transfers } from "./world.transfers.js";
6
+ export declare class Pipeline extends Transfers {
7
7
  constructor(options?: WorldOptions);
8
8
  /** Open a new frame and evaluate every registered tick source once. */
9
9
  beginFrame(delta: number): void;
@@ -1,11 +1,13 @@
1
1
  import { System } from "../system.js";
2
2
  import { ALWAYS_TICK_SOURCE } from "../timer.js";
3
- import { Modules } from "./world.modules.js";
4
- export class Pipeline extends Modules {
3
+ import { Transfers } from "./world.transfers.js";
4
+ export class Pipeline extends Transfers {
5
5
  constructor(options = {}) {
6
6
  super(options);
7
7
  /** @internal Flat system execution pipeline, rebuilt from `_pipelineQuery`. */
8
8
  this._pipeline = [];
9
+ /** @internal Query whose ordered result defines the system pipeline. */
10
+ this._pipelineQuery = undefined;
9
11
  /** @internal World-owned tick sources evaluated once per frame. */
10
12
  this._tickSources = new Set();
11
13
  /** @internal Monotonic frame id used to memoize tick-source evaluation. */
@@ -1 +1 @@
1
- {"version":3,"file":"world.pipeline.js","sourceRoot":"","sources":["../../src/world/world.pipeline.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"world.pipeline.js","sourceRoot":"","sources":["../../src/world/world.pipeline.ts"],"names":[],"mappings":"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"}
@@ -13,4 +13,11 @@ export declare class Queries extends Storage {
13
13
  query(this: World, name: string): Query;
14
14
  /** Return the shared materialized term for a reactive query DSL expression. */
15
15
  getTerm(this: World, q: QueryDSL): Term;
16
+ /**
17
+ * Index a built query under every component eid it watches. Only queries that
18
+ * watch updates join entity membership sets, so only those are indexed.
19
+ */
20
+ private _addUpdateWatcher;
21
+ /** Drop a query from the watcher index; the inverse of {@link _addUpdateWatcher}. */
22
+ private _removeUpdateWatcher;
16
23
  }
@@ -15,6 +15,22 @@ export class Queries extends Storage {
15
15
  this._termCache = new Map();
16
16
  /** @internal Component eid -> pinned component leaf term. */
17
17
  this._componentTerms = new ArrayMap();
18
+ /** @internal Pinned false term. */
19
+ this._emptyTerm = undefined;
20
+ /** @internal Pinned world term. */
21
+ this._worldTerm = undefined;
22
+ /**
23
+ * @internal Term membership events currently being delivered (see
24
+ * `Term._add` / `Term._delete`). While it is zero, every composite term agrees
25
+ * with its children's membership.
26
+ */
27
+ this._termEmitDepth = 0;
28
+ /**
29
+ * @internal Component eid -> built queries that watch it for updates. Read by
30
+ * `Entity._routeModified`; maintained by {@link _addQuery} and
31
+ * {@link _removeQuery}.
32
+ */
33
+ this._updateWatchers = [];
18
34
  /** @internal True while the world is driving one logical frame. */
19
35
  this._frameInProgress = false;
20
36
  /** @internal True while the world is auto-building pending queries. */
@@ -31,6 +47,7 @@ export class Queries extends Storage {
31
47
  }
32
48
  this._removeUnbuiltQuery(q);
33
49
  this._queries.push(q);
50
+ this._addUpdateWatcher(q);
34
51
  }
35
52
  /** @internal Track a newly-created query until it is explicitly or automatically built. */
36
53
  _addUnbuiltQuery(q) {
@@ -42,6 +59,7 @@ export class Queries extends Storage {
42
59
  const idx = this._queries.indexOf(q);
43
60
  if (idx !== -1) {
44
61
  this._queries.splice(idx, 1);
62
+ this._removeUpdateWatcher(q);
45
63
  }
46
64
  q._unsubscribeRootTerm();
47
65
  this._entities.forEach((e) => e._purgeQuery(q));
@@ -105,5 +123,39 @@ export class Queries extends Storage {
105
123
  this._buildingPendingQueries = false;
106
124
  }
107
125
  }
126
+ /**
127
+ * Index a built query under every component eid it watches. Only queries that
128
+ * watch updates join entity membership sets, so only those are indexed.
129
+ */
130
+ _addUpdateWatcher(q) {
131
+ if (!q._watchesUpdates()) {
132
+ return;
133
+ }
134
+ q._watchlistBitmask.forEach((ceid) => {
135
+ let watchers = this._updateWatchers[ceid];
136
+ if (watchers === undefined) {
137
+ watchers = { queries: [], synchronous: 0 };
138
+ this._updateWatchers[ceid] = watchers;
139
+ }
140
+ watchers.queries.push(q);
141
+ if (!q._queuesUpdates) {
142
+ watchers.synchronous++;
143
+ }
144
+ });
145
+ }
146
+ /** Drop a query from the watcher index; the inverse of {@link _addUpdateWatcher}. */
147
+ _removeUpdateWatcher(q) {
148
+ q._watchlistBitmask.forEach((ceid) => {
149
+ const watchers = this._updateWatchers[ceid];
150
+ const index = watchers?.queries.indexOf(q) ?? -1;
151
+ if (index === -1) {
152
+ return;
153
+ }
154
+ watchers.queries.splice(index, 1);
155
+ if (!q._queuesUpdates) {
156
+ watchers.synchronous--;
157
+ }
158
+ });
159
+ }
108
160
  }
109
161
  //# sourceMappingURL=world.queries.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"world.queries.js","sourceRoot":"","sources":["../../src/world/world.queries.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"world.queries.js","sourceRoot":"","sources":["../../src/world/world.queries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,137 @@
1
+ import { type EID, type Entity } from "../entity/index.js";
2
+ import { type EntitySubtreeSnapshot, type MoveSubtreeResult, type RestoreSubtreeResult, type SubtreeSnapshotOptions } from "../snapshot/types.js";
3
+ import { Modules } from "./world.modules.js";
4
+ import { type World } from "./world.js";
5
+ /**
6
+ * Thrown by {@link World.moveSubtree} when the destination restore fails after
7
+ * the source roots have already been destroyed.
8
+ *
9
+ * Everything the destination restore created is destroyed, the source snapshot
10
+ * is restored back into the source world, and the destination's original error
11
+ * becomes this error's `cause`. The rollback rebuilds equivalent state with
12
+ * freshly allocated ids, so callers that held `Entity` references across the
13
+ * failed move must rebind them — {@link restored} is the mapping that does it:
14
+ * old source id to the restored entity that replaced it.
15
+ *
16
+ * Inbound edges — edges pointing *into* the moved subtree from an entity outside
17
+ * it — are not part of the snapshot and are not carried by the rollback either.
18
+ * They belonged to the state left behind in the source world.
19
+ */
20
+ export declare class MoveSubtreeError extends Error {
21
+ /** The destination failure that triggered the rollback. */
22
+ readonly cause: unknown;
23
+ /** Old source id to the entity that replaced it in the source world. */
24
+ readonly restored: ReadonlyMap<EID, Entity>;
25
+ /** Whether the rollback itself failed, leaving the source world incomplete. */
26
+ readonly rollbackFailed: boolean;
27
+ constructor(operation: string, cause: unknown, restored: ReadonlyMap<EID, Entity>, rollbackFailed: boolean);
28
+ }
29
+ export declare class Transfers extends Modules {
30
+ /**
31
+ * Capture one entity's subtree, or several roots as one atomic forest, into
32
+ * detached records.
33
+ *
34
+ * Nothing in the source world changes: the forest is walked and every selected
35
+ * component and edge is copied before this returns. Entity ids and
36
+ * relationship edges are world-local, so the result carries *data* — its
37
+ * component classes and payloads, plus internal edges keyed by snapshot key —
38
+ * and never a live instance.
39
+ *
40
+ * Per component type, capture follows the type's `OnSnapshot` declaration, set
41
+ * by the module that owns it: plain data clones its own enumerable fields
42
+ * (`ClonePublic`), `DontSnapshot` types are left behind, and
43
+ * `CustomSnapshot` types call the owner's `capture`. Relationship targets
44
+ * inside the forest are stored as snapshot keys; targets outside it follow
45
+ * the `externalTargets` policy.
46
+ *
47
+ * @param rootOrRoots - A single root entity, or an array of roots captured as
48
+ * one forest.
49
+ * @param options - Traversal relationship, component and relationship
50
+ * allowlists, and the external-target policy.
51
+ * @returns A snapshot bound to this world.
52
+ * @throws If the world is deferred, a root is destroyed or is a
53
+ * component-definition entity, the traversal relationship is unregistered,
54
+ * the forest contains a cycle or a repeated member, a selected type is
55
+ * `DontSnapshot`, or an external target is found under the `"error"` policy.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * const snapshot = world.snapshotSubtree(ship, {
60
+ * components: [Position, LinearVelocity, Hull],
61
+ * relationships: [ChildOf, Carries],
62
+ * externalTargets: "error",
63
+ * });
64
+ * ```
65
+ */
66
+ snapshotSubtree(this: World, rootOrRoots: Entity | readonly Entity[], options?: SubtreeSnapshotOptions): EntitySubtreeSnapshot;
67
+ /**
68
+ * Recreate a captured snapshot inside `destination` with fresh entity ids.
69
+ *
70
+ * Every destination component is built by the canonical materializer, so
71
+ * exclusivity, interface aliases, `add` hooks, and query entry fire exactly
72
+ * as they would for an ordinary `set`. Source instances are never attached:
73
+ * the snapshot holds data only.
74
+ *
75
+ * Edges are rebuilt through the public relationship API, in two passes — the
76
+ * traversal relationship first, then everything else — so
77
+ * hierarchy-sensitive policies see a complete tree. Internal targets are
78
+ * remapped onto the freshly allocated ids; targets left behind at capture time
79
+ * stay left behind.
80
+ *
81
+ * The source entities are untouched. Use {@link moveSubtree} to transfer
82
+ * ownership as well.
83
+ *
84
+ * @param destination - World that receives the snapshot.
85
+ * @param snapshot - A snapshot from {@link snapshotSubtree}.
86
+ * @returns The destination entities, keyed by snapshot key and by source
87
+ * entity.
88
+ * @throws If either world is deferred, a captured class is unregistered or
89
+ * excluded in `destination`, or materialization fails. A failure after
90
+ * creation destroys everything the attempt created.
91
+ */
92
+ restoreSubtree(this: World, destination: World, snapshot: EntitySubtreeSnapshot): RestoreSubtreeResult;
93
+ /**
94
+ * Move one entity's subtree, or several roots as one atomic forest, into
95
+ * `destination`.
96
+ *
97
+ * Capture and preflight both complete before the source is touched, so a
98
+ * snapshot that cannot be restored — an unregistered class, an excluded type —
99
+ * leaves the source world exactly as it was. Only then are the source roots
100
+ * destroyed, and the snapshot is restored into `destination`.
101
+ *
102
+ * If the destination restore fails, everything that restore created is
103
+ * destroyed, the source snapshot is restored back into this world, and a
104
+ * {@link MoveSubtreeError} is thrown carrying the original error as its `cause`.
105
+ *
106
+ * The rollback rebuilds equivalent state with freshly allocated ids, so
107
+ * `Entity` references held before the move are stale afterwards. Rebind them
108
+ * through the thrown error's `restored` map, which is keyed by the old source
109
+ * id. An edge pointing *into* the subtree from an entity outside it is never
110
+ * carried — not by a successful move, and not by the rollback.
111
+ *
112
+ * Destroying a root applies its component `remove` hooks and its relationship
113
+ * cleanup policies, which can reach outside the captured forest. Select
114
+ * transferable data accordingly.
115
+ *
116
+ * @param rootOrRoots - A single root entity, or an array of roots moved as one
117
+ * atomic forest.
118
+ * @param destination - World that receives the forest.
119
+ * @param options - Traversal relationship, component and relationship
120
+ * allowlists, and the external-target policy.
121
+ * @returns The destination entities, keyed by snapshot key and by source
122
+ * entity.
123
+ * @throws {@link MoveSubtreeError} If the destination restore fails after the
124
+ * source was destroyed, with `restored` mapping old source ids to the
125
+ * entities that replaced them. The source forest survives unchanged when
126
+ * capture or preflight fails, in which case the original error is thrown.
127
+ *
128
+ * @example
129
+ * ```ts
130
+ * const result = world.moveSubtree([ship, ...escorts], nextSectorWorld, {
131
+ * components: [Position, LinearVelocity, Hull, Cargo],
132
+ * relationships: [ChildOf, Carries, TetheredTo],
133
+ * });
134
+ * ```
135
+ */
136
+ moveSubtree(this: World, rootOrRoots: Entity | readonly Entity[], destination: World, options?: SubtreeSnapshotOptions): MoveSubtreeResult;
137
+ }
@@ -0,0 +1,188 @@
1
+ // The `World` half of cross-world subtree transfer: `snapshotSubtree`,
2
+ // `restoreSubtree`, and `moveSubtree`. The capture, preflight, and restore
3
+ // mechanics live in `../snapshot/`.
4
+ import { _captureSubtree, _preflightRestore, _restoreSubtree } from "../snapshot/index.js";
5
+ import { Modules } from "./world.modules.js";
6
+ /**
7
+ * Thrown by {@link World.moveSubtree} when the destination restore fails after
8
+ * the source roots have already been destroyed.
9
+ *
10
+ * Everything the destination restore created is destroyed, the source snapshot
11
+ * is restored back into the source world, and the destination's original error
12
+ * becomes this error's `cause`. The rollback rebuilds equivalent state with
13
+ * freshly allocated ids, so callers that held `Entity` references across the
14
+ * failed move must rebind them — {@link restored} is the mapping that does it:
15
+ * old source id to the restored entity that replaced it.
16
+ *
17
+ * Inbound edges — edges pointing *into* the moved subtree from an entity outside
18
+ * it — are not part of the snapshot and are not carried by the rollback either.
19
+ * They belonged to the state left behind in the source world.
20
+ */
21
+ export class MoveSubtreeError extends Error {
22
+ constructor(operation, cause, restored, rollbackFailed) {
23
+ super(`${operation} failed and the source forest was restored with new entity ids` +
24
+ (rollbackFailed ? "; the rollback itself did not complete" : ""));
25
+ this.name = "MoveSubtreeError";
26
+ this.cause = cause;
27
+ this.restored = restored;
28
+ this.rollbackFailed = rollbackFailed;
29
+ }
30
+ }
31
+ export class Transfers extends Modules {
32
+ /**
33
+ * Capture one entity's subtree, or several roots as one atomic forest, into
34
+ * detached records.
35
+ *
36
+ * Nothing in the source world changes: the forest is walked and every selected
37
+ * component and edge is copied before this returns. Entity ids and
38
+ * relationship edges are world-local, so the result carries *data* — its
39
+ * component classes and payloads, plus internal edges keyed by snapshot key —
40
+ * and never a live instance.
41
+ *
42
+ * Per component type, capture follows the type's `OnSnapshot` declaration, set
43
+ * by the module that owns it: plain data clones its own enumerable fields
44
+ * (`ClonePublic`), `DontSnapshot` types are left behind, and
45
+ * `CustomSnapshot` types call the owner's `capture`. Relationship targets
46
+ * inside the forest are stored as snapshot keys; targets outside it follow
47
+ * the `externalTargets` policy.
48
+ *
49
+ * @param rootOrRoots - A single root entity, or an array of roots captured as
50
+ * one forest.
51
+ * @param options - Traversal relationship, component and relationship
52
+ * allowlists, and the external-target policy.
53
+ * @returns A snapshot bound to this world.
54
+ * @throws If the world is deferred, a root is destroyed or is a
55
+ * component-definition entity, the traversal relationship is unregistered,
56
+ * the forest contains a cycle or a repeated member, a selected type is
57
+ * `DontSnapshot`, or an external target is found under the `"error"` policy.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * const snapshot = world.snapshotSubtree(ship, {
62
+ * components: [Position, LinearVelocity, Hull],
63
+ * relationships: [ChildOf, Carries],
64
+ * externalTargets: "error",
65
+ * });
66
+ * ```
67
+ */
68
+ snapshotSubtree(rootOrRoots, options = {}) {
69
+ this._assertNotDeferred("snapshotSubtree");
70
+ return _captureSubtree(this, rootOrRoots, options);
71
+ }
72
+ /**
73
+ * Recreate a captured snapshot inside `destination` with fresh entity ids.
74
+ *
75
+ * Every destination component is built by the canonical materializer, so
76
+ * exclusivity, interface aliases, `add` hooks, and query entry fire exactly
77
+ * as they would for an ordinary `set`. Source instances are never attached:
78
+ * the snapshot holds data only.
79
+ *
80
+ * Edges are rebuilt through the public relationship API, in two passes — the
81
+ * traversal relationship first, then everything else — so
82
+ * hierarchy-sensitive policies see a complete tree. Internal targets are
83
+ * remapped onto the freshly allocated ids; targets left behind at capture time
84
+ * stay left behind.
85
+ *
86
+ * The source entities are untouched. Use {@link moveSubtree} to transfer
87
+ * ownership as well.
88
+ *
89
+ * @param destination - World that receives the snapshot.
90
+ * @param snapshot - A snapshot from {@link snapshotSubtree}.
91
+ * @returns The destination entities, keyed by snapshot key and by source
92
+ * entity.
93
+ * @throws If either world is deferred, a captured class is unregistered or
94
+ * excluded in `destination`, or materialization fails. A failure after
95
+ * creation destroys everything the attempt created.
96
+ */
97
+ restoreSubtree(destination, snapshot) {
98
+ this._assertNotDeferred("restoreSubtree");
99
+ destination._assertNotDeferred("restoreSubtree");
100
+ return _restoreSubtree(destination, snapshot);
101
+ }
102
+ /**
103
+ * Move one entity's subtree, or several roots as one atomic forest, into
104
+ * `destination`.
105
+ *
106
+ * Capture and preflight both complete before the source is touched, so a
107
+ * snapshot that cannot be restored — an unregistered class, an excluded type —
108
+ * leaves the source world exactly as it was. Only then are the source roots
109
+ * destroyed, and the snapshot is restored into `destination`.
110
+ *
111
+ * If the destination restore fails, everything that restore created is
112
+ * destroyed, the source snapshot is restored back into this world, and a
113
+ * {@link MoveSubtreeError} is thrown carrying the original error as its `cause`.
114
+ *
115
+ * The rollback rebuilds equivalent state with freshly allocated ids, so
116
+ * `Entity` references held before the move are stale afterwards. Rebind them
117
+ * through the thrown error's `restored` map, which is keyed by the old source
118
+ * id. An edge pointing *into* the subtree from an entity outside it is never
119
+ * carried — not by a successful move, and not by the rollback.
120
+ *
121
+ * Destroying a root applies its component `remove` hooks and its relationship
122
+ * cleanup policies, which can reach outside the captured forest. Select
123
+ * transferable data accordingly.
124
+ *
125
+ * @param rootOrRoots - A single root entity, or an array of roots moved as one
126
+ * atomic forest.
127
+ * @param destination - World that receives the forest.
128
+ * @param options - Traversal relationship, component and relationship
129
+ * allowlists, and the external-target policy.
130
+ * @returns The destination entities, keyed by snapshot key and by source
131
+ * entity.
132
+ * @throws {@link MoveSubtreeError} If the destination restore fails after the
133
+ * source was destroyed, with `restored` mapping old source ids to the
134
+ * entities that replaced them. The source forest survives unchanged when
135
+ * capture or preflight fails, in which case the original error is thrown.
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * const result = world.moveSubtree([ship, ...escorts], nextSectorWorld, {
140
+ * components: [Position, LinearVelocity, Hull, Cargo],
141
+ * relationships: [ChildOf, Carries, TetheredTo],
142
+ * });
143
+ * ```
144
+ */
145
+ moveSubtree(rootOrRoots, destination, options = {}) {
146
+ this._assertNotDeferred("moveSubtree");
147
+ if (destination === this) {
148
+ throw new Error("moveSubtree requires a destination world other than the source");
149
+ }
150
+ destination._assertNotDeferred("moveSubtree");
151
+ const snapshot = _captureSubtree(this, rootOrRoots, options);
152
+ _preflightRestore(destination, snapshot);
153
+ for (const record of snapshot.entities) {
154
+ if (!record.source.destroyed) {
155
+ record.source.destroy();
156
+ }
157
+ }
158
+ try {
159
+ return _restoreSubtree(destination, snapshot);
160
+ }
161
+ catch (error) {
162
+ const [cause, restored, rollbackFailed] = this._rollback(error, snapshot);
163
+ throw new MoveSubtreeError("moveSubtree", cause, restored, rollbackFailed);
164
+ }
165
+ }
166
+ /** @internal Reject cross-world scheduling while a world is queueing mutations. */
167
+ _assertNotDeferred(operation) {
168
+ if (this.deferred) {
169
+ throw new Error(`${operation} cannot run while the world is deferred; cross-world scheduling is the application's job`);
170
+ }
171
+ }
172
+ /**
173
+ * @internal Best-effort restore of the source forest after a failed transfer.
174
+ *
175
+ * A failed rollback is a consequence of the destination failure, not an
176
+ * independent problem, so it must not mask the original error; it is reported
177
+ * as a flag on the {@link MoveSubtreeError} instead.
178
+ */
179
+ _rollback(cause, snapshot) {
180
+ try {
181
+ return [cause, _restoreSubtree(this, snapshot).entities, false];
182
+ }
183
+ catch {
184
+ return [cause, new Map(), true];
185
+ }
186
+ }
187
+ }
188
+ //# sourceMappingURL=world.transfers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"world.transfers.js","sourceRoot":"","sources":["../../src/world/world.transfers.ts"],"names":[],"mappings":"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"}
package/docs/README.md CHANGED
@@ -17,11 +17,15 @@ Read in this order the first time through:
17
17
  - [Components](./components.md) — registration, hooks, traits, exclusivity, cleanup policies,
18
18
  interfaces, singletons.
19
19
  - [Entities](./entities.md) — creation, lookup, the component API, relationship targets, lifecycle.
20
- - [Systems](./systems.md) — membership, reactive callbacks, callback options, `each`/`run`, cadence, injection.
20
+ - [Systems](./systems.md) — membership, reactive callbacks, callback options, `each`/`run`, cadence,
21
+ component and relationship injection.
21
22
  - [Queries and filters](./queries-and-filters.md) — the query DSL, live queries, one-shot
22
23
  filters, grouped queries, `Bitset`.
23
- - [Relationships](./relationships.md) — links, target creation and ownership, hierarchy, cleanup cascades.
24
+ - [Relationships](./relationships.md) — links, target creation and projection, ownership, hierarchy,
25
+ cleanup cascades.
24
26
  - [Modules](./modules.md) — packaging features, composition, the built-in modules.
27
+ - [Subtree snapshots](./snapshots.md) — capturing, restoring, and moving an entity forest
28
+ between two worlds.
25
29
  5. [Design guide](./design-guide.md) — opinionated patterns and anti-patterns distilled from real
26
30
  designs. Read it once you know the machinery.
27
31
  6. [Utilities](./utilities.md) — helper classes exported by `@vworlds/vecs` but not part of the ECS
@@ -38,13 +42,21 @@ Keep the [Glossary](./glossary.md) at hand for terminology.
38
42
  | [execution-model.md](./execution-model.md) | `world.progress`, the 8 built-in phases, deferred commands, flush boundaries, event routing. |
39
43
  | [components.md](./components.md) | Component registration, hooks, traits, exclusivity, cleanup, aliases, and singletons. |
40
44
  | [entities.md](./entities.md) | Entity creation, component mutation, relationship targets, lifecycle, deferred reads. |
41
- | [systems.md](./systems.md) | `world.system`, `with`/`without`, `enter`/`update`/`exit`, callback options, tick sources. |
45
+ | [systems.md](./systems.md) | `world.system`, callbacks, injection, ordering, cadence, and tick sources. |
42
46
  | [queries-and-filters.md](./queries-and-filters.md) | `QueryDSL`, `Query`, `Filter`, `groupBy`, `ignoreSource`. |
43
- | [relationships.md](./relationships.md) | Relationships, target creation and ownership, hierarchy, traversal, and cleanup cascades. |
47
+ | [relationships.md](./relationships.md) | Relationships, target creation, projection and ownership, hierarchy, traversal, and cleanup. |
44
48
  | [modules.md](./modules.md) | `Module<Config>`, `world.module`, composition, built-in modules. |
49
+ | [snapshots.md](./snapshots.md) | `snapshotSubtree`, `restoreSubtree`, `moveSubtree`, and `OnSnapshot` capture policies. |
45
50
  | [design-guide.md](./design-guide.md) | Patterns, anti-patterns, and a Phaser render-layer case study. |
46
51
  | [utilities.md](./utilities.md) | Public helper classes: `Events`, `ArrayMap`, `IterableArrayMap`, plus `Bitset` cross-ref. |
47
52
  | [glossary.md](./glossary.md) | ECS and vecs terminology. |
48
53
 
49
- Networking (wire encoding with `@wireType`, protocol component ordering, replication) lives in the
50
- `@vworlds/vecs-wire` and `@vworlds/vecs-protocol` packages and is only cross-referenced here.
54
+ Networking (wire encoding with `@wireType`, protocol component ordering, replication, RPCs, server
55
+ sessions, and the client world) lives in the `@vworlds/vecs-wire`, `@vworlds/vecs-protocol`,
56
+ `@vworlds/vecs-server`, and `@vworlds/vecs-client` packages:
57
+
58
+ - [Remote procedure calls](../../vecs-protocol/docs/rpc.md) — the call channel and typed errors.
59
+ - [Sessions and caller context](../../vecs-server/docs/sessions.md) — per-connection RPC context,
60
+ `closeSession`, and exactly-once teardown.
61
+ - [Client world](../../vecs-client/docs/client-world.md) — replication, `invoke`/`listen`, and
62
+ disposal.