@spearwolf/shadow-objects 0.32.0 → 0.33.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.
Files changed (82) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/README.md +49 -13
  3. package/bundle.js +7 -7
  4. package/package.json +2 -2
  5. package/src/elements/ShaeEntElement.d.ts +4 -4
  6. package/src/elements/ShaeEntElement.d.ts.map +1 -1
  7. package/src/elements/ShaeEntElement.js +4 -5
  8. package/src/elements/ShaeEntElement.js.map +2 -2
  9. package/src/elements/ShaePropElement.d.ts +5 -5
  10. package/src/elements/ShaePropElement.d.ts.map +1 -1
  11. package/src/elements/ShaePropElement.js +2 -2
  12. package/src/elements/ShaePropElement.js.map +2 -2
  13. package/src/elements/ShaeWorkerElement.d.ts.map +1 -1
  14. package/src/elements/ShaeWorkerElement.js +31 -6
  15. package/src/elements/ShaeWorkerElement.js.map +2 -2
  16. package/src/in-the-dark/Kernel.d.ts +5 -0
  17. package/src/in-the-dark/Kernel.d.ts.map +1 -1
  18. package/src/in-the-dark/Kernel.js +49 -24
  19. package/src/in-the-dark/Kernel.js.map +2 -2
  20. package/src/in-the-dark/Registry.d.ts +1 -1
  21. package/src/in-the-dark/Registry.d.ts.map +1 -1
  22. package/src/in-the-dark/Registry.js +24 -20
  23. package/src/in-the-dark/Registry.js.map +2 -2
  24. package/src/in-the-dark/ShadowObject.d.ts +1 -1
  25. package/src/in-the-dark/ShadowObject.d.ts.map +1 -1
  26. package/src/in-the-dark/ShadowObject.js +2 -2
  27. package/src/in-the-dark/ShadowObject.js.map +2 -2
  28. package/src/in-the-dark/SignalsPath.d.ts.map +1 -1
  29. package/src/in-the-dark/SignalsPath.js.map +2 -2
  30. package/src/in-the-dark/importModule.js +3 -3
  31. package/src/in-the-dark/importModule.js.map +2 -2
  32. package/src/types.d.ts +4 -4
  33. package/src/types.d.ts.map +1 -1
  34. package/src/utils/ConsoleLogger.d.ts.map +1 -1
  35. package/src/utils/ConsoleLogger.js +3 -2
  36. package/src/utils/ConsoleLogger.js.map +2 -2
  37. package/src/utils/FrameLoop.d.ts +1 -1
  38. package/src/utils/FrameLoop.d.ts.map +1 -1
  39. package/src/utils/FrameLoop.js +0 -2
  40. package/src/utils/FrameLoop.js.map +2 -2
  41. package/src/utils/attr-utils.d.ts.map +1 -1
  42. package/src/utils/attr-utils.js +1 -1
  43. package/src/utils/attr-utils.js.map +2 -2
  44. package/src/utils/generateUUID.d.ts +1 -1
  45. package/src/utils/generateUUID.d.ts.map +1 -1
  46. package/src/utils/props-utils.d.ts +1 -1
  47. package/src/utils/props-utils.d.ts.map +1 -1
  48. package/src/utils/waitForMessageOfType.d.ts +5 -1
  49. package/src/utils/waitForMessageOfType.d.ts.map +1 -1
  50. package/src/utils/waitForMessageOfType.js +12 -2
  51. package/src/utils/waitForMessageOfType.js.map +2 -2
  52. package/src/view/ComponentChanges.d.ts +4 -1
  53. package/src/view/ComponentChanges.d.ts.map +1 -1
  54. package/src/view/ComponentChanges.js +20 -6
  55. package/src/view/ComponentChanges.js.map +2 -2
  56. package/src/view/ComponentContext.d.ts +43 -1
  57. package/src/view/ComponentContext.d.ts.map +1 -1
  58. package/src/view/ComponentContext.js +123 -47
  59. package/src/view/ComponentContext.js.map +2 -2
  60. package/src/view/ComponentMemory.js +3 -1
  61. package/src/view/ComponentMemory.js.map +2 -2
  62. package/src/view/IShadowObjectEnvProxy.d.ts +6 -0
  63. package/src/view/IShadowObjectEnvProxy.d.ts.map +1 -1
  64. package/src/view/LocalShadowObjectEnv.d.ts +1 -1
  65. package/src/view/LocalShadowObjectEnv.d.ts.map +1 -1
  66. package/src/view/LocalShadowObjectEnv.js +11 -6
  67. package/src/view/LocalShadowObjectEnv.js.map +2 -2
  68. package/src/view/RemoteWorkerEnv.d.ts +42 -0
  69. package/src/view/RemoteWorkerEnv.d.ts.map +1 -1
  70. package/src/view/RemoteWorkerEnv.js +130 -18
  71. package/src/view/RemoteWorkerEnv.js.map +2 -2
  72. package/src/view/ShadowEnv.d.ts +25 -1
  73. package/src/view/ShadowEnv.d.ts.map +1 -1
  74. package/src/view/ShadowEnv.js +103 -29
  75. package/src/view/ShadowEnv.js.map +2 -2
  76. package/src/view/ViewComponent.d.ts +22 -1
  77. package/src/view/ViewComponent.d.ts.map +1 -1
  78. package/src/view/ViewComponent.js +66 -22
  79. package/src/view/ViewComponent.js.map +2 -2
  80. package/src/worker/MessageRouter.d.ts.map +1 -1
  81. package/src/worker/MessageRouter.js +7 -5
  82. package/src/worker/MessageRouter.js.map +2 -2
