@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.
- package/CHANGELOG.md +64 -0
- package/README.md +49 -13
- package/bundle.js +7 -7
- package/package.json +2 -2
- package/src/elements/ShaeEntElement.d.ts +4 -4
- package/src/elements/ShaeEntElement.d.ts.map +1 -1
- package/src/elements/ShaeEntElement.js +4 -5
- package/src/elements/ShaeEntElement.js.map +2 -2
- package/src/elements/ShaePropElement.d.ts +5 -5
- package/src/elements/ShaePropElement.d.ts.map +1 -1
- package/src/elements/ShaePropElement.js +2 -2
- package/src/elements/ShaePropElement.js.map +2 -2
- package/src/elements/ShaeWorkerElement.d.ts.map +1 -1
- package/src/elements/ShaeWorkerElement.js +31 -6
- package/src/elements/ShaeWorkerElement.js.map +2 -2
- package/src/in-the-dark/Kernel.d.ts +5 -0
- package/src/in-the-dark/Kernel.d.ts.map +1 -1
- package/src/in-the-dark/Kernel.js +49 -24
- package/src/in-the-dark/Kernel.js.map +2 -2
- package/src/in-the-dark/Registry.d.ts +1 -1
- package/src/in-the-dark/Registry.d.ts.map +1 -1
- package/src/in-the-dark/Registry.js +24 -20
- package/src/in-the-dark/Registry.js.map +2 -2
- package/src/in-the-dark/ShadowObject.d.ts +1 -1
- package/src/in-the-dark/ShadowObject.d.ts.map +1 -1
- package/src/in-the-dark/ShadowObject.js +2 -2
- package/src/in-the-dark/ShadowObject.js.map +2 -2
- package/src/in-the-dark/SignalsPath.d.ts.map +1 -1
- package/src/in-the-dark/SignalsPath.js.map +2 -2
- package/src/in-the-dark/importModule.js +3 -3
- package/src/in-the-dark/importModule.js.map +2 -2
- package/src/types.d.ts +4 -4
- package/src/types.d.ts.map +1 -1
- package/src/utils/ConsoleLogger.d.ts.map +1 -1
- package/src/utils/ConsoleLogger.js +3 -2
- package/src/utils/ConsoleLogger.js.map +2 -2
- package/src/utils/FrameLoop.d.ts +1 -1
- package/src/utils/FrameLoop.d.ts.map +1 -1
- package/src/utils/FrameLoop.js +0 -2
- package/src/utils/FrameLoop.js.map +2 -2
- package/src/utils/attr-utils.d.ts.map +1 -1
- package/src/utils/attr-utils.js +1 -1
- package/src/utils/attr-utils.js.map +2 -2
- package/src/utils/generateUUID.d.ts +1 -1
- package/src/utils/generateUUID.d.ts.map +1 -1
- package/src/utils/props-utils.d.ts +1 -1
- package/src/utils/props-utils.d.ts.map +1 -1
- package/src/utils/waitForMessageOfType.d.ts +5 -1
- package/src/utils/waitForMessageOfType.d.ts.map +1 -1
- package/src/utils/waitForMessageOfType.js +12 -2
- package/src/utils/waitForMessageOfType.js.map +2 -2
- package/src/view/ComponentChanges.d.ts +4 -1
- package/src/view/ComponentChanges.d.ts.map +1 -1
- package/src/view/ComponentChanges.js +20 -6
- package/src/view/ComponentChanges.js.map +2 -2
- package/src/view/ComponentContext.d.ts +43 -1
- package/src/view/ComponentContext.d.ts.map +1 -1
- package/src/view/ComponentContext.js +123 -47
- package/src/view/ComponentContext.js.map +2 -2
- package/src/view/ComponentMemory.js +3 -1
- package/src/view/ComponentMemory.js.map +2 -2
- package/src/view/IShadowObjectEnvProxy.d.ts +6 -0
- package/src/view/IShadowObjectEnvProxy.d.ts.map +1 -1
- package/src/view/LocalShadowObjectEnv.d.ts +1 -1
- package/src/view/LocalShadowObjectEnv.d.ts.map +1 -1
- package/src/view/LocalShadowObjectEnv.js +11 -6
- package/src/view/LocalShadowObjectEnv.js.map +2 -2
- package/src/view/RemoteWorkerEnv.d.ts +42 -0
- package/src/view/RemoteWorkerEnv.d.ts.map +1 -1
- package/src/view/RemoteWorkerEnv.js +130 -18
- package/src/view/RemoteWorkerEnv.js.map +2 -2
- package/src/view/ShadowEnv.d.ts +25 -1
- package/src/view/ShadowEnv.d.ts.map +1 -1
- package/src/view/ShadowEnv.js +103 -29
- package/src/view/ShadowEnv.js.map +2 -2
- package/src/view/ViewComponent.d.ts +22 -1
- package/src/view/ViewComponent.d.ts.map +1 -1
- package/src/view/ViewComponent.js +66 -22
- package/src/view/ViewComponent.js.map +2 -2
- package/src/worker/MessageRouter.d.ts.map +1 -1
- package/src/worker/MessageRouter.js +7 -5
- 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
|
-
|
|
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;
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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)
|
|
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)
|
|
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
|
-
|
|
154
|
-
|
|
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
|
-
|
|
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)
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
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
|
-
|
|
317
|
-
|
|
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
|
|
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": "AAAA,SAAQ,kBAAkB,aAAa,gBAAe;AAEtD,SAAQ,kBAAiB;AACzB,SAAQ,mBAAkB;AAC1B,SAAQ,wBAAuB;AAC/B,SAAQ,uBAAsB;
|
|
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
|
-
|
|
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
|
|
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;
|
|
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;
|
|
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
|
|
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,
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
|
56
|
+
if (!this.#usesDefaultRegistry) {
|
|
57
|
+
this.registry.clear();
|
|
58
|
+
}
|
|
54
59
|
this.#importedModules.clear();
|
|
55
60
|
}
|
|
56
61
|
}
|