@spearwolf/shadow-objects 0.30.2 → 0.31.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 (122) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/bundle.js +13 -13
  3. package/package.json +3 -3
  4. package/src/bundle.js +4 -4
  5. package/src/bundle.js.map +7 -1
  6. package/src/constants.js +53 -40
  7. package/src/constants.js.map +7 -1
  8. package/src/create-worker.bundle.js +6 -8
  9. package/src/create-worker.bundle.js.map +7 -1
  10. package/src/create-worker.js +5 -2
  11. package/src/create-worker.js.map +7 -1
  12. package/src/elements/ShaeElement.js +57 -54
  13. package/src/elements/ShaeElement.js.map +7 -1
  14. package/src/elements/ShaeEntElement.d.ts.map +1 -1
  15. package/src/elements/ShaeEntElement.js +320 -341
  16. package/src/elements/ShaeEntElement.js.map +7 -1
  17. package/src/elements/ShaePropElement.js +312 -320
  18. package/src/elements/ShaePropElement.js.map +7 -1
  19. package/src/elements/ShaeWorkerElement.js +234 -229
  20. package/src/elements/ShaeWorkerElement.js.map +7 -1
  21. package/src/elements/constants.js +37 -22
  22. package/src/elements/constants.js.map +7 -1
  23. package/src/elements/events.d.ts +1 -1
  24. package/src/elements/events.d.ts.map +1 -1
  25. package/src/elements/events.js +1 -2
  26. package/src/elements/events.js.map +7 -1
  27. package/src/elements.js +4 -4
  28. package/src/elements.js.map +7 -1
  29. package/src/in-the-dark/Entity.d.ts +1 -1
  30. package/src/in-the-dark/Entity.d.ts.map +1 -1
  31. package/src/in-the-dark/Entity.js +299 -293
  32. package/src/in-the-dark/Entity.js.map +7 -1
  33. package/src/in-the-dark/Kernel.d.ts.map +1 -1
  34. package/src/in-the-dark/Kernel.js +556 -533
  35. package/src/in-the-dark/Kernel.js.map +7 -1
  36. package/src/in-the-dark/Registry.d.ts.map +1 -1
  37. package/src/in-the-dark/Registry.js +101 -104
  38. package/src/in-the-dark/Registry.js.map +7 -1
  39. package/src/in-the-dark/ShadowObject.d.ts.map +1 -1
  40. package/src/in-the-dark/ShadowObject.js +21 -23
  41. package/src/in-the-dark/ShadowObject.js.map +7 -1
  42. package/src/in-the-dark/SignalsPath.d.ts.map +1 -1
  43. package/src/in-the-dark/SignalsPath.js +139 -123
  44. package/src/in-the-dark/SignalsPath.js.map +7 -1
  45. package/src/in-the-dark/events.js +11 -9
  46. package/src/in-the-dark/events.js.map +7 -1
  47. package/src/in-the-dark/importModule.js +31 -29
  48. package/src/in-the-dark/importModule.js.map +7 -1
  49. package/src/index.d.ts +2 -2
  50. package/src/index.d.ts.map +1 -1
  51. package/src/index.js +14 -14
  52. package/src/index.js.map +7 -1
  53. package/src/shadow-objects.js +6 -6
  54. package/src/shadow-objects.js.map +7 -1
  55. package/src/shadow-objects.worker.js +3 -3
  56. package/src/shadow-objects.worker.js.map +7 -1
  57. package/src/shae-ent.js +3 -3
  58. package/src/shae-ent.js.map +7 -1
  59. package/src/shae-prop.js +3 -3
  60. package/src/shae-prop.js.map +7 -1
  61. package/src/shae-worker.js +3 -3
  62. package/src/shae-worker.js.map +7 -1
  63. package/src/types.d.ts +3 -2
  64. package/src/types.d.ts.map +1 -1
  65. package/src/types.js +1 -2
  66. package/src/types.js.map +7 -1
  67. package/src/utils/ConsoleLogger.js +179 -185
  68. package/src/utils/ConsoleLogger.js.map +7 -1
  69. package/src/utils/FrameLoop.js +41 -40
  70. package/src/utils/FrameLoop.js.map +7 -1
  71. package/src/utils/array-utils.js +22 -24
  72. package/src/utils/array-utils.js.map +7 -1
  73. package/src/utils/attr-utils.js +15 -11
  74. package/src/utils/attr-utils.js.map +7 -1
  75. package/src/utils/constants.js +5 -2
  76. package/src/utils/constants.js.map +7 -1
  77. package/src/utils/generateUUID.d.ts.map +1 -1
  78. package/src/utils/generateUUID.js +269 -32
  79. package/src/utils/generateUUID.js.map +7 -1
  80. package/src/utils/props-utils.js +34 -43
  81. package/src/utils/props-utils.js.map +7 -1
  82. package/src/utils/toMaybe.js +5 -2
  83. package/src/utils/toMaybe.js.map +7 -1
  84. package/src/utils/toNamespace.js +6 -3
  85. package/src/utils/toNamespace.js.map +7 -1
  86. package/src/utils/toUrlString.js +9 -6
  87. package/src/utils/toUrlString.js.map +7 -1
  88. package/src/utils/waitForMessageOfType.js +30 -32
  89. package/src/utils/waitForMessageOfType.js.map +7 -1
  90. package/src/view/ComponentChanges.d.ts +1 -1
  91. package/src/view/ComponentChanges.d.ts.map +1 -1
  92. package/src/view/ComponentChanges.js +249 -251
  93. package/src/view/ComponentChanges.js.map +7 -1
  94. package/src/view/ComponentContext.d.ts.map +1 -1
  95. package/src/view/ComponentContext.js +303 -331
  96. package/src/view/ComponentContext.js.map +7 -1
  97. package/src/view/ComponentMemory.d.ts +1 -0
  98. package/src/view/ComponentMemory.d.ts.map +1 -1
  99. package/src/view/ComponentMemory.js +73 -76
  100. package/src/view/ComponentMemory.js.map +7 -1
  101. package/src/view/IShadowObjectEnvProxy.js +1 -2
  102. package/src/view/IShadowObjectEnvProxy.js.map +7 -1
  103. package/src/view/LocalShadowObjectEnv.d.ts.map +1 -1
  104. package/src/view/LocalShadowObjectEnv.js +57 -52
  105. package/src/view/LocalShadowObjectEnv.js.map +7 -1
  106. package/src/view/RemoteWorkerEnv.js +134 -123
  107. package/src/view/RemoteWorkerEnv.js.map +7 -1
  108. package/src/view/ShadowEnv.d.ts.map +1 -1
  109. package/src/view/ShadowEnv.js +232 -228
  110. package/src/view/ShadowEnv.js.map +7 -1
  111. package/src/view/ViewComponent.d.ts +9 -0
  112. package/src/view/ViewComponent.d.ts.map +1 -1
  113. package/src/view/ViewComponent.js +142 -130
  114. package/src/view/ViewComponent.js.map +7 -1
  115. package/src/view/cloneChangeTrail.js +13 -11
  116. package/src/view/cloneChangeTrail.js.map +7 -1
  117. package/src/worker/MessageRouter.d.ts.map +1 -1
  118. package/src/worker/MessageRouter.js +78 -67
  119. package/src/worker/MessageRouter.js.map +7 -1
  120. package/src/worker/WorkerRuntime.js +22 -21
  121. package/src/worker/WorkerRuntime.js.map +7 -1
  122. package/tsconfig.lib.tsbuildinfo +0 -1