@@ -21,6 +21,13 @@ declare global {
21
21
  * If no namespace is specified when creating a {@link ComponentContext}, the global namespace is used.
22
22
  * There is only one {@link ComponentContext} (a singleton) for each namespace.
23
23
  */
24
+ /**
25
+ * Thrown when a {@link ViewComponent} tries to join a {@link ComponentContext} that has
26
+ * already been disposed.
27
+ */
28
+ export declare class ComponentContextDisposedError extends Error {
29
+ constructor(message?: string);
30
+ }
24
31
  export declare class ComponentContext {
25
32
  #private;
26
33
  static readonly ReRequestParentRoots = "re-request-parent-roots";
@@ -28,6 +35,14 @@ export declare class ComponentContext {
28
35
  static get(namespace?: NamespaceType): ComponentContext;
29
36
  ns?: NamespaceType;
30
37
  constructor(namespace?: NamespaceType);
38
+ /**
39
+ * Whether this context has been torn down by {@link ComponentContext.dispose}.
40
+ *
41
+ * A disposed context holds no components, produces empty change trails and no longer
42
+ * occupies its namespace. It cannot be revived; use {@link ComponentContext.get} to
43
+ * obtain a fresh context for the same namespace.
44
+ */
45
+ get isDisposed(): boolean;
31
46
  addComponent(component: ViewComponent): void;
32
47
  hasComponent(component: ViewComponent): boolean;
33
48
  hasComponents(): boolean;
@@ -39,8 +54,16 @@ export declare class ComponentContext {
39
54
  changeToken(component: ViewComponent, token?: string): void;
40
55
  isChildOf(child: ViewComponent, parent: ViewComponent): boolean;
41
56
  addToChildren(parent: ViewComponent, child: ViewComponent): void;
57
+ /**
58
+ * Destroy a component and all its descendants without writing anything to a change trail.
59
+ *
60
+ * @see {@link ComponentContext.clear}
61
+ */
42
62
  removeSubTree(uuid: string): void;
43
- setProperty<T = unknown>(component: ViewComponent, propKey: string, value: T, isEqual?: (a: T, b: T) => boolean): false | void;
63
+ /**
64
+ * @returns `true` if the value differs from the last value written to a change trail
65
+ */
66
+ setProperty<T = unknown>(component: ViewComponent, propKey: string, value: T, isEqual?: (a: T, b: T) => boolean): boolean;
44
67
  removeProperty(component: ViewComponent, propKey: string): void;
45
68
  changeOrder(component: ViewComponent): void;
46
69
  /**
@@ -77,6 +100,25 @@ export declare class ComponentContext {
77
100
  * @see {@link ComponentContext.buildChangeTrails}
78
101
  */
79
102
  reCreateChanges(): void;
103
+ /**
104
+ * Remove all components without writing anything to a change trail. The context stays
105
+ * registered under its namespace and can be used again afterwards.
106
+ *
107
+ * @see {@link ComponentContext.dispose} for the final teardown
108
+ */
80
109
  clear(): void;
110
+ /**
111
+ * Tear the context down for good: every {@link ViewComponent} it holds is destroyed, the
112
+ * component memory is dropped, and the namespace is released so that
113
+ * {@link ComponentContext.get} creates a fresh context for it.
114
+ *
115
+ * Unlike {@link ComponentContext.clear} this is final. The context holds no components,
116
+ * produces empty change trails, and rejects any component that tries to join it. Calling
117
+ * it more than once is a no-op.
118
+ *
119
+ * A {@link ShadowEnv} bound to this context keeps its reference; destroy the environment
120
+ * first if you want the namespace released on both sides.
121
+ */
122
+ dispose(): void;
81
123
  }
82
124
  //# sourceMappingURL=ComponentContext.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ComponentContext.d.ts","sourceRoot":"","sources":["../../../src/view/ComponentContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,eAAe,EAAwB,aAAa,EAAC,MAAM,aAAa,CAAC;AAKtF,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAStD,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,oBAAoB,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,gBAAgB,CAAC,GAAG,SAAS,CAAC;CAC9E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,gBAAgB;;IAC3B,MAAM,CAAC,QAAQ,CAAC,oBAAoB,6BAA6B;IAEjE,MAAM,CAAC,cAAc,IAAI,GAAG,CAAC,aAAa,EAAE,gBAAgB,CAAC;IAO7D,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,gBAAgB;IASvD,EAAE,CAAC,EAAE,aAAa,CAAC;gBAOP,SAAS,GAAE,aAAwB;IAU/C,YAAY,CAAC,SAAS,EAAE,aAAa;IAkCrC,YAAY,CAAC,SAAS,EAAE,aAAa;IAIrC,aAAa;IAIb,eAAe,CAAC,SAAS,EAAE,aAAa;IAIxC,gBAAgB,CAAC,SAAS,EAAE,aAAa;IASzC,WAAW,CAAC,SAAS,EAAE,aAAa,GAAG,aAAa,EAAE;IAItD,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa;IAczD,UAAU,CAAC,SAAS,EAAE,MAAM;IAS5B,WAAW,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,MAAM;IAIpD,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa;IAQrD,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa;IAYzD,aAAa,CAAC,IAAI,EAAE,MAAM;IAS1B,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO;IAc/G,cAAc,CAAC,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM;IAIxD,WAAW,CAAC,SAAS,EAAE,aAAa;IAapC;;OAEG;IACH,qBAAqB,IAAI,aAAa,EAAE;IAIxC;;OAEG;IACH,0BAA0B,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,YAAY,EAAE;IAIhH;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,OAAmB;IAMtD;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,OAAmB,EAAE,gBAAgB,UAAQ;IAI/F;;OAEG;IACH,4BAA4B;IAM5B;;;;;OAKG;IACH,iBAAiB,CAAC,YAAY,UAAO,GAAG,eAAe;IAmCvD;;;;;OAKG;IACH,eAAe;IA6Bf,KAAK;CA2GN"}
1
+ {"version":3,"file":"ComponentContext.d.ts","sourceRoot":"","sources":["../../../src/view/ComponentContext.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,eAAe,EAAwB,aAAa,EAAC,MAAM,aAAa,CAAC;AAKtF,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAStD,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,oBAAoB,EAAE,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,gBAAgB,CAAC,GAAG,SAAS,CAAC;CAC9E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH;;;GAGG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;gBAC1C,OAAO,SAA4C;CAIhE;AAED,qBAAa,gBAAgB;;IAC3B,MAAM,CAAC,QAAQ,CAAC,oBAAoB,6BAA6B;IAEjE,MAAM,CAAC,cAAc,IAAI,GAAG,CAAC,aAAa,EAAE,gBAAgB,CAAC;IAO7D,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,aAAa,GAAG,gBAAgB;IASvD,EAAE,CAAC,EAAE,aAAa,CAAC;gBAQP,SAAS,GAAE,aAAwB;IAU/C;;;;;;OAMG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,YAAY,CAAC,SAAS,EAAE,aAAa;IA+CrC,YAAY,CAAC,SAAS,EAAE,aAAa;IAIrC,aAAa;IAIb,eAAe,CAAC,SAAS,EAAE,aAAa;IAIxC,gBAAgB,CAAC,SAAS,EAAE,aAAa;IAWzC,WAAW,CAAC,SAAS,EAAE,aAAa,GAAG,aAAa,EAAE;IAItD,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa;IAkBzD,UAAU,CAAC,SAAS,EAAE,MAAM;IAS5B,WAAW,CAAC,SAAS,EAAE,aAAa,EAAE,KAAK,CAAC,EAAE,MAAM;IAIpD,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa;IAQrD,aAAa,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa;IAYzD;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM;IAkB1B;;OAEG;IACH,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,OAAO;IAczH,cAAc,CAAC,SAAS,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM;IAIxD,WAAW,CAAC,SAAS,EAAE,aAAa;IAmBpC;;OAEG;IACH,qBAAqB,IAAI,aAAa,EAAE;IAIxC;;OAEG;IACH,0BAA0B,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,YAAY,EAAE;IAIhH;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,OAAmB;IAMtD;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,OAAmB,EAAE,gBAAgB,UAAQ;IAI/F;;OAEG;IACH,4BAA4B;IAM5B;;;;;OAKG;IACH,iBAAiB,CAAC,YAAY,UAAO,GAAG,eAAe;IAmCvD;;;;;OAKG;IACH,eAAe;IA6Bf;;;;;OAKG;IACH,KAAK;IAiBL;;;;;;;;;;;OAWG;IACH,OAAO;CAyGR"}
@@ -3,6 +3,12 @@ import { removeFrom } from "../utils/array-utils.js";
3
3
  import { toNamespace } from "../utils/toNamespace.js";
4
4
  import { ComponentChanges } from "./ComponentChanges.js";
5
5
  import { ComponentMemory } from "./ComponentMemory.js";
6
+ class ComponentContextDisposedError extends Error {
7
+ constructor(message = "the component context has been disposed") {
8
+ super(message);
9
+ this.name = "ComponentContextDisposedError";
10
+ }
11
+ }
6
12
  class ComponentContext {
7
13
  static {
8
14
  this.ReRequestParentRoots = "re-request-parent-roots";
@@ -24,6 +30,7 @@ class ComponentContext {
24
30
  #components = /* @__PURE__ */ new Map();
25
31
  #rootComponents = [];
26
32
  // we use an Array here and not a Set, because we want to keep the insertion order
33
+ #isDisposed = false;
27
34
  #componentMemory = new ComponentMemory();
28
35
  constructor(namespace = GlobalNS) {
29
36
  const ns = toNamespace(namespace);
@@ -34,10 +41,29 @@ class ComponentContext {
34
41
  this.ns = ns;
35
42
  ctxMap.set(ns, this);
36
43
  }
44
+ /**
45
+ * Whether this context has been torn down by {@link ComponentContext.dispose}.
46
+ *
47
+ * A disposed context holds no components, produces empty change trails and no longer
48
+ * occupies its namespace. It cannot be revived; use {@link ComponentContext.get} to
49
+ * obtain a fresh context for the same namespace.
50
+ */
51
+ get isDisposed() {
52
+ return this.#isDisposed;
53
+ }
37
54
  addComponent(component) {
38
- let viewInstance;
39
- if (this.#components.has(component.uuid)) {
40
- viewInstance = this.#components.get(component.uuid);
55
+ if (this.#isDisposed) {
56
+ throw new ComponentContextDisposedError(
57
+ `the view component ${component.uuid} cannot join the component context because it has been disposed`
58
+ );
59
+ }
60
+ let viewInstance = this.#components.get(component.uuid);
61
+ if (viewInstance) {
62
+ if (viewInstance.component !== component) {
63
+ for (const childUuid of viewInstance.children.slice(0)) {
64
+ this.#components.get(childUuid)?.component.removeFromParent();
65
+ }
66
+ }
41
67
  viewInstance.component = component;
42
68
  viewInstance.children = [];
43
69
  } else {
@@ -75,7 +101,9 @@ class ComponentContext {
75
101
  destroyComponent(component) {
76
102
  if (this.hasComponent(component)) {
77
103
  const entry = this.#components.get(component.uuid);
78
- entry.children.slice(0).forEach((childUuid) => this.#components.get(childUuid)?.component.removeFromParent());
104
+ for (const childUuid of entry.children.slice(0)) {
105
+ this.#components.get(childUuid)?.component.removeFromParent();
106
+ }
79
107
  entry.changes.destroy();
80
108
  this.#viewInstances = void 0;
81
109
  }
@@ -86,6 +114,7 @@ class ComponentContext {
86
114
  removeFromParent(childUuid, parent) {
87
115
  if (this.hasComponent(parent)) {
88
116
  const childEntry = this.#components.get(childUuid);
117
+ if (childEntry === void 0) return;
89
118
  const parentEntry = this.#components.get(parent.uuid);
90
119
  const childIdx = parentEntry.children.indexOf(childUuid);
91
120
  if (childIdx !== -1) {
@@ -125,14 +154,29 @@ class ComponentContext {
125
154
  throw new Error(`the view component ${parent.uuid} cannot have a child added to it because the component do not exist!`);
126
155
  }
127
156
  }
157
+ /**
158
+ * Destroy a component and all its descendants without writing anything to a change trail.
159
+ *
160
+ * @see {@link ComponentContext.clear}
161
+ */
128
162
  removeSubTree(uuid) {
163
+ this.#removeSubTree(uuid, /* @__PURE__ */ new Set());
164
+ }
165
+ #removeSubTree(uuid, visited) {
166
+ if (visited.has(uuid)) return;
167
+ visited.add(uuid);
129
168
  const entry = this.#components.get(uuid);
130
169
  if (entry) {
131
- entry.children.slice(0).forEach((childUuid) => this.removeSubTree(childUuid));
170
+ for (const childUuid of entry.children.slice(0)) {
171
+ this.#removeSubTree(childUuid, visited);
172
+ }
132
173
  this.destroyComponent(entry.component);
133
174
  this.#deleteComponent(uuid);
134
175
  }
135
176
  }
177
+ /**
178
+ * @returns `true` if the value differs from the last value written to a change trail
179
+ */
136
180
  setProperty(component, propKey, value, isEqual) {
137
181
  const vi = this.#components.get(component.uuid);
138
182
  if (vi != null) {
@@ -150,15 +194,17 @@ class ComponentContext {
150
194
  this.#components.get(component.uuid)?.changes.removeProperty(propKey);
151
195
  }
152
196
  changeOrder(component) {
153
- if (component.parent) {
154
- const parentEntry = this.#components.get(component.parent.uuid);
197
+ const entry = this.#components.get(component.uuid);
198
+ if (entry === void 0) return;
199
+ const parentEntry = component.parent ? this.#components.get(component.parent.uuid) : void 0;
200
+ if (parentEntry !== void 0) {
155
201
  removeFrom(parentEntry.children, component.uuid);
156
202
  this.#appendToOrdered(component, parentEntry.children);
157
- } else {
203
+ } else if (component.parent == null) {
158
204
  removeFrom(this.#rootComponents, component.uuid);
159
205
  this.#appendToOrdered(component, this.#rootComponents);
160
206
  }
161
- this.#components.get(component.uuid)?.changes.changeOrder(component.order);
207
+ entry.changes.changeOrder(component.order);
162
208
  this.#viewInstances = void 0;
163
209
  }
164
210
  /**
@@ -248,10 +294,18 @@ class ComponentContext {
248
294
  this.#componentMemory.clear();
249
295
  this.broadcastEvent(ContextLost);
250
296
  }
297
+ /**
298
+ * Remove all components without writing anything to a change trail. The context stays
299
+ * registered under its namespace and can be used again afterwards.
300
+ *
301
+ * @see {@link ComponentContext.dispose} for the final teardown
302
+ */
251
303
  clear() {
252
304
  this.#viewInstances = void 0;
253
305
  this.#componentMemory.clear();
254
- this.#rootComponents.slice(0).forEach((uuid) => this.removeSubTree(uuid));
306
+ for (const uuid of this.#rootComponents.slice(0)) {
307
+ this.removeSubTree(uuid);
308
+ }
255
309
  if (this.#rootComponents.length !== 0) {
256
310
  throw new Error("component-context panic: #rootComponents is not empty!");
257
311
  }
@@ -259,52 +313,70 @@ class ComponentContext {
259
313
  throw new Error("component-context panic: #components is not empty!");
260
314
  }
261
315
  }
316
+ /**
317
+ * Tear the context down for good: every {@link ViewComponent} it holds is destroyed, the
318
+ * component memory is dropped, and the namespace is released so that
319
+ * {@link ComponentContext.get} creates a fresh context for it.
320
+ *
321
+ * Unlike {@link ComponentContext.clear} this is final. The context holds no components,
322
+ * produces empty change trails, and rejects any component that tries to join it. Calling
323
+ * it more than once is a no-op.
324
+ *
325
+ * A {@link ShadowEnv} bound to this context keeps its reference; destroy the environment
326
+ * first if you want the namespace released on both sides.
327
+ */
328
+ dispose() {
329
+ if (this.#isDisposed) return;
330
+ for (const { component } of Array.from(this.#components.values())) {
331
+ component.destroy();
332
+ }
333
+ this.clear();
334
+ this.#isDisposed = true;
335
+ const ctxMap = ComponentContext.getContextsMap();
336
+ if (this.ns != null && ctxMap.get(this.ns) === this) {
337
+ ctxMap.delete(this.ns);
338
+ }
339
+ }
262
340
  #deleteComponent(uuid) {
263
- if (this.#components.has(uuid)) {
264
- this.#components.delete(uuid);
265
- removeFrom(this.#rootComponents, uuid);
266
- this.#viewInstances = void 0;
341
+ const entry = this.#components.get(uuid);
342
+ if (entry === void 0) return;
343
+ const parentUuid = entry.component.parent?.uuid;
344
+ if (parentUuid !== void 0) {
345
+ const parentEntry = this.#components.get(parentUuid);
346
+ if (parentEntry !== void 0) {
347
+ removeFrom(parentEntry.children, uuid);
348
+ }
267
349
  }
350
+ this.#components.delete(uuid);
351
+ removeFrom(this.#rootComponents, uuid);
352
+ this.#viewInstances = void 0;
268
353
  }
269
354
  #buildPathOfChanges() {
270
355
  return this.#traverseLevelOrderBFS().filter((vi) => vi.changes.hasChanges()).map((vi) => vi.changes);
271
356
  }
357
+ /**
358
+ * Insert a component into an ordered list of uuids.
359
+ *
360
+ * The list is kept sorted by ascending {@link ViewComponent#order}. Components sharing
361
+ * the same order value keep their insertion order, so the new component is placed after
362
+ * all components with an equal order.
363
+ *
364
+ * Uuids without a matching view instance are skipped instead of dereferenced, so a
365
+ * partially torn down list can never turn a reordering into an exception.
366
+ */
272
367
  #appendToOrdered(component, childUuids) {
273
- if (childUuids.length === 0) {
274
- childUuids.push(component.uuid);
275
- return;
276
- }
277
368
  if (childUuids.includes(component.uuid)) {
278
369
  return;
279
370
  }
280
- const len = childUuids.length;
281
- const childComponents = new Array(len);
282
- childComponents[0] = this.#components.get(childUuids[0]).component;
283
- if (component.order < childComponents[0].order) {
284
- childUuids.unshift(component.uuid);
285
- return;
286
- }
287
- if (len === 1) {
288
- childUuids.push(component.uuid);
289
- return;
290
- }
291
- const lastIdx = len - 1;
292
- childComponents[lastIdx] = this.#components.get(childUuids[lastIdx]).component;
293
- if (component.order >= childComponents[lastIdx].order) {
294
- childUuids.push(component.uuid);
295
- return;
296
- }
297
- if (len === 2) {
298
- childUuids.splice(1, 0, component.uuid);
299
- return;
300
- }
301
- for (let i = lastIdx - 1; i >= 1; i--) {
302
- childComponents[i] = this.#components.get(childUuids[i]).component;
303
- if (component.order >= childComponents[i].order) {
304
- childUuids.splice(i + 1, 0, component.uuid);
371
+ const { order } = component;
372
+ for (let i = 0; i < childUuids.length; i++) {
373
+ const other = this.#components.get(childUuids[i])?.component;
374
+ if (other !== void 0 && order < other.order) {
375
+ childUuids.splice(i, 0, component.uuid);
305
376
  return;
306
377
  }
307
378
  }
379
+ childUuids.push(component.uuid);
308
380
  }
309
381
  #viewInstances;
310
382
  #traverseLevelOrderBFS() {
@@ -313,8 +385,9 @@ class ComponentContext {
313
385
  const traverse = (uuid, depth) => {
314
386
  const viewInstance = this.#components.get(uuid);
315
387
  if (viewInstance == null) return;
316
- if (lvl.has(depth)) {
317
- lvl.get(depth).push(viewInstance);
388
+ const atDepth = lvl.get(depth);
389
+ if (atDepth) {
390
+ atDepth.push(viewInstance);
318
391
  } else {
319
392
  lvl.set(depth, [viewInstance]);
320
393
  }
@@ -322,12 +395,15 @@ class ComponentContext {
322
395
  traverse(childUuid, depth + 1);
323
396
  }
324
397
  };
325
- this.#rootComponents.forEach((uuid) => traverse(uuid, 0));
398
+ for (const uuid of this.#rootComponents) {
399
+ traverse(uuid, 0);
400
+ }
326
401
  this.#viewInstances = Array.from(lvl.entries()).sort((a, b) => a[0] - b[0]).flatMap(([, vi]) => vi);
327
402
  return this.#viewInstances;
328
403
  }
329
404
  }
330
405
  export {
331
- ComponentContext
406
+ ComponentContext,
407
+ ComponentContextDisposedError
332
408
  };
333
409
  //# sourceMappingURL=ComponentContext.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/view/ComponentContext.ts"],
4
- "sourcesContent": ["import {ChangeTrailPhase, ContextLost, GlobalNS} from '../constants.js';\nimport type {ChangeTrailType, IComponentChangeType, NamespaceType} from '../types.js';\nimport {removeFrom} from '../utils/array-utils.js';\nimport {toNamespace} from '../utils/toNamespace.js';\nimport {ComponentChanges} from './ComponentChanges.js';\nimport {ComponentMemory} from './ComponentMemory.js';\nimport type {ViewComponent} from './ViewComponent.js';\n\ninterface ViewInstance {\n component: ViewComponent;\n children: string[]; // we use an Array here and not a Set, because we want to keep the insertion order\n changes: ComponentChanges;\n propIsEqual?: Map<string, (a: any, b: any) => boolean>;\n}\n\ndeclare global {\n // eslint-disable-next-line no-var\n var __shadowEntsContexts: Map<string | symbol, ComponentContext> | undefined;\n}\n\n/**\n * The {@link ComponentContext} represents the current real-time state of the _view components_.\n *\n * Changes to the components and their hierarchy are also logged to the {@link ComponentChanges}.\n *\n * Each time a change trail is created (a call to {@link ComponentContext#buildChangeTrails}),\n * the past changes are summarized and returned as the result. This means that the change trail\n * is always the path of changes from the time of the previous change trail (or from the beginning)\n * to the current call to the {@link ComponentContext#buildChangeTrails} method.\n *\n * In addition, there is the {@link ComponentMemory}. The memory represents the component state at\n * the time of the last change trail, as opposed to the {@link ComponentContext}, which represents\n * the current real-time state of the _view components_.\n *\n * A context is always associated with a namespace.\n * If no namespace is specified when creating a {@link ComponentContext}, the global namespace is used.\n * There is only one {@link ComponentContext} (a singleton) for each namespace.\n */\nexport class ComponentContext {\n static readonly ReRequestParentRoots = 're-request-parent-roots';\n\n static getContextsMap(): Map<NamespaceType, ComponentContext> {\n if (globalThis.__shadowEntsContexts == null) {\n globalThis.__shadowEntsContexts = new Map<NamespaceType, ComponentContext>();\n }\n return globalThis.__shadowEntsContexts;\n }\n\n static get(namespace?: NamespaceType): ComponentContext {\n const ns = toNamespace(namespace);\n const ctxMap = ComponentContext.getContextsMap();\n if (ctxMap.has(ns)) {\n return ctxMap.get(ns)!;\n }\n return new ComponentContext(ns);\n }\n\n ns?: NamespaceType;\n\n #components: Map<string, ViewInstance> = new Map();\n #rootComponents: string[] = []; // we use an Array here and not a Set, because we want to keep the insertion order\n\n readonly #componentMemory = new ComponentMemory();\n\n constructor(namespace: NamespaceType = GlobalNS) {\n const ns = toNamespace(namespace);\n const ctxMap = ComponentContext.getContextsMap();\n if (ctxMap.has(ns)) {\n return ctxMap.get(ns)!;\n }\n this.ns = ns;\n ctxMap.set(ns, this);\n }\n\n addComponent(component: ViewComponent) {\n let viewInstance: ViewInstance | undefined;\n\n if (this.#components.has(component.uuid)) {\n viewInstance = this.#components.get(component.uuid);\n viewInstance.component = component;\n viewInstance.children = [];\n } else {\n viewInstance = {\n component,\n children: [],\n changes: new ComponentChanges(component.uuid),\n propIsEqual: undefined,\n };\n this.#components.set(component.uuid, viewInstance);\n }\n\n viewInstance.changes.create(\n component.token,\n component.parent?.uuid,\n component.order,\n component.autoDestructionOnParentRemoval,\n );\n\n if (component.parent) {\n this.addToChildren(component.parent, component);\n viewInstance.changes.setParent(component.parent.uuid);\n } else {\n this.#appendToOrdered(component, this.#rootComponents);\n }\n\n this.#viewInstances = undefined;\n }\n\n hasComponent(component: ViewComponent) {\n return this.#components.has(component.uuid);\n }\n\n hasComponents() {\n return this.#components.size > 0;\n }\n\n isRootComponent(component: ViewComponent) {\n return this.#rootComponents.includes(component.uuid);\n }\n\n destroyComponent(component: ViewComponent) {\n if (this.hasComponent(component)) {\n const entry = this.#components.get(component.uuid)!;\n entry.children.slice(0).forEach((childUuid) => this.#components.get(childUuid)?.component.removeFromParent());\n entry.changes.destroy();\n this.#viewInstances = undefined;\n }\n }\n\n getChildren(component: ViewComponent): ViewComponent[] {\n return this.#components.get(component.uuid)?.children.map((uuid) => this.#components.get(uuid)!.component) ?? [];\n }\n\n removeFromParent(childUuid: string, parent: ViewComponent) {\n if (this.hasComponent(parent)) {\n const childEntry = this.#components.get(childUuid)!;\n const parentEntry = this.#components.get(parent.uuid)!;\n const childIdx = parentEntry.children.indexOf(childUuid);\n if (childIdx !== -1) {\n parentEntry.children.splice(childIdx, 1);\n childEntry.changes.setParent(undefined);\n }\n this.#appendToOrdered(childEntry.component, this.#rootComponents);\n this.#viewInstances = undefined;\n }\n }\n\n moveToRoot(childUuid: string) {\n const childEntry = this.#components.get(childUuid)!;\n if (childEntry) {\n childEntry.changes?.setParent(undefined);\n this.#appendToOrdered(childEntry.component, this.#rootComponents);\n }\n this.#viewInstances = undefined;\n }\n\n changeToken(component: ViewComponent, token?: string) {\n this.#components.get(component.uuid)?.changes.changeToken(token);\n }\n\n isChildOf(child: ViewComponent, parent: ViewComponent) {\n if (this.hasComponent(parent)) {\n const entry = this.#components.get(parent.uuid)!;\n return entry.children.includes(child.uuid);\n }\n return false;\n }\n\n addToChildren(parent: ViewComponent, child: ViewComponent) {\n const entry = this.#components.get(parent.uuid);\n if (entry) {\n this.#appendToOrdered(child, entry.children);\n this.#components.get(child.uuid)?.changes.setParent(parent.uuid);\n removeFrom(this.#rootComponents, child.uuid);\n this.#viewInstances = undefined;\n } else {\n throw new Error(`the view component ${parent.uuid} cannot have a child added to it because the component do not exist!`);\n }\n }\n\n removeSubTree(uuid: string) {\n const entry = this.#components.get(uuid);\n if (entry) {\n entry.children.slice(0).forEach((childUuid) => this.removeSubTree(childUuid));\n this.destroyComponent(entry.component);\n this.#deleteComponent(uuid);\n }\n }\n\n setProperty<T = unknown>(component: ViewComponent, propKey: string, value: T, isEqual?: (a: T, b: T) => boolean) {\n const vi = this.#components.get(component.uuid);\n if (vi != null) {\n if (isEqual != null) {\n vi.propIsEqual ??= new Map();\n vi.propIsEqual.set(propKey, isEqual);\n } else if (vi.propIsEqual?.has(propKey)) {\n vi.propIsEqual.delete(propKey);\n }\n return vi.changes.changeProperty(propKey, value, isEqual);\n }\n return false;\n }\n\n removeProperty(component: ViewComponent, propKey: string) {\n this.#components.get(component.uuid)?.changes.removeProperty(propKey);\n }\n\n changeOrder(component: ViewComponent) {\n if (component.parent) {\n const parentEntry = this.#components.get(component.parent.uuid)!;\n removeFrom(parentEntry.children, component.uuid);\n this.#appendToOrdered(component, parentEntry.children);\n } else {\n removeFrom(this.#rootComponents, component.uuid);\n this.#appendToOrdered(component, this.#rootComponents);\n }\n this.#components.get(component.uuid)?.changes.changeOrder(component.order);\n this.#viewInstances = undefined;\n }\n\n /**\n * @returns all view-components in breadth-first order\n */\n traverseLevelOrderBFS(): ViewComponent[] {\n return this.#traverseLevelOrderBFS().map((vi) => vi.component);\n }\n\n /**\n * Dispatch an event to the shadow objects linked to the view component\n */\n dispatchShadowObjectsEvent(component: ViewComponent, type: string, data: unknown, transferables?: Transferable[]) {\n this.#components.get(component.uuid)?.changes.createEvent(type, data, transferables);\n }\n\n /**\n * Dispatch an event to all view components\n */\n broadcastEvent(type: string, data: unknown = undefined) {\n for (const c of this.traverseLevelOrderBFS()) {\n c.dispatchEvent(type, data, false);\n }\n }\n\n /**\n * Dispatch an event (usually from the shadow-objects from the worker env) to a specific view component\n */\n dispatchMessage(uuid: string, type: string, data: unknown = undefined, traverseChildren = false) {\n this.#components.get(uuid)?.component.dispatchEvent(type, data, traverseChildren);\n }\n\n /**\n * Inform all root components that they should re-request their parents\n */\n dispatchReRequestParentRoots() {\n for (const uuid of this.#rootComponents) {\n this.dispatchMessage(uuid, ComponentContext.ReRequestParentRoots);\n }\n }\n\n /**\n * Create the component change trails at this point in time.\n * The next call will only return the differences from the previous call.\n *\n * @see {@link ComponentContext.reCreateChanges}\n */\n buildChangeTrails(clearChanges = true): ChangeTrailType {\n const trails: IComponentChangeType[] = [];\n\n if (!this.hasComponents()) return trails;\n\n const pathOfChanges = this.#buildPathOfChanges();\n\n // console.log(\n // 'path of changes:',\n // pathOfChanges.map((c) => c.uuid),\n // );\n\n for (const changes of pathOfChanges) {\n changes.buildChangeTrail(trails, ChangeTrailPhase.StructuralChanges);\n }\n\n for (const changes of pathOfChanges) {\n changes.buildChangeTrail(trails, ChangeTrailPhase.ContentUpdates);\n }\n\n for (const changes of pathOfChanges) {\n changes.buildChangeTrail(trails, ChangeTrailPhase.Removal);\n\n if (changes.isDestroyed || (changes.isNew && !changes.isCreated)) {\n this.#deleteComponent(changes.uuid);\n }\n\n if (clearChanges) changes.clear();\n }\n\n this.#componentMemory.write(trails);\n\n return trails;\n }\n\n /**\n * Resets the internal component change states so that all view components are regenerated with the next change trail.\n * The outstanding events are taken over.\n *\n * @see {@link ComponentContext.buildChangeTrails}\n */\n reCreateChanges() {\n if (this.#componentMemory.isEmpty()) return;\n\n this.buildChangeTrails(false);\n\n for (const [uuid, cMem] of this.#componentMemory) {\n const c = this.#components.get(uuid);\n if (c) {\n const changes = new ComponentChanges(uuid);\n changes.create(cMem.token, cMem.parentUuid, cMem.order, cMem.autoDestructionOnParentRemoval);\n\n if (cMem.properties) {\n for (const [key, value] of cMem.properties) {\n changes.changeProperty(key, value, c.propIsEqual?.get(key));\n }\n }\n\n c.changes.transferEventsTo(changes);\n c.changes.clear();\n\n c.changes = changes;\n }\n }\n\n this.#componentMemory.clear();\n\n this.broadcastEvent(ContextLost);\n }\n\n clear() {\n this.#viewInstances = undefined;\n this.#componentMemory.clear();\n\n this.#rootComponents.slice(0).forEach((uuid) => this.removeSubTree(uuid));\n\n if (this.#rootComponents.length !== 0) {\n throw new Error('component-context panic: #rootComponents is not empty!');\n }\n\n if (this.#components.size !== 0) {\n throw new Error('component-context panic: #components is not empty!');\n }\n }\n\n #deleteComponent(uuid: string) {\n // console.log('deleteComponent:', uuid, this.#components.has(uuid) ? 'x' : '');\n if (this.#components.has(uuid)) {\n this.#components.delete(uuid);\n removeFrom(this.#rootComponents, uuid);\n this.#viewInstances = undefined;\n }\n }\n\n #buildPathOfChanges(): ComponentChanges[] {\n return this.#traverseLevelOrderBFS()\n .filter((vi) => vi.changes.hasChanges())\n .map((vi) => vi.changes);\n }\n\n #appendToOrdered(component: ViewComponent, childUuids: string[]) {\n if (childUuids.length === 0) {\n childUuids.push(component.uuid);\n return;\n }\n\n if (childUuids.includes(component.uuid)) {\n return;\n }\n\n const len = childUuids.length;\n const childComponents = new Array<ViewComponent>(len);\n\n childComponents[0] = this.#components.get(childUuids[0])!.component;\n\n if (component.order < childComponents[0].order) {\n childUuids.unshift(component.uuid);\n return;\n }\n\n if (len === 1) {\n childUuids.push(component.uuid);\n return;\n }\n\n const lastIdx = len - 1;\n childComponents[lastIdx] = this.#components.get(childUuids[lastIdx])!.component;\n\n if (component.order >= childComponents[lastIdx].order) {\n childUuids.push(component.uuid);\n return;\n }\n\n if (len === 2) {\n childUuids.splice(1, 0, component.uuid);\n return;\n }\n\n for (let i = lastIdx - 1; i >= 1; i--) {\n childComponents[i] = this.#components.get(childUuids[i])!.component;\n if (component.order >= childComponents[i].order) {\n childUuids.splice(i + 1, 0, component.uuid);\n return;\n }\n }\n }\n\n #viewInstances?: ViewInstance[];\n\n #traverseLevelOrderBFS(): ViewInstance[] {\n if (this.#viewInstances) return this.#viewInstances;\n\n const lvl = new Map<number, ViewInstance[]>();\n\n const traverse = (uuid: string, depth: number) => {\n const viewInstance = this.#components.get(uuid);\n if (viewInstance == null) return;\n\n if (lvl.has(depth)) {\n lvl.get(depth).push(viewInstance);\n } else {\n lvl.set(depth, [viewInstance]);\n }\n\n for (const childUuid of viewInstance.children) {\n traverse(childUuid, depth + 1);\n }\n };\n\n this.#rootComponents.forEach((uuid) => traverse(uuid, 0));\n\n this.#viewInstances = Array.from(lvl.entries())\n .sort((a, b) => a[0] - b[0])\n .flatMap(([, vi]) => vi);\n\n return this.#viewInstances;\n }\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {ChangeTrailPhase, ContextLost, GlobalNS} from '../constants.js';\nimport type {ChangeTrailType, IComponentChangeType, NamespaceType} from '../types.js';\nimport {removeFrom} from '../utils/array-utils.js';\nimport {toNamespace} from '../utils/toNamespace.js';\nimport {ComponentChanges} from './ComponentChanges.js';\nimport {ComponentMemory} from './ComponentMemory.js';\nimport type {ViewComponent} from './ViewComponent.js';\n\ninterface ViewInstance {\n component: ViewComponent;\n children: string[]; // we use an Array here and not a Set, because we want to keep the insertion order\n changes: ComponentChanges;\n propIsEqual?: Map<string, (a: any, b: any) => boolean>;\n}\n\ndeclare global {\n // eslint-disable-next-line no-var\n var __shadowEntsContexts: Map<string | symbol, ComponentContext> | undefined;\n}\n\n/**\n * The {@link ComponentContext} represents the current real-time state of the _view components_.\n *\n * Changes to the components and their hierarchy are also logged to the {@link ComponentChanges}.\n *\n * Each time a change trail is created (a call to {@link ComponentContext#buildChangeTrails}),\n * the past changes are summarized and returned as the result. This means that the change trail\n * is always the path of changes from the time of the previous change trail (or from the beginning)\n * to the current call to the {@link ComponentContext#buildChangeTrails} method.\n *\n * In addition, there is the {@link ComponentMemory}. The memory represents the component state at\n * the time of the last change trail, as opposed to the {@link ComponentContext}, which represents\n * the current real-time state of the _view components_.\n *\n * A context is always associated with a namespace.\n * If no namespace is specified when creating a {@link ComponentContext}, the global namespace is used.\n * There is only one {@link ComponentContext} (a singleton) for each namespace.\n */\n/**\n * Thrown when a {@link ViewComponent} tries to join a {@link ComponentContext} that has\n * already been disposed.\n */\nexport class ComponentContextDisposedError extends Error {\n constructor(message = 'the component context has been disposed') {\n super(message);\n this.name = 'ComponentContextDisposedError';\n }\n}\n\nexport class ComponentContext {\n static readonly ReRequestParentRoots = 're-request-parent-roots';\n\n static getContextsMap(): Map<NamespaceType, ComponentContext> {\n if (globalThis.__shadowEntsContexts == null) {\n globalThis.__shadowEntsContexts = new Map<NamespaceType, ComponentContext>();\n }\n return globalThis.__shadowEntsContexts;\n }\n\n static get(namespace?: NamespaceType): ComponentContext {\n const ns = toNamespace(namespace);\n const ctxMap = ComponentContext.getContextsMap();\n if (ctxMap.has(ns)) {\n return ctxMap.get(ns)!;\n }\n return new ComponentContext(ns);\n }\n\n ns?: NamespaceType;\n\n #components: Map<string, ViewInstance> = new Map();\n #rootComponents: string[] = []; // we use an Array here and not a Set, because we want to keep the insertion order\n #isDisposed = false;\n\n readonly #componentMemory = new ComponentMemory();\n\n constructor(namespace: NamespaceType = GlobalNS) {\n const ns = toNamespace(namespace);\n const ctxMap = ComponentContext.getContextsMap();\n if (ctxMap.has(ns)) {\n return ctxMap.get(ns)!;\n }\n this.ns = ns;\n ctxMap.set(ns, this);\n }\n\n /**\n * Whether this context has been torn down by {@link ComponentContext.dispose}.\n *\n * A disposed context holds no components, produces empty change trails and no longer\n * occupies its namespace. It cannot be revived; use {@link ComponentContext.get} to\n * obtain a fresh context for the same namespace.\n */\n get isDisposed(): boolean {\n return this.#isDisposed;\n }\n\n addComponent(component: ViewComponent) {\n if (this.#isDisposed) {\n throw new ComponentContextDisposedError(\n `the view component ${component.uuid} cannot join the component context because it has been disposed`,\n );\n }\n\n let viewInstance = this.#components.get(component.uuid);\n\n if (viewInstance) {\n if (viewInstance.component !== component) {\n // another component claims this uuid: promote the children of the previous one to\n // root components, otherwise they would stay in the map but drop out of the tree\n for (const childUuid of viewInstance.children.slice(0)) {\n this.#components.get(childUuid)?.component.removeFromParent();\n }\n }\n\n viewInstance.component = component;\n viewInstance.children = [];\n } else {\n viewInstance = {\n component,\n children: [],\n changes: new ComponentChanges(component.uuid),\n propIsEqual: undefined,\n };\n this.#components.set(component.uuid, viewInstance);\n }\n\n viewInstance.changes.create(\n component.token,\n component.parent?.uuid,\n component.order,\n component.autoDestructionOnParentRemoval,\n );\n\n if (component.parent) {\n this.addToChildren(component.parent, component);\n viewInstance.changes.setParent(component.parent.uuid);\n } else {\n this.#appendToOrdered(component, this.#rootComponents);\n }\n\n this.#viewInstances = undefined;\n }\n\n hasComponent(component: ViewComponent) {\n return this.#components.has(component.uuid);\n }\n\n hasComponents() {\n return this.#components.size > 0;\n }\n\n isRootComponent(component: ViewComponent) {\n return this.#rootComponents.includes(component.uuid);\n }\n\n destroyComponent(component: ViewComponent) {\n if (this.hasComponent(component)) {\n const entry = this.#components.get(component.uuid)!;\n for (const childUuid of entry.children.slice(0)) {\n this.#components.get(childUuid)?.component.removeFromParent();\n }\n entry.changes.destroy();\n this.#viewInstances = undefined;\n }\n }\n\n getChildren(component: ViewComponent): ViewComponent[] {\n return this.#components.get(component.uuid)?.children.map((uuid) => this.#components.get(uuid)!.component) ?? [];\n }\n\n removeFromParent(childUuid: string, parent: ViewComponent) {\n if (this.hasComponent(parent)) {\n // the child may already be gone (destroyComponent, removeSubTree) while the component\n // still holds on to its parent \u2014 detaching it must not resurrect it as a root\n const childEntry = this.#components.get(childUuid);\n if (childEntry === undefined) return;\n\n const parentEntry = this.#components.get(parent.uuid)!;\n const childIdx = parentEntry.children.indexOf(childUuid);\n if (childIdx !== -1) {\n parentEntry.children.splice(childIdx, 1);\n childEntry.changes.setParent(undefined);\n }\n this.#appendToOrdered(childEntry.component, this.#rootComponents);\n this.#viewInstances = undefined;\n }\n }\n\n moveToRoot(childUuid: string) {\n const childEntry = this.#components.get(childUuid);\n if (childEntry) {\n childEntry.changes?.setParent(undefined);\n this.#appendToOrdered(childEntry.component, this.#rootComponents);\n }\n this.#viewInstances = undefined;\n }\n\n changeToken(component: ViewComponent, token?: string) {\n this.#components.get(component.uuid)?.changes.changeToken(token);\n }\n\n isChildOf(child: ViewComponent, parent: ViewComponent) {\n if (this.hasComponent(parent)) {\n const entry = this.#components.get(parent.uuid)!;\n return entry.children.includes(child.uuid);\n }\n return false;\n }\n\n addToChildren(parent: ViewComponent, child: ViewComponent) {\n const entry = this.#components.get(parent.uuid);\n if (entry) {\n this.#appendToOrdered(child, entry.children);\n this.#components.get(child.uuid)?.changes.setParent(parent.uuid);\n removeFrom(this.#rootComponents, child.uuid);\n this.#viewInstances = undefined;\n } else {\n throw new Error(`the view component ${parent.uuid} cannot have a child added to it because the component do not exist!`);\n }\n }\n\n /**\n * Destroy a component and all its descendants without writing anything to a change trail.\n *\n * @see {@link ComponentContext.clear}\n */\n removeSubTree(uuid: string) {\n this.#removeSubTree(uuid, new Set());\n }\n\n #removeSubTree(uuid: string, visited: Set<string>) {\n if (visited.has(uuid)) return;\n visited.add(uuid);\n\n const entry = this.#components.get(uuid);\n if (entry) {\n for (const childUuid of entry.children.slice(0)) {\n this.#removeSubTree(childUuid, visited);\n }\n this.destroyComponent(entry.component);\n this.#deleteComponent(uuid);\n }\n }\n\n /**\n * @returns `true` if the value differs from the last value written to a change trail\n */\n setProperty<T = unknown>(component: ViewComponent, propKey: string, value: T, isEqual?: (a: T, b: T) => boolean): boolean {\n const vi = this.#components.get(component.uuid);\n if (vi != null) {\n if (isEqual != null) {\n vi.propIsEqual ??= new Map();\n vi.propIsEqual.set(propKey, isEqual);\n } else if (vi.propIsEqual?.has(propKey)) {\n vi.propIsEqual.delete(propKey);\n }\n return vi.changes.changeProperty(propKey, value, isEqual);\n }\n return false;\n }\n\n removeProperty(component: ViewComponent, propKey: string) {\n this.#components.get(component.uuid)?.changes.removeProperty(propKey);\n }\n\n changeOrder(component: ViewComponent) {\n // a component this context does not (or no longer) hold must never be re-inserted into an\n // ordered list \u2014 clear() and dispose() both leave live components pointing back at us\n const entry = this.#components.get(component.uuid);\n if (entry === undefined) return;\n\n const parentEntry = component.parent ? this.#components.get(component.parent.uuid) : undefined;\n if (parentEntry !== undefined) {\n removeFrom(parentEntry.children, component.uuid);\n this.#appendToOrdered(component, parentEntry.children);\n } else if (component.parent == null) {\n removeFrom(this.#rootComponents, component.uuid);\n this.#appendToOrdered(component, this.#rootComponents);\n }\n\n entry.changes.changeOrder(component.order);\n this.#viewInstances = undefined;\n }\n\n /**\n * @returns all view-components in breadth-first order\n */\n traverseLevelOrderBFS(): ViewComponent[] {\n return this.#traverseLevelOrderBFS().map((vi) => vi.component);\n }\n\n /**\n * Dispatch an event to the shadow objects linked to the view component\n */\n dispatchShadowObjectsEvent(component: ViewComponent, type: string, data: unknown, transferables?: Transferable[]) {\n this.#components.get(component.uuid)?.changes.createEvent(type, data, transferables);\n }\n\n /**\n * Dispatch an event to all view components\n */\n broadcastEvent(type: string, data: unknown = undefined) {\n for (const c of this.traverseLevelOrderBFS()) {\n c.dispatchEvent(type, data, false);\n }\n }\n\n /**\n * Dispatch an event (usually from the shadow-objects from the worker env) to a specific view component\n */\n dispatchMessage(uuid: string, type: string, data: unknown = undefined, traverseChildren = false) {\n this.#components.get(uuid)?.component.dispatchEvent(type, data, traverseChildren);\n }\n\n /**\n * Inform all root components that they should re-request their parents\n */\n dispatchReRequestParentRoots() {\n for (const uuid of this.#rootComponents) {\n this.dispatchMessage(uuid, ComponentContext.ReRequestParentRoots);\n }\n }\n\n /**\n * Create the component change trails at this point in time.\n * The next call will only return the differences from the previous call.\n *\n * @see {@link ComponentContext.reCreateChanges}\n */\n buildChangeTrails(clearChanges = true): ChangeTrailType {\n const trails: IComponentChangeType[] = [];\n\n if (!this.hasComponents()) return trails;\n\n const pathOfChanges = this.#buildPathOfChanges();\n\n // console.log(\n // 'path of changes:',\n // pathOfChanges.map((c) => c.uuid),\n // );\n\n for (const changes of pathOfChanges) {\n changes.buildChangeTrail(trails, ChangeTrailPhase.StructuralChanges);\n }\n\n for (const changes of pathOfChanges) {\n changes.buildChangeTrail(trails, ChangeTrailPhase.ContentUpdates);\n }\n\n for (const changes of pathOfChanges) {\n changes.buildChangeTrail(trails, ChangeTrailPhase.Removal);\n\n if (changes.isDestroyed || (changes.isNew && !changes.isCreated)) {\n this.#deleteComponent(changes.uuid);\n }\n\n if (clearChanges) changes.clear();\n }\n\n this.#componentMemory.write(trails);\n\n return trails;\n }\n\n /**\n * Resets the internal component change states so that all view components are regenerated with the next change trail.\n * The outstanding events are taken over.\n *\n * @see {@link ComponentContext.buildChangeTrails}\n */\n reCreateChanges() {\n if (this.#componentMemory.isEmpty()) return;\n\n this.buildChangeTrails(false);\n\n for (const [uuid, cMem] of this.#componentMemory) {\n const c = this.#components.get(uuid);\n if (c) {\n const changes = new ComponentChanges(uuid);\n changes.create(cMem.token, cMem.parentUuid, cMem.order, cMem.autoDestructionOnParentRemoval);\n\n if (cMem.properties) {\n for (const [key, value] of cMem.properties) {\n changes.changeProperty(key, value, c.propIsEqual?.get(key));\n }\n }\n\n c.changes.transferEventsTo(changes);\n c.changes.clear();\n\n c.changes = changes;\n }\n }\n\n this.#componentMemory.clear();\n\n this.broadcastEvent(ContextLost);\n }\n\n /**\n * Remove all components without writing anything to a change trail. The context stays\n * registered under its namespace and can be used again afterwards.\n *\n * @see {@link ComponentContext.dispose} for the final teardown\n */\n clear() {\n this.#viewInstances = undefined;\n this.#componentMemory.clear();\n\n for (const uuid of this.#rootComponents.slice(0)) {\n this.removeSubTree(uuid);\n }\n\n if (this.#rootComponents.length !== 0) {\n throw new Error('component-context panic: #rootComponents is not empty!');\n }\n\n if (this.#components.size !== 0) {\n throw new Error('component-context panic: #components is not empty!');\n }\n }\n\n /**\n * Tear the context down for good: every {@link ViewComponent} it holds is destroyed, the\n * component memory is dropped, and the namespace is released so that\n * {@link ComponentContext.get} creates a fresh context for it.\n *\n * Unlike {@link ComponentContext.clear} this is final. The context holds no components,\n * produces empty change trails, and rejects any component that tries to join it. Calling\n * it more than once is a no-op.\n *\n * A {@link ShadowEnv} bound to this context keeps its reference; destroy the environment\n * first if you want the namespace released on both sides.\n */\n dispose() {\n if (this.#isDisposed) return;\n\n // destroy first, while the context is still live: a component whose context is gone\n // would otherwise keep reporting itself as alive\n for (const {component} of Array.from(this.#components.values())) {\n component.destroy();\n }\n\n this.clear();\n\n this.#isDisposed = true;\n\n const ctxMap = ComponentContext.getContextsMap();\n if (this.ns != null && ctxMap.get(this.ns) === this) {\n ctxMap.delete(this.ns);\n }\n }\n\n #deleteComponent(uuid: string) {\n const entry = this.#components.get(uuid);\n if (entry === undefined) return;\n\n // a uuid must never survive in a children list, otherwise every later lookup\n // on that list dereferences a component that no longer exists\n const parentUuid = entry.component.parent?.uuid;\n if (parentUuid !== undefined) {\n const parentEntry = this.#components.get(parentUuid);\n if (parentEntry !== undefined) {\n removeFrom(parentEntry.children, uuid);\n }\n }\n\n this.#components.delete(uuid);\n removeFrom(this.#rootComponents, uuid);\n this.#viewInstances = undefined;\n }\n\n #buildPathOfChanges(): ComponentChanges[] {\n return this.#traverseLevelOrderBFS()\n .filter((vi) => vi.changes.hasChanges())\n .map((vi) => vi.changes);\n }\n\n /**\n * Insert a component into an ordered list of uuids.\n *\n * The list is kept sorted by ascending {@link ViewComponent#order}. Components sharing\n * the same order value keep their insertion order, so the new component is placed after\n * all components with an equal order.\n *\n * Uuids without a matching view instance are skipped instead of dereferenced, so a\n * partially torn down list can never turn a reordering into an exception.\n */\n #appendToOrdered(component: ViewComponent, childUuids: string[]) {\n if (childUuids.includes(component.uuid)) {\n return;\n }\n\n const {order} = component;\n\n for (let i = 0; i < childUuids.length; i++) {\n const other = this.#components.get(childUuids[i])?.component;\n if (other !== undefined && order < other.order) {\n childUuids.splice(i, 0, component.uuid);\n return;\n }\n }\n\n childUuids.push(component.uuid);\n }\n\n #viewInstances?: ViewInstance[];\n\n #traverseLevelOrderBFS(): ViewInstance[] {\n if (this.#viewInstances) return this.#viewInstances;\n\n const lvl = new Map<number, ViewInstance[]>();\n\n const traverse = (uuid: string, depth: number) => {\n const viewInstance = this.#components.get(uuid);\n if (viewInstance == null) return;\n\n const atDepth = lvl.get(depth);\n if (atDepth) {\n atDepth.push(viewInstance);\n } else {\n lvl.set(depth, [viewInstance]);\n }\n\n for (const childUuid of viewInstance.children) {\n traverse(childUuid, depth + 1);\n }\n };\n\n for (const uuid of this.#rootComponents) {\n traverse(uuid, 0);\n }\n\n this.#viewInstances = Array.from(lvl.entries())\n .sort((a, b) => a[0] - b[0])\n .flatMap(([, vi]) => vi);\n\n return this.#viewInstances;\n }\n}"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -55,7 +55,9 @@ class ComponentMemory {
55
55
  setParent({ uuid, parentUuid, order }) {
56
56
  const c = this.getComponentState(uuid);
57
57
  c.parentUuid = parentUuid;
58
- c.order = order ?? 0;
58
+ if (order !== void 0) {
59
+ c.order = order;
60
+ }
59
61
  }
60
62
  destroyEntity({ uuid }) {
61
63
  this.#components.delete(uuid);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/view/ComponentMemory.ts"],
4
- "sourcesContent": ["import {ComponentChangeType, VoidToken} from '../constants.js';\nimport type {\n ComponentPropertiesType,\n IChangeToken,\n IComponentChange,\n ICreateEntitiesChange,\n IDestroyEntitiesChange,\n IPropertiesChange,\n ISetParentChange,\n IUpdateOrderChange,\n} from '../types.js';\nimport {applyPropsChanges} from '../utils/props-utils.js';\n\nexport interface ComponentState {\n token: string;\n parentUuid?: string;\n order?: number;\n properties?: ComponentPropertiesType;\n autoDestructionOnParentRemoval?: boolean;\n}\n\n/**\n * Stores the state of components and their hierarchy. The state is updated using a _change trail_.\n *\n * @internal\n * @see ComponentContext.buildChangeTrails\n */\nexport class ComponentMemory {\n #components: Map<string, ComponentState> = new Map();\n\n get [Symbol.iterator]() {\n return this.#components.entries.bind(this.#components);\n }\n\n clear() {\n this.#components.clear();\n }\n\n isEmpty() {\n return this.#components.size === 0;\n }\n\n hasComponentState(uuid: string) {\n return this.#components.has(uuid);\n }\n\n getComponentState(uuid: string) {\n return this.#components.get(uuid);\n }\n\n write(changes: IComponentChange[]) {\n for (const change of changes) {\n if (change.type === ComponentChangeType.CreateEntities) {\n this.createEntity(change as ICreateEntitiesChange);\n } else if (this.#components.has(change.uuid)) {\n switch (change.type) {\n case ComponentChangeType.DestroyEntities:\n this.destroyEntity(change as IDestroyEntitiesChange);\n break;\n\n case ComponentChangeType.SetParent:\n this.setParent(change as ISetParentChange);\n break;\n\n case ComponentChangeType.UpdateOrder:\n this.updateOrder(change as IUpdateOrderChange);\n break;\n\n case ComponentChangeType.ChangeToken:\n this.changeToken(change as IChangeToken);\n break;\n\n case ComponentChangeType.ChangeProperties:\n this.changeProperties(change as IPropertiesChange);\n break;\n }\n }\n }\n }\n\n private changeProperties({uuid, properties}: IPropertiesChange) {\n const c = this.getComponentState(uuid)!;\n c.properties = applyPropsChanges(c.properties, properties);\n }\n\n private changeToken({uuid, token}: IChangeToken) {\n this.getComponentState(uuid)!.token = token || VoidToken;\n }\n\n private updateOrder({uuid, order}: IUpdateOrderChange) {\n this.getComponentState(uuid)!.order = order ?? 0;\n }\n\n private setParent({uuid, parentUuid, order}: ISetParentChange) {\n const c = this.getComponentState(uuid)!;\n c.parentUuid = parentUuid;\n c.order = order ?? 0;\n }\n\n private destroyEntity({uuid}: IDestroyEntitiesChange) {\n this.#components.delete(uuid);\n }\n\n private createEntity({uuid, token, parentUuid, order, properties, autoDestructionOnParentRemoval}: ICreateEntitiesChange) {\n this.#components.set(uuid, {\n token: token || VoidToken,\n parentUuid,\n order: order ?? 0,\n properties: applyPropsChanges(undefined, properties),\n ...(autoDestructionOnParentRemoval ? {autoDestructionOnParentRemoval: true} : {}),\n });\n }\n}"],
5
- "mappings": "AAAA,SAAQ,qBAAqB,iBAAgB;AAW7C,SAAQ,yBAAwB;AAgBzB,MAAM,gBAAgB;AAAA,EAC3B,cAA2C,oBAAI,IAAI;AAAA,EAEnD,KAAK,OAAO,QAAQ,IAAI;AACtB,WAAO,KAAK,YAAY,QAAQ,KAAK,KAAK,WAAW;AAAA,EACvD;AAAA,EAEA,QAAQ;AACN,SAAK,YAAY,MAAM;AAAA,EACzB;AAAA,EAEA,UAAU;AACR,WAAO,KAAK,YAAY,SAAS;AAAA,EACnC;AAAA,EAEA,kBAAkB,MAAc;AAC9B,WAAO,KAAK,YAAY,IAAI,IAAI;AAAA,EAClC;AAAA,EAEA,kBAAkB,MAAc;AAC9B,WAAO,KAAK,YAAY,IAAI,IAAI;AAAA,EAClC;AAAA,EAEA,MAAM,SAA6B;AACjC,eAAW,UAAU,SAAS;AAC5B,UAAI,OAAO,SAAS,oBAAoB,gBAAgB;AACtD,aAAK,aAAa,MAA+B;AAAA,MACnD,WAAW,KAAK,YAAY,IAAI,OAAO,IAAI,GAAG;AAC5C,gBAAQ,OAAO,MAAM;AAAA,UACnB,KAAK,oBAAoB;AACvB,iBAAK,cAAc,MAAgC;AACnD;AAAA,UAEF,KAAK,oBAAoB;AACvB,iBAAK,UAAU,MAA0B;AACzC;AAAA,UAEF,KAAK,oBAAoB;AACvB,iBAAK,YAAY,MAA4B;AAC7C;AAAA,UAEF,KAAK,oBAAoB;AACvB,iBAAK,YAAY,MAAsB;AACvC;AAAA,UAEF,KAAK,oBAAoB;AACvB,iBAAK,iBAAiB,MAA2B;AACjD;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,iBAAiB,EAAC,MAAM,WAAU,GAAsB;AAC9D,UAAM,IAAI,KAAK,kBAAkB,IAAI;AACrC,MAAE,aAAa,kBAAkB,EAAE,YAAY,UAAU;AAAA,EAC3D;AAAA,EAEQ,YAAY,EAAC,MAAM,MAAK,GAAiB;AAC/C,SAAK,kBAAkB,IAAI,EAAG,QAAQ,SAAS;AAAA,EACjD;AAAA,EAEQ,YAAY,EAAC,MAAM,MAAK,GAAuB;AACrD,SAAK,kBAAkB,IAAI,EAAG,QAAQ,SAAS;AAAA,EACjD;AAAA,EAEQ,UAAU,EAAC,MAAM,YAAY,MAAK,GAAqB;AAC7D,UAAM,IAAI,KAAK,kBAAkB,IAAI;AACrC,MAAE,aAAa;AACf,MAAE,QAAQ,SAAS;AAAA,EACrB;AAAA,EAEQ,cAAc,EAAC,KAAI,GAA2B;AACpD,SAAK,YAAY,OAAO,IAAI;AAAA,EAC9B;AAAA,EAEQ,aAAa,EAAC,MAAM,OAAO,YAAY,OAAO,YAAY,+BAA8B,GAA0B;AACxH,SAAK,YAAY,IAAI,MAAM;AAAA,MACzB,OAAO,SAAS;AAAA,MAChB;AAAA,MACA,OAAO,SAAS;AAAA,MAChB,YAAY,kBAAkB,QAAW,UAAU;AAAA,MACnD,GAAI,iCAAiC,EAAC,gCAAgC,KAAI,IAAI,CAAC;AAAA,IACjF,CAAC;AAAA,EACH;AACF;",
4
+ "sourcesContent": ["import {ComponentChangeType, VoidToken} from '../constants.js';\nimport type {\n ComponentPropertiesType,\n IChangeToken,\n IComponentChange,\n ICreateEntitiesChange,\n IDestroyEntitiesChange,\n IPropertiesChange,\n ISetParentChange,\n IUpdateOrderChange,\n} from '../types.js';\nimport {applyPropsChanges} from '../utils/props-utils.js';\n\nexport interface ComponentState {\n token: string;\n parentUuid?: string;\n order?: number;\n properties?: ComponentPropertiesType;\n autoDestructionOnParentRemoval?: boolean;\n}\n\n/**\n * Stores the state of components and their hierarchy. The state is updated using a _change trail_.\n *\n * @internal\n * @see ComponentContext.buildChangeTrails\n */\nexport class ComponentMemory {\n #components: Map<string, ComponentState> = new Map();\n\n get [Symbol.iterator]() {\n return this.#components.entries.bind(this.#components);\n }\n\n clear() {\n this.#components.clear();\n }\n\n isEmpty() {\n return this.#components.size === 0;\n }\n\n hasComponentState(uuid: string) {\n return this.#components.has(uuid);\n }\n\n getComponentState(uuid: string) {\n return this.#components.get(uuid);\n }\n\n write(changes: IComponentChange[]) {\n for (const change of changes) {\n if (change.type === ComponentChangeType.CreateEntities) {\n this.createEntity(change as ICreateEntitiesChange);\n } else if (this.#components.has(change.uuid)) {\n switch (change.type) {\n case ComponentChangeType.DestroyEntities:\n this.destroyEntity(change as IDestroyEntitiesChange);\n break;\n\n case ComponentChangeType.SetParent:\n this.setParent(change as ISetParentChange);\n break;\n\n case ComponentChangeType.UpdateOrder:\n this.updateOrder(change as IUpdateOrderChange);\n break;\n\n case ComponentChangeType.ChangeToken:\n this.changeToken(change as IChangeToken);\n break;\n\n case ComponentChangeType.ChangeProperties:\n this.changeProperties(change as IPropertiesChange);\n break;\n }\n }\n }\n }\n\n private changeProperties({uuid, properties}: IPropertiesChange) {\n const c = this.getComponentState(uuid)!;\n c.properties = applyPropsChanges(c.properties, properties);\n }\n\n private changeToken({uuid, token}: IChangeToken) {\n this.getComponentState(uuid)!.token = token || VoidToken;\n }\n\n private updateOrder({uuid, order}: IUpdateOrderChange) {\n this.getComponentState(uuid)!.order = order ?? 0;\n }\n\n private setParent({uuid, parentUuid, order}: ISetParentChange) {\n const c = this.getComponentState(uuid)!;\n c.parentUuid = parentUuid;\n // a set-parent change only carries an order when it actually changed,\n // so an absent order must keep the current one instead of resetting it\n if (order !== undefined) {\n c.order = order;\n }\n }\n\n private destroyEntity({uuid}: IDestroyEntitiesChange) {\n this.#components.delete(uuid);\n }\n\n private createEntity({uuid, token, parentUuid, order, properties, autoDestructionOnParentRemoval}: ICreateEntitiesChange) {\n this.#components.set(uuid, {\n token: token || VoidToken,\n parentUuid,\n order: order ?? 0,\n properties: applyPropsChanges(undefined, properties),\n ...(autoDestructionOnParentRemoval ? {autoDestructionOnParentRemoval: true} : {}),\n });\n }\n}"],
5
+ "mappings": "AAAA,SAAQ,qBAAqB,iBAAgB;AAW7C,SAAQ,yBAAwB;AAgBzB,MAAM,gBAAgB;AAAA,EAC3B,cAA2C,oBAAI,IAAI;AAAA,EAEnD,KAAK,OAAO,QAAQ,IAAI;AACtB,WAAO,KAAK,YAAY,QAAQ,KAAK,KAAK,WAAW;AAAA,EACvD;AAAA,EAEA,QAAQ;AACN,SAAK,YAAY,MAAM;AAAA,EACzB;AAAA,EAEA,UAAU;AACR,WAAO,KAAK,YAAY,SAAS;AAAA,EACnC;AAAA,EAEA,kBAAkB,MAAc;AAC9B,WAAO,KAAK,YAAY,IAAI,IAAI;AAAA,EAClC;AAAA,EAEA,kBAAkB,MAAc;AAC9B,WAAO,KAAK,YAAY,IAAI,IAAI;AAAA,EAClC;AAAA,EAEA,MAAM,SAA6B;AACjC,eAAW,UAAU,SAAS;AAC5B,UAAI,OAAO,SAAS,oBAAoB,gBAAgB;AACtD,aAAK,aAAa,MAA+B;AAAA,MACnD,WAAW,KAAK,YAAY,IAAI,OAAO,IAAI,GAAG;AAC5C,gBAAQ,OAAO,MAAM;AAAA,UACnB,KAAK,oBAAoB;AACvB,iBAAK,cAAc,MAAgC;AACnD;AAAA,UAEF,KAAK,oBAAoB;AACvB,iBAAK,UAAU,MAA0B;AACzC;AAAA,UAEF,KAAK,oBAAoB;AACvB,iBAAK,YAAY,MAA4B;AAC7C;AAAA,UAEF,KAAK,oBAAoB;AACvB,iBAAK,YAAY,MAAsB;AACvC;AAAA,UAEF,KAAK,oBAAoB;AACvB,iBAAK,iBAAiB,MAA2B;AACjD;AAAA,QACJ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,iBAAiB,EAAC,MAAM,WAAU,GAAsB;AAC9D,UAAM,IAAI,KAAK,kBAAkB,IAAI;AACrC,MAAE,aAAa,kBAAkB,EAAE,YAAY,UAAU;AAAA,EAC3D;AAAA,EAEQ,YAAY,EAAC,MAAM,MAAK,GAAiB;AAC/C,SAAK,kBAAkB,IAAI,EAAG,QAAQ,SAAS;AAAA,EACjD;AAAA,EAEQ,YAAY,EAAC,MAAM,MAAK,GAAuB;AACrD,SAAK,kBAAkB,IAAI,EAAG,QAAQ,SAAS;AAAA,EACjD;AAAA,EAEQ,UAAU,EAAC,MAAM,YAAY,MAAK,GAAqB;AAC7D,UAAM,IAAI,KAAK,kBAAkB,IAAI;AACrC,MAAE,aAAa;AAGf,QAAI,UAAU,QAAW;AACvB,QAAE,QAAQ;AAAA,IACZ;AAAA,EACF;AAAA,EAEQ,cAAc,EAAC,KAAI,GAA2B;AACpD,SAAK,YAAY,OAAO,IAAI;AAAA,EAC9B;AAAA,EAEQ,aAAa,EAAC,MAAM,OAAO,YAAY,OAAO,YAAY,+BAA8B,GAA0B;AACxH,SAAK,YAAY,IAAI,MAAM;AAAA,MACzB,OAAO,SAAS;AAAA,MAChB;AAAA,MACA,OAAO,SAAS;AAAA,MAChB,YAAY,kBAAkB,QAAW,UAAU;AAAA,MACnD,GAAI,iCAAiC,EAAC,gCAAgC,KAAI,IAAI,CAAC;AAAA,IACjF,CAAC;AAAA,EACH;AACF;",
6
6
  "names": []
7
7
  }
@@ -6,5 +6,11 @@ export interface IShadowObjectEnvProxy {
6
6
  applyChangeTrail(data: ChangeTrailType, waitForConfirmation: boolean): Promise<void>;
7
7
  destroy(): void;
8
8
  onMessageToView?: (event: Omit<MessageToViewEvent, 'transferables'>) => any;
9
+ /**
10
+ * Called when the proxy has irrecoverably lost the environment it stands for.
11
+ * {@link ShadowEnv} installs it on every proxy it is given; an implementation
12
+ * that cannot fail simply never calls it.
13
+ */
14
+ onProxyFailed?: (reason: unknown) => any;
9
15
  }
10
16
  //# sourceMappingURL=IShadowObjectEnvProxy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IShadowObjectEnvProxy.d.ts","sourceRoot":"","sources":["../../../src/view/IShadowObjectEnvProxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,qBAAqB;IACpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,mBAAmB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErF,OAAO,IAAI,IAAI,CAAC;IAEhB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,eAAe,CAAC,KAAK,GAAG,CAAC;CAC7E"}
1
+ {"version":3,"file":"IShadowObjectEnvProxy.d.ts","sourceRoot":"","sources":["../../../src/view/IShadowObjectEnvProxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,qBAAqB;IACpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,mBAAmB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErF,OAAO,IAAI,IAAI,CAAC;IAEhB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,eAAe,CAAC,KAAK,GAAG,CAAC;IAE5E;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,GAAG,CAAC;CAC1C"}
@@ -1,5 +1,5 @@
1
1
  import { Kernel } from '../in-the-dark/Kernel.js';
2
- import type { Registry } from '../in-the-dark/Registry.js';
2
+ import { Registry } from '../in-the-dark/Registry.js';
3
3
  import type { ChangeTrailType, ShadowObjectsModule } from '../types.js';
4
4
  import type { IShadowObjectEnvProxy } from './IShadowObjectEnvProxy.js';
5
5
  export declare class LocalShadowObjectEnv implements IShadowObjectEnvProxy {
@@ -1 +1 @@
1
- {"version":3,"file":"LocalShadowObjectEnv.d.ts","sourceRoot":"","sources":["../../../src/view/LocalShadowObjectEnv.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,MAAM,EAA0B,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAC,eAAe,EAAE,mBAAmB,EAAY,MAAM,aAAa,CAAC;AAGjF,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,4BAA4B,CAAC;AAEtE,qBAAa,oBAAqB,YAAW,qBAAqB;;IAGhE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,IAAI,QAAQ,IAAI,QAAQ,CAEvB;IAED,QAAQ,CAAC,UAAU,QAAQ;IAE3B,sBAAsB,UAAS;gBAEnB,QAAQ,CAAC,EAAE,QAAQ;IAY/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,oBAAoB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAY/E,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9C,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,OAAO,IAAI,IAAI;CAKhB"}
1
+ {"version":3,"file":"LocalShadowObjectEnv.d.ts","sourceRoot":"","sources":["../../../src/view/LocalShadowObjectEnv.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,MAAM,EAA0B,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAC,QAAQ,EAAC,MAAM,4BAA4B,CAAC;AACpD,OAAO,KAAK,EAAC,eAAe,EAAE,mBAAmB,EAAY,MAAM,aAAa,CAAC;AAGjF,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,4BAA4B,CAAC;AAEtE,qBAAa,oBAAqB,YAAW,qBAAqB;;IAIhE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,IAAI,QAAQ,IAAI,QAAQ,CAEvB;IAED,QAAQ,CAAC,UAAU,QAAQ;IAE3B,sBAAsB,UAAS;gBAEnB,QAAQ,CAAC,EAAE,QAAQ;IAsB/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,oBAAoB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAY/E,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9C,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI9D,OAAO,IAAI,IAAI;CAOhB"}
@@ -2,6 +2,7 @@ import { on } from "@spearwolf/eventize";
2
2
  import { MessageToView, ShadowObjectsExport } from "../constants.js";
3
3
  import { importModule } from "../in-the-dark/importModule.js";
4
4
  import { Kernel } from "../in-the-dark/Kernel.js";
5
+ import { Registry } from "../in-the-dark/Registry.js";
5
6
  import { toUrlString } from "../utils/toUrlString.js";
6
7
  import { cloneChangeTrail } from "./cloneChangeTrail.js";
7
8
  class LocalShadowObjectEnv {
@@ -10,15 +11,17 @@ class LocalShadowObjectEnv {
10
11
  this.isLocalEnv = true;
11
12
  this.disableStructuredClone = false;
12
13
  this.kernel = new Kernel(registry);
14
+ this.#usesDefaultRegistry = this.kernel.registry === Registry.get();
13
15
  on(this.kernel, MessageToView, (message) => {
14
- if (this.onMessageToView != null) {
15
- const { type, uuid, traverseChildren } = message;
16
- const data = structuredClone(message.data, { transfer: message.transferables });
17
- this.onMessageToView({ type, uuid, data, traverseChildren });
18
- }
16
+ const onMessageToView = this.onMessageToView;
17
+ if (onMessageToView == null) return;
18
+ const { type, uuid, traverseChildren } = message;
19
+ const data = structuredClone(message.data, { transfer: message.transferables });
20
+ onMessageToView.call(this, { type, uuid, data, traverseChildren });
19
21
  });
20
22
  }
21
23
  #importedModules;
24
+ #usesDefaultRegistry;
22
25
  get registry() {
23
26
  return this.kernel.registry;
24
27
  }
@@ -50,7 +53,9 @@ class LocalShadowObjectEnv {
50
53
  }
51
54
  destroy() {
52
55
  this.kernel.destroy();
53
- this.registry.clear();
56
+ if (!this.#usesDefaultRegistry) {
57
+ this.registry.clear();
58
+ }
54
59
  this.#importedModules.clear();
55
60
  }
56
61
  }