@@ -1,361 +1,333 @@
1
- import { ChangeTrailPhase, ContextLost, GlobalNS } from '../constants.js';
2
- import { removeFrom } from '../utils/array-utils.js';
3
- import { toNamespace } from '../utils/toNamespace.js';
4
- import { ComponentChanges } from './ComponentChanges.js';
5
- import { ComponentMemory } from './ComponentMemory.js';
6
- /**
7
- * The {@link ComponentContext} represents the current real-time state of the _view components_.
8
- *
9
- * Changes to the components and their hierarchy are also logged to the {@link ComponentChanges}.
10
- *
11
- * Each time a change trail is created (a call to {@link ComponentContext#buildChangeTrails}),
12
- * the past changes are summarized and returned as the result. This means that the change trail
13
- * is always the path of changes from the time of the previous change trail (or from the beginning)
14
- * to the current call to the {@link ComponentContext#buildChangeTrails} method.
15
- *
16
- * In addition, there is the {@link ComponentMemory}. The memory represents the component state at
17
- * the time of the last change trail, as opposed to the {@link ComponentContext}, which represents
18
- * the current real-time state of the _view components_.
19
- *
20
- * A context is always associated with a namespace.
21
- * If no namespace is specified when creating a {@link ComponentContext}, the global namespace is used.
22
- * There is only one {@link ComponentContext} (a singleton) for each namespace.
23
- */
24
- export class ComponentContext {
25
- static { this.ReRequestParentRoots = 're-request-parent-roots'; }
26
- static getContextsMap() {
27
- if (globalThis.__shadowEntsContexts == null) {
28
- globalThis.__shadowEntsContexts = new Map();
29
- }
30
- return globalThis.__shadowEntsContexts;
1
+ import { ChangeTrailPhase, ContextLost, GlobalNS } from "../constants.js";
2
+ import { removeFrom } from "../utils/array-utils.js";
3
+ import { toNamespace } from "../utils/toNamespace.js";
4
+ import { ComponentChanges } from "./ComponentChanges.js";
5
+ import { ComponentMemory } from "./ComponentMemory.js";
6
+ class ComponentContext {
7
+ static {
8
+ this.ReRequestParentRoots = "re-request-parent-roots";
9
+ }
10
+ static getContextsMap() {
11
+ if (globalThis.__shadowEntsContexts == null) {
12
+ globalThis.__shadowEntsContexts = /* @__PURE__ */ new Map();
31
13
  }
32
- static get(namespace) {
33
- const ns = toNamespace(namespace);
34
- const ctxMap = ComponentContext.getContextsMap();
35
- if (ctxMap.has(ns)) {
36
- return ctxMap.get(ns);
37
- }
38
- return new ComponentContext(ns);
14
+ return globalThis.__shadowEntsContexts;
15
+ }
16
+ static get(namespace) {
17
+ const ns = toNamespace(namespace);
18
+ const ctxMap = ComponentContext.getContextsMap();
19
+ if (ctxMap.has(ns)) {
20
+ return ctxMap.get(ns);
39
21
  }
40
- #components = new Map();
41
- #rootComponents = []; // we use an Array here and not a Set, because we want to keep the insertion order
42
- #componentMemory = new ComponentMemory();
43
- constructor(namespace = GlobalNS) {
44
- const ns = toNamespace(namespace);
45
- const ctxMap = ComponentContext.getContextsMap();
46
- if (ctxMap.has(ns)) {
47
- return ctxMap.get(ns);
48
- }
49
- this.ns = ns;
50
- ctxMap.set(ns, this);
22
+ return new ComponentContext(ns);
23
+ }
24
+ #components = /* @__PURE__ */ new Map();
25
+ #rootComponents = [];
26
+ // we use an Array here and not a Set, because we want to keep the insertion order
27
+ #componentMemory = new ComponentMemory();
28
+ constructor(namespace = GlobalNS) {
29
+ const ns = toNamespace(namespace);
30
+ const ctxMap = ComponentContext.getContextsMap();
31
+ if (ctxMap.has(ns)) {
32
+ return ctxMap.get(ns);
51
33
  }
52
- addComponent(component) {
53
- let viewInstance;
54
- if (this.#components.has(component.uuid)) {
55
- viewInstance = this.#components.get(component.uuid);
56
- viewInstance.component = component;
57
- viewInstance.children = [];
58
- }
59
- else {
60
- viewInstance = {
61
- component,
62
- children: [],
63
- changes: new ComponentChanges(component.uuid),
64
- propIsEqual: undefined,
65
- };
66
- this.#components.set(component.uuid, viewInstance);
67
- }
68
- viewInstance.changes.create(component.token, component.parent?.uuid, component.order);
69
- if (component.parent) {
70
- this.addToChildren(component.parent, component);
71
- viewInstance.changes.setParent(component.parent.uuid);
72
- }
73
- else {
74
- this.#appendToOrdered(component, this.#rootComponents);
75
- }
76
- this.#viewInstances = undefined;
34
+ this.ns = ns;
35
+ ctxMap.set(ns, this);
36
+ }
37
+ addComponent(component) {
38
+ let viewInstance;
39
+ if (this.#components.has(component.uuid)) {
40
+ viewInstance = this.#components.get(component.uuid);
41
+ viewInstance.component = component;
42
+ viewInstance.children = [];
43
+ } else {
44
+ viewInstance = {
45
+ component,
46
+ children: [],
47
+ changes: new ComponentChanges(component.uuid),
48
+ propIsEqual: void 0
49
+ };
50
+ this.#components.set(component.uuid, viewInstance);
77
51
  }
78
- hasComponent(component) {
79
- return this.#components.has(component.uuid);
52
+ viewInstance.changes.create(
53
+ component.token,
54
+ component.parent?.uuid,
55
+ component.order,
56
+ component.autoDestructionOnParentRemoval
57
+ );
58
+ if (component.parent) {
59
+ this.addToChildren(component.parent, component);
60
+ viewInstance.changes.setParent(component.parent.uuid);
61
+ } else {
62
+ this.#appendToOrdered(component, this.#rootComponents);
80
63
  }
81
- hasComponents() {
82
- return this.#components.size > 0;
64
+ this.#viewInstances = void 0;
65
+ }
66
+ hasComponent(component) {
67
+ return this.#components.has(component.uuid);
68
+ }
69
+ hasComponents() {
70
+ return this.#components.size > 0;
71
+ }
72
+ isRootComponent(component) {
73
+ return this.#rootComponents.includes(component.uuid);
74
+ }
75
+ destroyComponent(component) {
76
+ if (this.hasComponent(component)) {
77
+ const entry = this.#components.get(component.uuid);
78
+ entry.children.slice(0).forEach((childUuid) => this.#components.get(childUuid)?.component.removeFromParent());
79
+ entry.changes.destroy();
80
+ this.#viewInstances = void 0;
83
81
  }
84
- isRootComponent(component) {
85
- return this.#rootComponents.includes(component.uuid);
82
+ }
83
+ getChildren(component) {
84
+ return this.#components.get(component.uuid)?.children.map((uuid) => this.#components.get(uuid).component) ?? [];
85
+ }
86
+ removeFromParent(childUuid, parent) {
87
+ if (this.hasComponent(parent)) {
88
+ const childEntry = this.#components.get(childUuid);
89
+ const parentEntry = this.#components.get(parent.uuid);
90
+ const childIdx = parentEntry.children.indexOf(childUuid);
91
+ if (childIdx !== -1) {
92
+ parentEntry.children.splice(childIdx, 1);
93
+ childEntry.changes.setParent(void 0);
94
+ }
95
+ this.#appendToOrdered(childEntry.component, this.#rootComponents);
96
+ this.#viewInstances = void 0;
86
97
  }
87
- destroyComponent(component) {
88
- if (this.hasComponent(component)) {
89
- const entry = this.#components.get(component.uuid);
90
- entry.children.slice(0).forEach((childUuid) => this.#components.get(childUuid)?.component.removeFromParent());
91
- entry.changes.destroy();
92
- this.#viewInstances = undefined;
93
- }
98
+ }
99
+ moveToRoot(childUuid) {
100
+ const childEntry = this.#components.get(childUuid);
101
+ if (childEntry) {
102
+ childEntry.changes?.setParent(void 0);
103
+ this.#appendToOrdered(childEntry.component, this.#rootComponents);
94
104
  }
95
- getChildren(component) {
96
- return this.#components.get(component.uuid)?.children.map((uuid) => this.#components.get(uuid).component) ?? [];
105
+ this.#viewInstances = void 0;
106
+ }
107
+ changeToken(component, token) {
108
+ this.#components.get(component.uuid)?.changes.changeToken(token);
109
+ }
110
+ isChildOf(child, parent) {
111
+ if (this.hasComponent(parent)) {
112
+ const entry = this.#components.get(parent.uuid);
113
+ return entry.children.includes(child.uuid);
97
114
  }
98
- removeFromParent(childUuid, parent) {
99
- if (this.hasComponent(parent)) {
100
- const childEntry = this.#components.get(childUuid);
101
- const parentEntry = this.#components.get(parent.uuid);
102
- const childIdx = parentEntry.children.indexOf(childUuid);
103
- if (childIdx !== -1) {
104
- parentEntry.children.splice(childIdx, 1);
105
- childEntry.changes.setParent(undefined);
106
- }
107
- this.#appendToOrdered(childEntry.component, this.#rootComponents);
108
- this.#viewInstances = undefined;
109
- }
115
+ return false;
116
+ }
117
+ addToChildren(parent, child) {
118
+ const entry = this.#components.get(parent.uuid);
119
+ if (entry) {
120
+ this.#appendToOrdered(child, entry.children);
121
+ this.#components.get(child.uuid)?.changes.setParent(parent.uuid);
122
+ removeFrom(this.#rootComponents, child.uuid);
123
+ this.#viewInstances = void 0;
124
+ } else {
125
+ throw new Error(`the view component ${parent.uuid} cannot have a child added to it because the component do not exist!`);
110
126
  }
111
- moveToRoot(childUuid) {
112
- const childEntry = this.#components.get(childUuid);
113
- if (childEntry) {
114
- childEntry.changes?.setParent(undefined);
115
- this.#appendToOrdered(childEntry.component, this.#rootComponents);
116
- }
117
- this.#viewInstances = undefined;
118
- }
119
- changeToken(component, token) {
120
- this.#components.get(component.uuid)?.changes.changeToken(token);
127
+ }
128
+ removeSubTree(uuid) {
129
+ const entry = this.#components.get(uuid);
130
+ if (entry) {
131
+ entry.children.slice(0).forEach((childUuid) => this.removeSubTree(childUuid));
132
+ this.destroyComponent(entry.component);
133
+ this.#deleteComponent(uuid);
121
134
  }
122
- isChildOf(child, parent) {
123
- if (this.hasComponent(parent)) {
124
- const entry = this.#components.get(parent.uuid);
125
- return entry.children.includes(child.uuid);
126
- }
127
- return false;
135
+ }
136
+ setProperty(component, propKey, value, isEqual) {
137
+ const vi = this.#components.get(component.uuid);
138
+ if (vi != null) {
139
+ if (isEqual != null) {
140
+ vi.propIsEqual ??= /* @__PURE__ */ new Map();
141
+ vi.propIsEqual.set(propKey, isEqual);
142
+ } else if (vi.propIsEqual?.has(propKey)) {
143
+ vi.propIsEqual.delete(propKey);
144
+ }
145
+ return vi.changes.changeProperty(propKey, value, isEqual);
128
146
  }
129
- addToChildren(parent, child) {
130
- const entry = this.#components.get(parent.uuid);
131
- if (entry) {
132
- this.#appendToOrdered(child, entry.children);
133
- this.#components.get(child.uuid)?.changes.setParent(parent.uuid);
134
- removeFrom(this.#rootComponents, child.uuid);
135
- this.#viewInstances = undefined;
136
- }
137
- else {
138
- throw new Error(`the view component ${parent.uuid} cannot have a child added to it because the component do not exist!`);
139
- }
147
+ return false;
148
+ }
149
+ removeProperty(component, propKey) {
150
+ this.#components.get(component.uuid)?.changes.removeProperty(propKey);
151
+ }
152
+ changeOrder(component) {
153
+ if (component.parent) {
154
+ const parentEntry = this.#components.get(component.parent.uuid);
155
+ removeFrom(parentEntry.children, component.uuid);
156
+ this.#appendToOrdered(component, parentEntry.children);
157
+ } else {
158
+ removeFrom(this.#rootComponents, component.uuid);
159
+ this.#appendToOrdered(component, this.#rootComponents);
140
160
  }
141
- removeSubTree(uuid) {
142
- const entry = this.#components.get(uuid);
143
- if (entry) {
144
- entry.children.slice(0).forEach((childUuid) => this.removeSubTree(childUuid));
145
- this.destroyComponent(entry.component);
146
- this.#deleteComponent(uuid);
147
- }
161
+ this.#components.get(component.uuid)?.changes.changeOrder(component.order);
162
+ this.#viewInstances = void 0;
163
+ }
164
+ /**
165
+ * @returns all view-components in breadth-first order
166
+ */
167
+ traverseLevelOrderBFS() {
168
+ return this.#traverseLevelOrderBFS().map((vi) => vi.component);
169
+ }
170
+ /**
171
+ * Dispatch an event to the shadow objects linked to the view component
172
+ */
173
+ dispatchShadowObjectsEvent(component, type, data, transferables) {
174
+ this.#components.get(component.uuid)?.changes.createEvent(type, data, transferables);
175
+ }
176
+ /**
177
+ * Dispatch an event to all view components
178
+ */
179
+ broadcastEvent(type, data = void 0) {
180
+ for (const c of this.traverseLevelOrderBFS()) {
181
+ c.dispatchEvent(type, data, false);
148
182
  }
149
- setProperty(component, propKey, value, isEqual) {
150
- const vi = this.#components.get(component.uuid);
151
- if (vi != null) {
152
- if (isEqual != null) {
153
- vi.propIsEqual ??= new Map();
154
- vi.propIsEqual.set(propKey, isEqual);
155
- }
156
- else if (vi.propIsEqual?.has(propKey)) {
157
- vi.propIsEqual.delete(propKey);
158
- }
159
- return vi.changes.changeProperty(propKey, value, isEqual);
160
- }
161
- return false;
183
+ }
184
+ /**
185
+ * Dispatch an event (usually from the shadow-objects from the worker env) to a specific view component
186
+ */
187
+ dispatchMessage(uuid, type, data = void 0, traverseChildren = false) {
188
+ this.#components.get(uuid)?.component.dispatchEvent(type, data, traverseChildren);
189
+ }
190
+ /**
191
+ * Inform all root components that they should re-request their parents
192
+ */
193
+ dispatchReRequestParentRoots() {
194
+ for (const uuid of this.#rootComponents) {
195
+ this.dispatchMessage(uuid, ComponentContext.ReRequestParentRoots);
162
196
  }
163
- removeProperty(component, propKey) {
164
- this.#components.get(component.uuid)?.changes.removeProperty(propKey);
197
+ }
198
+ /**
199
+ * Create the component change trails at this point in time.
200
+ * The next call will only return the differences from the previous call.
201
+ *
202
+ * @see {@link ComponentContext.reCreateChanges}
203
+ */
204
+ buildChangeTrails(clearChanges = true) {
205
+ const trails = [];
206
+ if (!this.hasComponents()) return trails;
207
+ const pathOfChanges = this.#buildPathOfChanges();
208
+ for (const changes of pathOfChanges) {
209
+ changes.buildChangeTrail(trails, ChangeTrailPhase.StructuralChanges);
165
210
  }
166
- changeOrder(component) {
167
- if (component.parent) {
168
- const parentEntry = this.#components.get(component.parent.uuid);
169
- removeFrom(parentEntry.children, component.uuid);
170
- this.#appendToOrdered(component, parentEntry.children);
171
- }
172
- else {
173
- removeFrom(this.#rootComponents, component.uuid);
174
- this.#appendToOrdered(component, this.#rootComponents);
175
- }
176
- this.#components.get(component.uuid)?.changes.changeOrder(component.order);
177
- this.#viewInstances = undefined;
211
+ for (const changes of pathOfChanges) {
212
+ changes.buildChangeTrail(trails, ChangeTrailPhase.ContentUpdates);
178
213
  }
179
- /**
180
- * @returns all view-components in breadth-first order
181
- */
182
- traverseLevelOrderBFS() {
183
- return this.#traverseLevelOrderBFS().map((vi) => vi.component);
214
+ for (const changes of pathOfChanges) {
215
+ changes.buildChangeTrail(trails, ChangeTrailPhase.Removal);
216
+ if (changes.isDestroyed || changes.isNew && !changes.isCreated) {
217
+ this.#deleteComponent(changes.uuid);
218
+ }
219
+ if (clearChanges) changes.clear();
184
220
  }
185
- /**
186
- * Dispatch an event to the shadow objects linked to the view component
187
- */
188
- dispatchShadowObjectsEvent(component, type, data, transferables) {
189
- this.#components.get(component.uuid)?.changes.createEvent(type, data, transferables);
221
+ this.#componentMemory.write(trails);
222
+ return trails;
223
+ }
224
+ /**
225
+ * Resets the internal component change states so that all view components are regenerated with the next change trail.
226
+ * The outstanding events are taken over.
227
+ *
228
+ * @see {@link ComponentContext.buildChangeTrails}
229
+ */
230
+ reCreateChanges() {
231
+ if (this.#componentMemory.isEmpty()) return;
232
+ this.buildChangeTrails(false);
233
+ for (const [uuid, cMem] of this.#componentMemory) {
234
+ const c = this.#components.get(uuid);
235
+ if (c) {
236
+ const changes = new ComponentChanges(uuid);
237
+ changes.create(cMem.token, cMem.parentUuid, cMem.order, cMem.autoDestructionOnParentRemoval);
238
+ if (cMem.properties) {
239
+ for (const [key, value] of cMem.properties) {
240
+ changes.changeProperty(key, value, c.propIsEqual?.get(key));
241
+ }
242
+ }
243
+ c.changes.transferEventsTo(changes);
244
+ c.changes.clear();
245
+ c.changes = changes;
246
+ }
190
247
  }
191
- /**
192
- * Dispatch an event to all view components
193
- */
194
- broadcastEvent(type, data = undefined) {
195
- for (const c of this.traverseLevelOrderBFS()) {
196
- c.dispatchEvent(type, data, false);
197
- }
248
+ this.#componentMemory.clear();
249
+ this.broadcastEvent(ContextLost);
250
+ }
251
+ clear() {
252
+ this.#viewInstances = void 0;
253
+ this.#componentMemory.clear();
254
+ this.#rootComponents.slice(0).forEach((uuid) => this.removeSubTree(uuid));
255
+ if (this.#rootComponents.length !== 0) {
256
+ throw new Error("component-context panic: #rootComponents is not empty!");
198
257
  }
199
- /**
200
- * Dispatch an event (usually from the shadow-objects from the worker env) to a specific view component
201
- */
202
- dispatchMessage(uuid, type, data = undefined, traverseChildren = false) {
203
- this.#components.get(uuid)?.component.dispatchEvent(type, data, traverseChildren);
258
+ if (this.#components.size !== 0) {
259
+ throw new Error("component-context panic: #components is not empty!");
204
260
  }
205
- /**
206
- * Inform all root components that they should re-request their parents
207
- */
208
- dispatchReRequestParentRoots() {
209
- for (const uuid of this.#rootComponents) {
210
- this.dispatchMessage(uuid, ComponentContext.ReRequestParentRoots);
211
- }
261
+ }
262
+ #deleteComponent(uuid) {
263
+ if (this.#components.has(uuid)) {
264
+ this.#components.delete(uuid);
265
+ removeFrom(this.#rootComponents, uuid);
266
+ this.#viewInstances = void 0;
212
267
  }
213
- /**
214
- * Create the component change trails at this point in time.
215
- * The next call will only return the differences from the previous call.
216
- *
217
- * @see {@link ComponentContext.reCreateChanges}
218
- */
219
- buildChangeTrails(clearChanges = true) {
220
- const trails = [];
221
- if (!this.hasComponents())
222
- return trails;
223
- const pathOfChanges = this.#buildPathOfChanges();
224
- // console.log(
225
- // 'path of changes:',
226
- // pathOfChanges.map((c) => c.uuid),
227
- // );
228
- for (const changes of pathOfChanges) {
229
- changes.buildChangeTrail(trails, ChangeTrailPhase.StructuralChanges);
230
- }
231
- for (const changes of pathOfChanges) {
232
- changes.buildChangeTrail(trails, ChangeTrailPhase.ContentUpdates);
233
- }
234
- for (const changes of pathOfChanges) {
235
- changes.buildChangeTrail(trails, ChangeTrailPhase.Removal);
236
- if (changes.isDestroyed || (changes.isNew && !changes.isCreated)) {
237
- this.#deleteComponent(changes.uuid);
238
- }
239
- if (clearChanges)
240
- changes.clear();
241
- }
242
- this.#componentMemory.write(trails);
243
- return trails;
268
+ }
269
+ #buildPathOfChanges() {
270
+ return this.#traverseLevelOrderBFS().filter((vi) => vi.changes.hasChanges()).map((vi) => vi.changes);
271
+ }
272
+ #appendToOrdered(component, childUuids) {
273
+ if (childUuids.length === 0) {
274
+ childUuids.push(component.uuid);
275
+ return;
244
276
  }
245
- /**
246
- * Resets the internal component change states so that all view components are regenerated with the next change trail.
247
- * The outstanding events are taken over.
248
- *
249
- * @see {@link ComponentContext.buildChangeTrails}
250
- */
251
- reCreateChanges() {
252
- if (this.#componentMemory.isEmpty())
253
- return;
254
- this.buildChangeTrails(false);
255
- for (const [uuid, cMem] of this.#componentMemory) {
256
- const c = this.#components.get(uuid);
257
- if (c) {
258
- const changes = new ComponentChanges(uuid);
259
- changes.create(cMem.token, cMem.parentUuid, cMem.order);
260
- if (cMem.properties) {
261
- for (const [key, value] of cMem.properties) {
262
- changes.changeProperty(key, value, c.propIsEqual?.get(key));
263
- }
264
- }
265
- c.changes.transferEventsTo(changes);
266
- c.changes.clear();
267
- c.changes = changes;
268
- }
269
- }
270
- this.#componentMemory.clear();
271
- this.broadcastEvent(ContextLost);
277
+ if (childUuids.includes(component.uuid)) {
278
+ return;
272
279
  }
273
- clear() {
274
- this.#viewInstances = undefined;
275
- this.#componentMemory.clear();
276
- this.#rootComponents.slice(0).forEach((uuid) => this.removeSubTree(uuid));
277
- if (this.#rootComponents.length !== 0) {
278
- throw new Error('component-context panic: #rootComponents is not empty!');
279
- }
280
- if (this.#components.size !== 0) {
281
- throw new Error('component-context panic: #components is not empty!');
282
- }
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;
283
286
  }
284
- #deleteComponent(uuid) {
285
- // console.log('deleteComponent:', uuid, this.#components.has(uuid) ? 'x' : '');
286
- if (this.#components.has(uuid)) {
287
- this.#components.delete(uuid);
288
- removeFrom(this.#rootComponents, uuid);
289
- this.#viewInstances = undefined;
290
- }
287
+ if (len === 1) {
288
+ childUuids.push(component.uuid);
289
+ return;
291
290
  }
292
- #buildPathOfChanges() {
293
- return this.#traverseLevelOrderBFS()
294
- .filter((vi) => vi.changes.hasChanges())
295
- .map((vi) => vi.changes);
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
296
  }
297
- #appendToOrdered(component, childUuids) {
298
- if (childUuids.length === 0) {
299
- childUuids.push(component.uuid);
300
- return;
301
- }
302
- if (childUuids.includes(component.uuid)) {
303
- return;
304
- }
305
- const len = childUuids.length;
306
- const childComponents = new Array(len);
307
- childComponents[0] = this.#components.get(childUuids[0]).component;
308
- if (component.order < childComponents[0].order) {
309
- childUuids.unshift(component.uuid);
310
- return;
311
- }
312
- if (len === 1) {
313
- childUuids.push(component.uuid);
314
- return;
315
- }
316
- const lastIdx = len - 1;
317
- childComponents[lastIdx] = this.#components.get(childUuids[lastIdx]).component;
318
- if (component.order >= childComponents[lastIdx].order) {
319
- childUuids.push(component.uuid);
320
- return;
321
- }
322
- if (len === 2) {
323
- childUuids.splice(1, 0, component.uuid);
324
- return;
325
- }
326
- for (let i = lastIdx - 1; i >= 1; i--) {
327
- childComponents[i] = this.#components.get(childUuids[i]).component;
328
- if (component.order >= childComponents[i].order) {
329
- childUuids.splice(i + 1, 0, component.uuid);
330
- return;
331
- }
332
- }
297
+ if (len === 2) {
298
+ childUuids.splice(1, 0, component.uuid);
299
+ return;
333
300
  }
334
- #viewInstances;
335
- #traverseLevelOrderBFS() {
336
- if (this.#viewInstances)
337
- return this.#viewInstances;
338
- const lvl = new Map();
339
- const traverse = (uuid, depth) => {
340
- const viewInstance = this.#components.get(uuid);
341
- if (viewInstance == null)
342
- return;
343
- if (lvl.has(depth)) {
344
- lvl.get(depth).push(viewInstance);
345
- }
346
- else {
347
- lvl.set(depth, [viewInstance]);
348
- }
349
- for (const childUuid of viewInstance.children) {
350
- traverse(childUuid, depth + 1);
351
- }
352
- };
353
- this.#rootComponents.forEach((uuid) => traverse(uuid, 0));
354
- this.#viewInstances = Array.from(lvl.entries())
355
- .sort((a, b) => a[0] - b[0])
356
- .map(([, vi]) => vi)
357
- .flat();
358
- return this.#viewInstances;
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);
305
+ return;
306
+ }
359
307
  }
308
+ }
309
+ #viewInstances;
310
+ #traverseLevelOrderBFS() {
311
+ if (this.#viewInstances) return this.#viewInstances;
312
+ const lvl = /* @__PURE__ */ new Map();
313
+ const traverse = (uuid, depth) => {
314
+ const viewInstance = this.#components.get(uuid);
315
+ if (viewInstance == null) return;
316
+ if (lvl.has(depth)) {
317
+ lvl.get(depth).push(viewInstance);
318
+ } else {
319
+ lvl.set(depth, [viewInstance]);
320
+ }
321
+ for (const childUuid of viewInstance.children) {
322
+ traverse(childUuid, depth + 1);
323
+ }
324
+ };
325
+ this.#rootComponents.forEach((uuid) => traverse(uuid, 0));
326
+ this.#viewInstances = Array.from(lvl.entries()).sort((a, b) => a[0] - b[0]).flatMap(([, vi]) => vi);
327
+ return this.#viewInstances;
328
+ }
360
329
  }
361
- //# sourceMappingURL=ComponentContext.js.map
330
+ export {
331
+ ComponentContext
332
+ };
333
+ //# sourceMappingURL=ComponentContext.js.map