@spearwolf/shadow-objects 0.33.0 → 0.34.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 +320 -61
- package/README.md +57 -13
- package/bundle.js +5 -54
- package/package.json +7 -3
- package/src/ChangeTrailRefusedError.d.ts +27 -0
- package/src/ChangeTrailRefusedError.d.ts.map +1 -0
- package/src/ChangeTrailRefusedError.js +12 -0
- package/src/ChangeTrailRefusedError.js.map +7 -0
- package/src/EntityUuidInUseError.d.ts +19 -0
- package/src/EntityUuidInUseError.d.ts.map +1 -0
- package/src/EntityUuidInUseError.js +11 -0
- package/src/EntityUuidInUseError.js.map +7 -0
- package/src/WorkerTimeoutError.d.ts +25 -0
- package/src/WorkerTimeoutError.d.ts.map +1 -0
- package/src/WorkerTimeoutError.js +12 -0
- package/src/WorkerTimeoutError.js.map +7 -0
- package/src/bundle.d.ts +1 -1
- package/src/bundle.d.ts.map +1 -1
- package/src/bundle.js +1 -1
- package/src/bundle.js.map +2 -2
- package/src/constants.d.ts +9 -2
- package/src/constants.d.ts.map +1 -1
- package/src/constants.js +1 -1
- package/src/constants.js.map +2 -2
- package/src/create-worker.bundle.d.ts +1 -1
- package/src/create-worker.bundle.d.ts.map +1 -1
- package/src/create-worker.bundle.js.map +1 -1
- package/src/create-worker.d.ts +1 -1
- package/src/create-worker.d.ts.map +1 -1
- package/src/create-worker.js.map +1 -1
- package/src/elements/ShaeElement.d.ts +70 -2
- package/src/elements/ShaeElement.d.ts.map +1 -1
- package/src/elements/ShaeElement.js +129 -25
- package/src/elements/ShaeElement.js.map +3 -3
- package/src/elements/ShaeEntElement.d.ts +39 -1
- package/src/elements/ShaeEntElement.d.ts.map +1 -1
- package/src/elements/ShaeEntElement.js +397 -167
- package/src/elements/ShaeEntElement.js.map +2 -2
- package/src/elements/ShaeLifecycleElement.d.ts +71 -0
- package/src/elements/ShaeLifecycleElement.d.ts.map +1 -0
- package/src/elements/ShaeLifecycleElement.js +83 -0
- package/src/elements/ShaeLifecycleElement.js.map +7 -0
- package/src/elements/ShaePropElement.d.ts +52 -2
- package/src/elements/ShaePropElement.d.ts.map +1 -1
- package/src/elements/ShaePropElement.js +240 -219
- package/src/elements/ShaePropElement.js.map +2 -2
- package/src/elements/ShaeWorkerElement.d.ts +49 -5
- package/src/elements/ShaeWorkerElement.d.ts.map +1 -1
- package/src/elements/ShaeWorkerElement.js +204 -73
- package/src/elements/ShaeWorkerElement.js.map +2 -2
- package/src/elements/constants.d.ts +6 -0
- package/src/elements/constants.d.ts.map +1 -1
- package/src/elements/constants.js +12 -0
- package/src/elements/constants.js.map +2 -2
- package/src/elements/deferredTeardown.d.ts +24 -0
- package/src/elements/deferredTeardown.d.ts.map +1 -0
- package/src/elements/deferredTeardown.js +30 -0
- package/src/elements/deferredTeardown.js.map +7 -0
- package/src/elements/displayContentsRule.d.ts +25 -0
- package/src/elements/displayContentsRule.d.ts.map +1 -0
- package/src/elements/displayContentsRule.js +37 -0
- package/src/elements/displayContentsRule.js.map +7 -0
- package/src/elements/events.d.ts +10 -7
- package/src/elements/events.d.ts.map +1 -1
- package/src/elements/forwardCustomEvents.d.ts +19 -0
- package/src/elements/forwardCustomEvents.d.ts.map +1 -0
- package/src/elements/forwardCustomEvents.js +47 -0
- package/src/elements/forwardCustomEvents.js.map +7 -0
- package/src/elements/hostedSlots.d.ts +36 -0
- package/src/elements/hostedSlots.d.ts.map +1 -0
- package/src/elements/hostedSlots.js +118 -0
- package/src/elements/hostedSlots.js.map +7 -0
- package/src/elements/parentRemoval.d.ts +18 -0
- package/src/elements/parentRemoval.d.ts.map +1 -0
- package/src/elements/parentRemoval.js +60 -0
- package/src/elements/parentRemoval.js.map +7 -0
- package/src/elements/propValueConverters.d.ts +3 -0
- package/src/elements/propValueConverters.d.ts.map +1 -0
- package/src/elements/propValueConverters.js +54 -0
- package/src/elements/propValueConverters.js.map +7 -0
- package/src/elements/requestEntAncestor.d.ts +32 -0
- package/src/elements/requestEntAncestor.d.ts.map +1 -0
- package/src/elements/requestEntAncestor.js +16 -0
- package/src/elements/requestEntAncestor.js.map +7 -0
- package/src/elements.js.map +1 -1
- package/src/in-the-dark/Entity.d.ts +113 -3
- package/src/in-the-dark/Entity.d.ts.map +1 -1
- package/src/in-the-dark/Entity.js +292 -63
- package/src/in-the-dark/Entity.js.map +3 -3
- package/src/in-the-dark/Kernel.d.ts +76 -17
- package/src/in-the-dark/Kernel.d.ts.map +1 -1
- package/src/in-the-dark/Kernel.js +410 -378
- package/src/in-the-dark/Kernel.js.map +3 -3
- package/src/in-the-dark/Registry.d.ts.map +1 -1
- package/src/in-the-dark/Registry.js +83 -14
- package/src/in-the-dark/Registry.js.map +2 -2
- package/src/in-the-dark/ShadowObject.d.ts.map +1 -1
- package/src/in-the-dark/ShadowObject.js +1 -0
- package/src/in-the-dark/ShadowObject.js.map +2 -2
- package/src/in-the-dark/ShadowObjectCreationScope.d.ts +126 -0
- package/src/in-the-dark/ShadowObjectCreationScope.d.ts.map +1 -0
- package/src/in-the-dark/ShadowObjectCreationScope.js +596 -0
- package/src/in-the-dark/ShadowObjectCreationScope.js.map +7 -0
- package/src/in-the-dark/SignalsPath.d.ts.map +1 -1
- package/src/in-the-dark/SignalsPath.js +2 -2
- package/src/in-the-dark/SignalsPath.js.map +2 -2
- package/src/in-the-dark/events.js.map +1 -1
- package/src/in-the-dark/importModule.d.ts +7 -0
- package/src/in-the-dark/importModule.d.ts.map +1 -1
- package/src/in-the-dark/importModule.js +5 -2
- package/src/in-the-dark/importModule.js.map +2 -2
- package/src/index.d.ts +7 -1
- package/src/index.d.ts.map +1 -1
- package/src/index.js +5 -1
- package/src/index.js.map +2 -2
- package/src/shadow-objects.d.ts +2 -0
- package/src/shadow-objects.d.ts.map +1 -1
- package/src/shadow-objects.js +2 -0
- package/src/shadow-objects.js.map +2 -2
- package/src/shadow-objects.worker.js +0 -1
- package/src/shadow-objects.worker.js.map +2 -2
- package/src/shae-ent.js.map +1 -1
- package/src/shae-prop.js +2 -2
- package/src/shae-prop.js.map +2 -2
- package/src/shae-worker.js.map +1 -1
- package/src/types.d.ts +35 -4
- package/src/types.d.ts.map +1 -1
- package/src/utils/ConsoleLogger.d.ts +45 -10
- package/src/utils/ConsoleLogger.d.ts.map +1 -1
- package/src/utils/ConsoleLogger.js +51 -26
- package/src/utils/ConsoleLogger.js.map +2 -2
- package/src/utils/FrameLoop.d.ts +42 -3
- package/src/utils/FrameLoop.d.ts.map +1 -1
- package/src/utils/FrameLoop.js +71 -10
- package/src/utils/FrameLoop.js.map +2 -2
- package/src/utils/MicrotaskCollector.d.ts +45 -0
- package/src/utils/MicrotaskCollector.d.ts.map +1 -0
- package/src/utils/MicrotaskCollector.js +33 -0
- package/src/utils/MicrotaskCollector.js.map +7 -0
- package/src/utils/MicrotaskGate.d.ts +17 -0
- package/src/utils/MicrotaskGate.d.ts.map +1 -0
- package/src/utils/MicrotaskGate.js +20 -0
- package/src/utils/MicrotaskGate.js.map +7 -0
- package/src/utils/array-utils.js.map +1 -1
- package/src/utils/attr-utils.d.ts +6 -0
- package/src/utils/attr-utils.d.ts.map +1 -1
- package/src/utils/attr-utils.js +3 -1
- package/src/utils/attr-utils.js.map +2 -2
- package/src/utils/constants.js.map +1 -1
- package/src/utils/generateUUID.d.ts +11 -0
- package/src/utils/generateUUID.d.ts.map +1 -1
- package/src/utils/generateUUID.js +31 -266
- package/src/utils/generateUUID.js.map +2 -2
- package/src/utils/props-utils.d.ts +3 -2
- package/src/utils/props-utils.d.ts.map +1 -1
- package/src/utils/props-utils.js +13 -24
- package/src/utils/props-utils.js.map +2 -2
- package/src/utils/runGuarded.d.ts +27 -0
- package/src/utils/runGuarded.d.ts.map +1 -0
- package/src/utils/runGuarded.js +11 -0
- package/src/utils/runGuarded.js.map +7 -0
- package/src/utils/toMaybe.d.ts.map +1 -1
- package/src/utils/toMaybe.js.map +1 -1
- package/src/utils/toNamespace.d.ts.map +1 -1
- package/src/utils/toNamespace.js.map +1 -1
- package/src/utils/toUrlString.d.ts +12 -0
- package/src/utils/toUrlString.d.ts.map +1 -1
- package/src/utils/toUrlString.js.map +2 -2
- package/src/utils/waitForMessageOfType.d.ts +12 -1
- package/src/utils/waitForMessageOfType.d.ts.map +1 -1
- package/src/utils/waitForMessageOfType.js +16 -1
- package/src/utils/waitForMessageOfType.js.map +2 -2
- package/src/view/ComponentChanges.d.ts +88 -1
- package/src/view/ComponentChanges.d.ts.map +1 -1
- package/src/view/ComponentChanges.js +243 -73
- package/src/view/ComponentChanges.js.map +2 -2
- package/src/view/ComponentContext.d.ts +206 -16
- package/src/view/ComponentContext.d.ts.map +1 -1
- package/src/view/ComponentContext.js +548 -91
- package/src/view/ComponentContext.js.map +2 -2
- package/src/view/ComponentMemory.d.ts +3 -3
- package/src/view/ComponentMemory.d.ts.map +1 -1
- package/src/view/ComponentMemory.js.map +1 -1
- package/src/view/IShadowObjectEnvProxy.d.ts +29 -3
- 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 +8 -6
- package/src/view/LocalShadowObjectEnv.js.map +2 -2
- package/src/view/RemoteWorkerEnv.d.ts +89 -5
- package/src/view/RemoteWorkerEnv.d.ts.map +1 -1
- package/src/view/RemoteWorkerEnv.js +195 -77
- package/src/view/RemoteWorkerEnv.js.map +2 -2
- package/src/view/ShadowEnv.d.ts +49 -2
- package/src/view/ShadowEnv.d.ts.map +1 -1
- package/src/view/ShadowEnv.js +223 -60
- package/src/view/ShadowEnv.js.map +2 -2
- package/src/view/ViewComponent.d.ts +78 -14
- package/src/view/ViewComponent.d.ts.map +1 -1
- package/src/view/ViewComponent.js +90 -14
- package/src/view/ViewComponent.js.map +2 -2
- package/src/view/cloneChangeTrail.js.map +2 -2
- package/src/worker/MessageRouter.d.ts +14 -0
- package/src/worker/MessageRouter.d.ts.map +1 -1
- package/src/worker/MessageRouter.js +75 -15
- package/src/worker/MessageRouter.js.map +2 -2
- package/src/worker/WorkerRuntime.d.ts +22 -1
- package/src/worker/WorkerRuntime.d.ts.map +1 -1
- package/src/worker/WorkerRuntime.js +60 -8
- package/src/worker/WorkerRuntime.js.map +2 -2
|
@@ -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 */\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": "AAAA,SAAQ,kBAAkB,aAAa,gBAAe;AAEtD,SAAQ,kBAAiB;AACzB,SAAQ,mBAAkB;AAC1B,SAAQ,wBAAuB;AAC/B,SAAQ,uBAAsB;AAqCvB,MAAM,sCAAsC,MAAM;AAAA,EACvD,YAAY,UAAU,2CAA2C;AAC/D,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,MAAM,iBAAiB;AAAA,EAC5B;AAAA,SAAgB,uBAAuB;AAAA;AAAA,EAEvC,OAAO,iBAAuD;AAC5D,QAAI,WAAW,wBAAwB,MAAM;AAC3C,iBAAW,uBAAuB,oBAAI,IAAqC;AAAA,IAC7E;AACA,WAAO,WAAW;AAAA,EACpB;AAAA,EAEA,OAAO,IAAI,WAA6C;AACtD,UAAM,KAAK,YAAY,SAAS;AAChC,UAAM,SAAS,iBAAiB,eAAe;AAC/C,QAAI,OAAO,IAAI,EAAE,GAAG;AAClB,aAAO,OAAO,IAAI,EAAE;AAAA,IACtB;AACA,WAAO,IAAI,iBAAiB,EAAE;AAAA,EAChC;AAAA,EAIA,cAAyC,oBAAI,IAAI;AAAA,EACjD,kBAA4B,CAAC;AAAA;AAAA,EAC7B,cAAc;AAAA,EAEL,mBAAmB,IAAI,gBAAgB;AAAA,EAEhD,YAAY,YAA2B,UAAU;AAC/C,UAAM,KAAK,YAAY,SAAS;AAChC,UAAM,SAAS,iBAAiB,eAAe;AAC/C,QAAI,OAAO,IAAI,EAAE,GAAG;AAClB,aAAO,OAAO,IAAI,EAAE;AAAA,IACtB;AACA,SAAK,KAAK;AACV,WAAO,IAAI,IAAI,IAAI;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,IAAI,aAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,aAAa,WAA0B;AACrC,QAAI,KAAK,aAAa;AACpB,YAAM,IAAI;AAAA,QACR,sBAAsB,UAAU,IAAI;AAAA,MACtC;AAAA,IACF;AAEA,QAAI,eAAe,KAAK,YAAY,IAAI,UAAU,IAAI;AAEtD,QAAI,cAAc;AAChB,UAAI,aAAa,cAAc,WAAW;AAGxC,mBAAW,aAAa,aAAa,SAAS,MAAM,CAAC,GAAG;AACtD,eAAK,YAAY,IAAI,SAAS,GAAG,UAAU,iBAAiB;AAAA,QAC9D;AAAA,MACF;AAEA,mBAAa,YAAY;AACzB,mBAAa,WAAW,CAAC;AAAA,IAC3B,OAAO;AACL,qBAAe;AAAA,QACb;AAAA,QACA,UAAU,CAAC;AAAA,QACX,SAAS,IAAI,iBAAiB,UAAU,IAAI;AAAA,QAC5C,aAAa;AAAA,MACf;AACA,WAAK,YAAY,IAAI,UAAU,MAAM,YAAY;AAAA,IACnD;AAEA,iBAAa,QAAQ;AAAA,MACnB,UAAU;AAAA,MACV,UAAU,QAAQ;AAAA,MAClB,UAAU;AAAA,MACV,UAAU;AAAA,IACZ;AAEA,QAAI,UAAU,QAAQ;AACpB,WAAK,cAAc,UAAU,QAAQ,SAAS;AAC9C,mBAAa,QAAQ,UAAU,UAAU,OAAO,IAAI;AAAA,IACtD,OAAO;AACL,WAAK,iBAAiB,WAAW,KAAK,eAAe;AAAA,IACvD;AAEA,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,aAAa,WAA0B;AACrC,WAAO,KAAK,YAAY,IAAI,UAAU,IAAI;AAAA,EAC5C;AAAA,EAEA,gBAAgB;AACd,WAAO,KAAK,YAAY,OAAO;AAAA,EACjC;AAAA,EAEA,gBAAgB,WAA0B;AACxC,WAAO,KAAK,gBAAgB,SAAS,UAAU,IAAI;AAAA,EACrD;AAAA,EAEA,iBAAiB,WAA0B;AACzC,QAAI,KAAK,aAAa,SAAS,GAAG;AAChC,YAAM,QAAQ,KAAK,YAAY,IAAI,UAAU,IAAI;AACjD,iBAAW,aAAa,MAAM,SAAS,MAAM,CAAC,GAAG;AAC/C,aAAK,YAAY,IAAI,SAAS,GAAG,UAAU,iBAAiB;AAAA,MAC9D;AACA,YAAM,QAAQ,QAAQ;AACtB,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,YAAY,WAA2C;AACrD,WAAO,KAAK,YAAY,IAAI,UAAU,IAAI,GAAG,SAAS,IAAI,CAAC,SAAS,KAAK,YAAY,IAAI,IAAI,EAAG,SAAS,KAAK,CAAC;AAAA,EACjH;AAAA,EAEA,iBAAiB,WAAmB,QAAuB;AACzD,QAAI,KAAK,aAAa,MAAM,GAAG;AAG7B,YAAM,aAAa,KAAK,YAAY,IAAI,SAAS;AACjD,UAAI,eAAe,OAAW;AAE9B,YAAM,cAAc,KAAK,YAAY,IAAI,OAAO,IAAI;AACpD,YAAM,WAAW,YAAY,SAAS,QAAQ,SAAS;AACvD,UAAI,aAAa,IAAI;AACnB,oBAAY,SAAS,OAAO,UAAU,CAAC;AACvC,mBAAW,QAAQ,UAAU,MAAS;AAAA,MACxC;AACA,WAAK,iBAAiB,WAAW,WAAW,KAAK,eAAe;AAChE,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,WAAW,WAAmB;AAC5B,UAAM,aAAa,KAAK,YAAY,IAAI,SAAS;AACjD,QAAI,YAAY;AACd,iBAAW,SAAS,UAAU,MAAS;AACvC,WAAK,iBAAiB,WAAW,WAAW,KAAK,eAAe;AAAA,IAClE;AACA,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,YAAY,WAA0B,OAAgB;AACpD,SAAK,YAAY,IAAI,UAAU,IAAI,GAAG,QAAQ,YAAY,KAAK;AAAA,EACjE;AAAA,EAEA,UAAU,OAAsB,QAAuB;AACrD,QAAI,KAAK,aAAa,MAAM,GAAG;AAC7B,YAAM,QAAQ,KAAK,YAAY,IAAI,OAAO,IAAI;AAC9C,aAAO,MAAM,SAAS,SAAS,MAAM,IAAI;AAAA,IAC3C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,QAAuB,OAAsB;AACzD,UAAM,QAAQ,KAAK,YAAY,IAAI,OAAO,IAAI;AAC9C,QAAI,OAAO;AACT,WAAK,iBAAiB,OAAO,MAAM,QAAQ;AAC3C,WAAK,YAAY,IAAI,MAAM,IAAI,GAAG,QAAQ,UAAU,OAAO,IAAI;AAC/D,iBAAW,KAAK,iBAAiB,MAAM,IAAI;AAC3C,WAAK,iBAAiB;AAAA,IACxB,OAAO;AACL,YAAM,IAAI,MAAM,sBAAsB,OAAO,IAAI,sEAAsE;AAAA,IACzH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAAc,MAAc;AAC1B,SAAK,eAAe,MAAM,oBAAI,IAAI,CAAC;AAAA,EACrC;AAAA,EAEA,eAAe,MAAc,SAAsB;AACjD,QAAI,QAAQ,IAAI,IAAI,EAAG;AACvB,YAAQ,IAAI,IAAI;AAEhB,UAAM,QAAQ,KAAK,YAAY,IAAI,IAAI;AACvC,QAAI,OAAO;AACT,iBAAW,aAAa,MAAM,SAAS,MAAM,CAAC,GAAG;AAC/C,aAAK,eAAe,WAAW,OAAO;AAAA,MACxC;AACA,WAAK,iBAAiB,MAAM,SAAS;AACrC,WAAK,iBAAiB,IAAI;AAAA,IAC5B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,YAAyB,WAA0B,SAAiB,OAAU,SAA4C;AACxH,UAAM,KAAK,KAAK,YAAY,IAAI,UAAU,IAAI;AAC9C,QAAI,MAAM,MAAM;AACd,UAAI,WAAW,MAAM;AACnB,WAAG,gBAAgB,oBAAI,IAAI;AAC3B,WAAG,YAAY,IAAI,SAAS,OAAO;AAAA,MACrC,WAAW,GAAG,aAAa,IAAI,OAAO,GAAG;AACvC,WAAG,YAAY,OAAO,OAAO;AAAA,MAC/B;AACA,aAAO,GAAG,QAAQ,eAAe,SAAS,OAAO,OAAO;AAAA,IAC1D;AACA,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,WAA0B,SAAiB;AACxD,SAAK,YAAY,IAAI,UAAU,IAAI,GAAG,QAAQ,eAAe,OAAO;AAAA,EACtE;AAAA,EAEA,YAAY,WAA0B;AAGpC,UAAM,QAAQ,KAAK,YAAY,IAAI,UAAU,IAAI;AACjD,QAAI,UAAU,OAAW;AAEzB,UAAM,cAAc,UAAU,SAAS,KAAK,YAAY,IAAI,UAAU,OAAO,IAAI,IAAI;AACrF,QAAI,gBAAgB,QAAW;AAC7B,iBAAW,YAAY,UAAU,UAAU,IAAI;AAC/C,WAAK,iBAAiB,WAAW,YAAY,QAAQ;AAAA,IACvD,WAAW,UAAU,UAAU,MAAM;AACnC,iBAAW,KAAK,iBAAiB,UAAU,IAAI;AAC/C,WAAK,iBAAiB,WAAW,KAAK,eAAe;AAAA,IACvD;AAEA,UAAM,QAAQ,YAAY,UAAU,KAAK;AACzC,SAAK,iBAAiB;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,wBAAyC;AACvC,WAAO,KAAK,uBAAuB,EAAE,IAAI,CAAC,OAAO,GAAG,SAAS;AAAA,EAC/D;AAAA;AAAA;AAAA;AAAA,EAKA,2BAA2B,WAA0B,MAAc,MAAe,eAAgC;AAChH,SAAK,YAAY,IAAI,UAAU,IAAI,GAAG,QAAQ,YAAY,MAAM,MAAM,aAAa;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,MAAc,OAAgB,QAAW;AACtD,eAAW,KAAK,KAAK,sBAAsB,GAAG;AAC5C,QAAE,cAAc,MAAM,MAAM,KAAK;AAAA,IACnC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,MAAc,MAAc,OAAgB,QAAW,mBAAmB,OAAO;AAC/F,SAAK,YAAY,IAAI,IAAI,GAAG,UAAU,cAAc,MAAM,MAAM,gBAAgB;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA,EAKA,+BAA+B;AAC7B,eAAW,QAAQ,KAAK,iBAAiB;AACvC,WAAK,gBAAgB,MAAM,iBAAiB,oBAAoB;AAAA,IAClE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,kBAAkB,eAAe,MAAuB;AACtD,UAAM,SAAiC,CAAC;AAExC,QAAI,CAAC,KAAK,cAAc,EAAG,QAAO;AAElC,UAAM,gBAAgB,KAAK,oBAAoB;AAO/C,eAAW,WAAW,eAAe;AACnC,cAAQ,iBAAiB,QAAQ,iBAAiB,iBAAiB;AAAA,IACrE;AAEA,eAAW,WAAW,eAAe;AACnC,cAAQ,iBAAiB,QAAQ,iBAAiB,cAAc;AAAA,IAClE;AAEA,eAAW,WAAW,eAAe;AACnC,cAAQ,iBAAiB,QAAQ,iBAAiB,OAAO;AAEzD,UAAI,QAAQ,eAAgB,QAAQ,SAAS,CAAC,QAAQ,WAAY;AAChE,aAAK,iBAAiB,QAAQ,IAAI;AAAA,MACpC;AAEA,UAAI,aAAc,SAAQ,MAAM;AAAA,IAClC;AAEA,SAAK,iBAAiB,MAAM,MAAM;AAElC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,kBAAkB;AAChB,QAAI,KAAK,iBAAiB,QAAQ,EAAG;AAErC,SAAK,kBAAkB,KAAK;AAE5B,eAAW,CAAC,MAAM,IAAI,KAAK,KAAK,kBAAkB;AAChD,YAAM,IAAI,KAAK,YAAY,IAAI,IAAI;AACnC,UAAI,GAAG;AACL,cAAM,UAAU,IAAI,iBAAiB,IAAI;AACzC,gBAAQ,OAAO,KAAK,OAAO,KAAK,YAAY,KAAK,OAAO,KAAK,8BAA8B;AAE3F,YAAI,KAAK,YAAY;AACnB,qBAAW,CAAC,KAAK,KAAK,KAAK,KAAK,YAAY;AAC1C,oBAAQ,eAAe,KAAK,OAAO,EAAE,aAAa,IAAI,GAAG,CAAC;AAAA,UAC5D;AAAA,QACF;AAEA,UAAE,QAAQ,iBAAiB,OAAO;AAClC,UAAE,QAAQ,MAAM;AAEhB,UAAE,UAAU;AAAA,MACd;AAAA,IACF;AAEA,SAAK,iBAAiB,MAAM;AAE5B,SAAK,eAAe,WAAW;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ;AACN,SAAK,iBAAiB;AACtB,SAAK,iBAAiB,MAAM;AAE5B,eAAW,QAAQ,KAAK,gBAAgB,MAAM,CAAC,GAAG;AAChD,WAAK,cAAc,IAAI;AAAA,IACzB;AAEA,QAAI,KAAK,gBAAgB,WAAW,GAAG;AACrC,YAAM,IAAI,MAAM,wDAAwD;AAAA,IAC1E;AAEA,QAAI,KAAK,YAAY,SAAS,GAAG;AAC/B,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,UAAU;AACR,QAAI,KAAK,YAAa;AAItB,eAAW,EAAC,UAAS,KAAK,MAAM,KAAK,KAAK,YAAY,OAAO,CAAC,GAAG;AAC/D,gBAAU,QAAQ;AAAA,IACpB;AAEA,SAAK,MAAM;AAEX,SAAK,cAAc;AAEnB,UAAM,SAAS,iBAAiB,eAAe;AAC/C,QAAI,KAAK,MAAM,QAAQ,OAAO,IAAI,KAAK,EAAE,MAAM,MAAM;AACnD,aAAO,OAAO,KAAK,EAAE;AAAA,IACvB;AAAA,EACF;AAAA,EAEA,iBAAiB,MAAc;AAC7B,UAAM,QAAQ,KAAK,YAAY,IAAI,IAAI;AACvC,QAAI,UAAU,OAAW;AAIzB,UAAM,aAAa,MAAM,UAAU,QAAQ;AAC3C,QAAI,eAAe,QAAW;AAC5B,YAAM,cAAc,KAAK,YAAY,IAAI,UAAU;AACnD,UAAI,gBAAgB,QAAW;AAC7B,mBAAW,YAAY,UAAU,IAAI;AAAA,MACvC;AAAA,IACF;AAEA,SAAK,YAAY,OAAO,IAAI;AAC5B,eAAW,KAAK,iBAAiB,IAAI;AACrC,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,sBAA0C;AACxC,WAAO,KAAK,uBAAuB,EAChC,OAAO,CAAC,OAAO,GAAG,QAAQ,WAAW,CAAC,EACtC,IAAI,CAAC,OAAO,GAAG,OAAO;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,iBAAiB,WAA0B,YAAsB;AAC/D,QAAI,WAAW,SAAS,UAAU,IAAI,GAAG;AACvC;AAAA,IACF;AAEA,UAAM,EAAC,MAAK,IAAI;AAEhB,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,YAAM,QAAQ,KAAK,YAAY,IAAI,WAAW,CAAC,CAAC,GAAG;AACnD,UAAI,UAAU,UAAa,QAAQ,MAAM,OAAO;AAC9C,mBAAW,OAAO,GAAG,GAAG,UAAU,IAAI;AACtC;AAAA,MACF;AAAA,IACF;AAEA,eAAW,KAAK,UAAU,IAAI;AAAA,EAChC;AAAA,EAEA;AAAA,EAEA,yBAAyC;AACvC,QAAI,KAAK,eAAgB,QAAO,KAAK;AAErC,UAAM,MAAM,oBAAI,IAA4B;AAE5C,UAAM,WAAW,CAAC,MAAc,UAAkB;AAChD,YAAM,eAAe,KAAK,YAAY,IAAI,IAAI;AAC9C,UAAI,gBAAgB,KAAM;AAE1B,YAAM,UAAU,IAAI,IAAI,KAAK;AAC7B,UAAI,SAAS;AACX,gBAAQ,KAAK,YAAY;AAAA,MAC3B,OAAO;AACL,YAAI,IAAI,OAAO,CAAC,YAAY,CAAC;AAAA,MAC/B;AAEA,iBAAW,aAAa,aAAa,UAAU;AAC7C,iBAAS,WAAW,QAAQ,CAAC;AAAA,MAC/B;AAAA,IACF;AAEA,eAAW,QAAQ,KAAK,iBAAiB;AACvC,eAAS,MAAM,CAAC;AAAA,IAClB;AAEA,SAAK,iBAAiB,MAAM,KAAK,IAAI,QAAQ,CAAC,EAC3C,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EAC1B,QAAQ,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE;AAEzB,WAAO,KAAK;AAAA,EACd;AACF;",
|
|
4
|
+
"sourcesContent": ["import {ChangeTrailPhase, ContextLost, GlobalNS} from '../constants.js';\nimport type {ChangeTrailType, IComponentChangeType, NamespaceType} from '../types.js';\nimport {ConsoleLogger} from '../utils/ConsoleLogger.js';\nimport {MicrotaskCollector} from '../utils/MicrotaskCollector.js';\nimport {runGuarded} from '../utils/runGuarded.js';\nimport {toNamespace} from '../utils/toNamespace.js';\nimport {ComponentChanges, PropertyWithoutValue} from './ComponentChanges.js';\nimport {ComponentMemory, type ComponentState} from './ComponentMemory.js';\nimport type {ViewComponent} from './ViewComponent.js';\n\n/**\n * A list of uuids that keeps its order and answers membership in one step.\n *\n * The order is what forbids a bare Set: the entity tree is walked in it, and a Set answers\n * membership but not position. So both are kept, and both are written only from here -- a\n * parallel set that any caller may write drifts from its list, and a uuid that one half knows\n * and the other does not is the defect this class exists to make impossible.\n */\nclass OrderedUuids {\n readonly #uuids: string[] = [];\n readonly #members = new Set<string>();\n\n /** The uuids in their order. Read-only: every write goes through this class. */\n get uuids(): readonly string[] {\n return this.#uuids;\n }\n\n get size(): number {\n return this.#uuids.length;\n }\n\n has(uuid: string): boolean {\n return this.#members.has(uuid);\n }\n\n push(uuid: string): void {\n this.#uuids.push(uuid);\n this.#members.add(uuid);\n }\n\n insertAt(index: number, uuid: string): void {\n this.#uuids.splice(index, 0, uuid);\n this.#members.add(uuid);\n }\n\n /** @returns whether the uuid was in the list */\n delete(uuid: string): boolean {\n if (!this.#members.delete(uuid)) return false;\n const idx = this.#uuids.indexOf(uuid);\n // Both halves are written together and only here, so the index is always found. The guard is\n // what keeps a `splice(-1, 1)` from cutting the last uuid out, should that ever stop holding.\n if (idx !== -1) {\n this.#uuids.splice(idx, 1);\n }\n return true;\n }\n\n clear(): void {\n this.#uuids.length = 0;\n this.#members.clear();\n }\n}\n\ninterface ViewInstance {\n component: ViewComponent;\n // the entity tree is walked in this order, so the children are a list and not a set: it is the\n // order in which one parent's children reach the shadow objects\n children: OrderedUuids;\n changes: ComponentChanges;\n propIsEqual?: Map<string, (a: any, b: any) => boolean> | undefined;\n}\n\ndeclare global {\n var __shadowObjectsContexts: Map<string | symbol, ComponentContext> | undefined;\n}\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\n/**\n * Thrown when a {@link ViewComponent} tries to join a {@link ComponentContext} under a uuid\n * another component of that {@link ComponentContext} is holding. A uuid names one component at a\n * time; it becomes free again once its holder has left.\n */\nexport class ComponentUuidInUseError extends Error {\n readonly uuid: string;\n\n constructor(uuid: string) {\n super(`the view component cannot join the component context because the uuid ${uuid} is already held by another component`);\n this.name = 'ComponentUuidInUseError';\n this.uuid = uuid;\n }\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} instance per namespace: the constructor returns the\n * existing instance for an already-occupied namespace rather than building a second one, so\n * {@link ComponentContext.get} is the way consumers are meant to reach it.\n */\nexport class ComponentContext {\n static readonly ReRequestParentRoots = 're-request-parent-roots';\n static readonly ReRequestParent = 're-request-parent';\n\n /**\n * Ask the element behind a component to let the properties hanging on it look for their host\n * again.\n *\n * A context knows nothing about `<shae-prop>` \u2014 a property has no view component and cannot be\n * addressed here. The signal still belongs next to the two above: it travels the same broadcast\n * channel to the same receivers, and the element on the other end is the one that can reach the\n * properties below it.\n */\n static readonly ReRequestEntHost = 're-request-ent-host';\n\n static getContextsMap(): Map<NamespaceType, ComponentContext> {\n if (globalThis.__shadowObjectsContexts == null) {\n globalThis.__shadowObjectsContexts = new Map<NamespaceType, ComponentContext>();\n }\n return globalThis.__shadowObjectsContexts;\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 // the entity tree is walked in this order, so the roots are a list and not a set\n #rootComponents = new OrderedUuids();\n #isDisposed = false;\n\n // which instances name this ComponentContext, and the one place that can say so. #components holds one\n // entry per uuid, and an entry outlives the departure of its component until the next change\n // trail \u2014 so a uuid standing in that map is no statement about anyone still being a member\n readonly #componentInstances = new Set<ViewComponent>();\n\n /**\n * The entry `component` owns, and nothing else.\n *\n * An entry outlives the departure of its component until the next change trail, so a later\n * component can take the uuid over while the entry is still standing. A lookup by uuid alone\n * would then hand back the entry of a namesake, and every write that followed would land on a\n * live component that was never named. Each method that is given an instance asks through here,\n * so that it acts on that instance or on nothing.\n */\n #entryOf(component: ViewComponent): ViewInstance | undefined {\n const entry = this.#components.get(component.uuid);\n return entry !== undefined && entry.component === component ? entry : undefined;\n }\n\n readonly #componentMemory = new ComponentMemory();\n\n readonly #logger = new ConsoleLogger('ComponentContext');\n\n /**\n * The change trail this context built last, as long as nobody has settled it yet.\n * `owners[i]` is the bookkeeping that produced `entries[i]`; `retiring` are the components the\n * build read as spent, which is a verdict of the build and not of the commit \u2014 a component\n * destroyed while the trail travels owes its destruction to the *next* trail, and dropping its\n * entry here would leave the entity standing with nothing left to take it down.\n */\n #uncommittedTrail?: {entries: IComponentChangeType[]; owners: ComponentChanges[]; retiring: ComponentChanges[]} | undefined;\n\n /** The components a build reads as spent: destroyed, or created and dropped without ever going out. */\n #retiringComponents(participants: ComponentChanges[]): ComponentChanges[] {\n return participants.filter((changes) => changes.isDestroyed || (changes.isNew && !changes.isCreated));\n }\n\n /**\n * Carry out the verdict the build took, for the components whose every entry is settled.\n *\n * A component that has been claimed again since the build stays: a uuid its holder has left is\n * free, and the entry now belongs to whoever took it over.\n */\n #retireComponents(retiring: ComponentChanges[], stillPending?: Set<ComponentChanges>): void {\n for (const changes of retiring) {\n if (stillPending?.has(changes)) continue;\n if (changes.isCreated) continue;\n this.#deleteComponent(changes.uuid, changes);\n }\n }\n\n /**\n * Release the record of the built trail and drop the components it retired, without folding\n * anything into their bookkeeping.\n */\n #retireBuiltTrail(): void {\n const uncommitted = this.#uncommittedTrail;\n if (uncommitted == null) return;\n\n this.#uncommittedTrail = undefined;\n\n this.#retireComponents(uncommitted.retiring);\n }\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 /**\n * Take a component in: it becomes a member of this {@link ComponentContext} and a\n * `CreateEntities` change is written for its uuid.\n *\n * Called by the {@link ViewComponent#context} setter, and by nothing else.\n *\n * @throws {ComponentContextDisposedError} if this {@link ComponentContext} has been disposed\n * @throws {ComponentUuidInUseError} if another member of this {@link ComponentContext} holds\n * `component.uuid`\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 // a uuid names one component at a time. The entry of a component that has left this\n // ComponentContext outlives it until the next change trail, so a later component may take the\n // uuid over \u2014 but not while the component holding it is still a member here: the two\n // would share one entry and one set of create/destroy counts, and the entity behind\n // the uuid would outlive both of them\n if (this.#componentInstances.has(viewInstance.component)) {\n throw new ComponentUuidInUseError(component.uuid);\n }\n\n // the predecessor promoted its children to root components on its way out; this is the\n // net that keeps a children list from outliving the component that filled it\n for (const childUuid of [...viewInstance.children.uuids]) {\n this.#components.get(childUuid)?.component.removeFromParent();\n }\n }\n\n viewInstance.component = component;\n viewInstance.children.clear();\n } else {\n viewInstance = {\n component,\n children: new OrderedUuids(),\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.#componentInstances.add(component);\n this.#viewInstances = undefined;\n }\n\n /**\n * Whether `component` is a member of this {@link ComponentContext} right now.\n *\n * This is the question about the instance, and the only one this class answers about\n * membership. A component that has left gets `false`, even while its entry is still standing \u2014\n * {@link ComponentContext.hasComponents} is what counts entries.\n */\n hasComponent(component: ViewComponent) {\n return this.#componentInstances.has(component);\n }\n\n hasComponents() {\n return this.#components.size > 0;\n }\n\n isRootComponent(component: ViewComponent) {\n return this.#entryOf(component) !== undefined && this.#rootComponents.has(component.uuid);\n }\n\n destroyComponent(component: ViewComponent) {\n // every way out of this context comes through here, so this is where an instance stops\n // naming us \u2014 unconditional, because a caller from outside runs through twice:\n // destroyComponent(vc) \u2192 vc.destroy() \u2192 destroyComponent(vc)\n this.#componentInstances.delete(component);\n\n const entry = this.#entryOf(component);\n\n // destroying an entry twice would put the destroy count ahead of the create count: a\n // component that joins again afterwards would be destroyed by the very next change trail.\n // And the entry belongs to whoever holds the uuid now \u2014 a component that has already left\n // goes a second time without taking that one's entity down with it\n if (entry !== undefined && !entry.changes.isDestroyed) {\n for (const childUuid of [...entry.children.uuids]) {\n this.#components.get(childUuid)?.component.removeFromParent();\n }\n entry.changes.destroy();\n this.#viewInstances = undefined;\n }\n\n // a component this context has torn down must not keep pointing at it, otherwise it keeps\n // reporting itself as alive. A component drops that pointer as it leaves its context, before\n // it calls back in here, so this branch is taken at most once\n if (component.context === this) {\n component.destroy();\n }\n }\n\n /**\n * The children of `component`, in sort order \u2014 a fresh array each call, and an empty one for\n * an instance that does not own its entry.\n *\n * Uuids without a matching view instance are skipped instead of dereferenced: `addToChildren()`\n * writes a uuid into a children list without the parent link of the child following along, so\n * `#deleteComponent()` has no list to take that uuid out of and the entry behind it goes while\n * the list keeps naming it. `#appendToOrdered()` and `#traverseLevelOrderBFS()` read a children\n * list the same way.\n */\n getChildren(component: ViewComponent): ViewComponent[] {\n const children = this.#entryOf(component)?.children;\n if (children === undefined) return [];\n\n const result: ViewComponent[] = [];\n for (const uuid of children.uuids) {\n const entry = this.#components.get(uuid);\n if (entry !== undefined) {\n result.push(entry.component);\n }\n }\n return result;\n }\n\n removeFromParent(component: ViewComponent, parent: ViewComponent) {\n const parentEntry = this.#entryOf(parent);\n if (parentEntry === undefined) return;\n\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.#entryOf(component);\n if (childEntry === undefined) return;\n\n // the promotion follows the detachment: a parent that does not hold this uuid gives nothing\n // up, and a component appended to the roots regardless would stand under the roots and in\n // the children list of the parent that really holds it at the same time\n if (parentEntry.children.delete(component.uuid)) {\n childEntry.changes.setParent(undefined);\n this.#appendToOrdered(childEntry.component, this.#rootComponents);\n this.#viewInstances = undefined;\n }\n }\n\n moveToRoot(component: ViewComponent) {\n const childEntry = this.#entryOf(component);\n if (childEntry === undefined) return;\n\n // the parent link names the list this uuid stands in, the way `changeOrder()` and\n // `#deleteComponent()` read it; leaving it there would put the component under the roots\n // and under a parent at once. The link itself is left alone -- clearing it is the business\n // of `ViewComponent.removeFromParent()`, which is where the two are written together\n const parentEntry = component.parent ? this.#entryOf(component.parent) : undefined;\n parentEntry?.children.delete(component.uuid);\n\n childEntry.changes.setParent(undefined);\n this.#appendToOrdered(childEntry.component, this.#rootComponents);\n this.#viewInstances = undefined;\n }\n\n changeToken(component: ViewComponent, token?: string) {\n this.#entryOf(component)?.changes.changeToken(token);\n }\n\n isChildOf(child: ViewComponent, parent: ViewComponent) {\n const parentEntry = this.#entryOf(parent);\n return parentEntry !== undefined && this.#entryOf(child) !== undefined && parentEntry.children.has(child.uuid);\n }\n\n addToChildren(parent: ViewComponent, child: ViewComponent) {\n const entry = this.#entryOf(parent);\n if (entry) {\n // a uuid put into a children list without an entry of its own behind it makes the next\n // clear() panic, so the child side is only touched for a child this context holds\n const childEntry = this.#entryOf(child);\n if (childEntry === undefined) return;\n\n this.#appendToOrdered(child, entry.children);\n childEntry.changes.setParent(parent.uuid);\n this.#rootComponents.delete(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 this context does not hold it`);\n }\n }\n\n /**\n * Destroy a component and all its descendants without writing anything to a change trail.\n * Each of them is detached from this context and reports {@link ViewComponent#isDestroyed}.\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.uuids]) {\n this.#removeSubTree(childUuid, visited);\n }\n // the entry goes before the teardown, not after it: `ViewComponent.Destroyed` travels\n // while the component is still able to act, and a listener there may put the component\n // back into this ComponentContext. Deleting the entry afterwards would take that join with\n // it and leave the component naming a ComponentContext that holds nothing under its uuid \u2014\n // free for a second component to claim, with both alive. Nothing here needs the entry\n // afterwards: this path writes no change trail, so the change bookkeeping in it has no\n // reader left, and the child uuid comes out of the parent's children list from here, while\n // the parent link is still there to name it \u2014 the teardown drops that link\n this.#deleteComponent(uuid);\n this.destroyComponent(entry.component);\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.#entryOf(component);\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 /**\n * Mark `propKey` on `component` as set without giving it a value: the change trail carries\n * an entry that names only the key, and the entity behind it reads the property as\n * `undefined` with the key in place. {@link ComponentContext.setProperty} with `undefined`\n * is the other thing \u2014 a removal.\n *\n * An equality rule registered for the key is forgotten, the way it is for a\n * {@link ComponentContext.setProperty} that comes without one: there is no value here for a\n * rule to compare.\n *\n * @returns `true` when this differs from the last value written to a change trail, and\n * `false` for an instance that does not own its entry\n */\n setPropertyWithoutValue(component: ViewComponent, propKey: string): boolean {\n const vi = this.#entryOf(component);\n if (vi != null) {\n vi.propIsEqual?.delete(propKey);\n return vi.changes.setPropertyWithoutValue(propKey);\n }\n return false;\n }\n\n removeProperty(component: ViewComponent, propKey: string) {\n this.#entryOf(component)?.changes.removeProperty(propKey);\n }\n\n /**\n * Hand the properties of `component` over to the context it has just joined.\n *\n * Called by the {@link ViewComponent#context} setter, and by nothing else. It reads the state\n * this context still holds for the component: leaving a context destroys it, but the entry\n * survives until the next {@link ComponentContext.buildChangeTrails}, so the properties are\n * still there to be read once the join has happened.\n *\n * The equality function travels with each property, because it is a rule about the key and not\n * about the value \u2014 the same key means the same notion of \"unchanged\" wherever it lives. It does\n * not get to decide about the arrival, though: the target holds nothing for the key yet, so it\n * would be asked whether the value equals `undefined`, and a function that says yes would drop\n * the property instead of carrying it over. The value is therefore written first and the rule\n * registered after it \u2014 the other way round, the write would delete the entry it just made,\n * because {@link ComponentContext.setProperty} keeps only what its caller passes.\n *\n * What the registered rule is for: {@link ComponentContext.reCreateChanges} is its one reader,\n * and it compares with it when it rebuilds a component from the memory. A later\n * {@link ComponentContext.setProperty} does not consult it \u2014 it uses its own argument, or none.\n *\n * A property that is set without a value goes over as one: handing it on as the value\n * `undefined` would have the target read it as a removal, and the key would not arrive.\n *\n * Built like {@link ComponentChanges.transferEventsTo}, with one difference: the properties are\n * copied, not moved. What stays behind goes down with the entity in this context.\n */\n transferPropertiesTo(component: ViewComponent, target: ComponentContext) {\n const vi = this.#entryOf(component);\n if (vi === undefined) return;\n\n for (const [key, value] of vi.changes.getProperties()) {\n if (value === PropertyWithoutValue) {\n target.setPropertyWithoutValue(component, key);\n } else {\n target.setProperty(component, key, value);\n }\n\n const isEqual = vi.propIsEqual?.get(key);\n if (isEqual != null) {\n target.#registerPropIsEqual(component, key, isEqual);\n }\n }\n }\n\n #registerPropIsEqual(component: ViewComponent, propKey: string, isEqual: (a: any, b: any) => boolean) {\n const vi = this.#entryOf(component);\n if (vi === undefined) return;\n\n vi.propIsEqual ??= new Map();\n vi.propIsEqual.set(propKey, isEqual);\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 this is public API, so the argument may well be a component whose uuid has\n // no entry here at all, and a uuid put back into an ordered list without one makes clear() panic\n const entry = this.#entryOf(component);\n if (entry === undefined) return;\n\n const parentEntry = component.parent ? this.#entryOf(component.parent) : undefined;\n if (parentEntry !== undefined) {\n parentEntry.children.delete(component.uuid);\n this.#appendToOrdered(component, parentEntry.children);\n } else if (component.parent == null) {\n this.#rootComponents.delete(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.#entryOf(component)?.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 * Every root is asked, because there is nothing here to ask about: the message carries no\n * sender, so this side cannot narrow the set down at all. The receiver is the one that can:\n * it re-asks the element tree, and whoever answers first wins.\n *\n * Delivery is immediate: the round is over by the time the call returns. Two paths inside the\n * library end here \u2014 {@link ComponentContext.dispatchReRequestParentSiblings} for a component\n * without a parent, whose candidate set is the roots, and the delivery of a collected round for\n * that same set. What does not come this way is an entity that has just arrived: it hands its\n * round to the collector below. The method is public because running a round at a moment of\n * one's own choosing is what it is for.\n */\n dispatchReRequestParentRoots() {\n // a root that answers with a parent is taken out of #rootComponents right away, so walking\n // the live array would skip the entry that slid into the freed slot \u2014 every second candidate\n for (const uuid of [...this.#rootComponents.uuids]) {\n this.dispatchMessage(uuid, ComponentContext.ReRequestParentRoots);\n }\n }\n\n /**\n * Inform the children of `component` that they should re-request their parents.\n *\n * The receivers are the components hanging on `component` right now, and every one of them has\n * to let go: the message carries no sender and needs no filter, because there is nothing here to\n * decide. {@link ComponentContext.ReRequestParentRoots} is the signal for it \u2014 it means \"drop\n * your parent and ask again\", which is what the roots happen to be asked for most often, not\n * what it says.\n */\n dispatchReRequestParentChildren(component: ViewComponent) {\n // getChildren() hands out a fresh array, so a child that re-parents mid-loop cannot displace\n // the entry behind it\n for (const child of this.getChildren(component)) {\n this.dispatchMessage(child.uuid, ComponentContext.ReRequestParentRoots);\n }\n }\n\n /**\n * Inform the siblings of `component` that they should re-request their parents.\n *\n * This narrows the candidate set for one specific question: which components could have bound\n * to an ancestor further away than they should have, because `component` was not yet answering\n * when they asked? Such a component sits below `component` in the element tree and shares its\n * parent \u2014 any entity in between would have answered first. As long as `component` has no\n * parent of its own, the roots are that same set.\n *\n * The signal alone does not decide anything: the receiver re-asks, and whoever answers first\n * wins. Which components exist as candidates is what this method knows; whether one of them\n * really sits below `component` is settled on the receiving side, which is where the element\n * tree is visible \u2014 `data` is what carries the sender's identity there.\n *\n * The two signals differ in the order they work in, and that decides more than it looks like:\n * {@link ComponentContext.ReRequestParentRoots} releases the parent before asking, so a\n * component that gets the same answer back re-joins its parent's children at the end;\n * {@link ComponentContext.ReRequestParent} asks first and releases only where nobody answers,\n * which leaves every component that is already bound where it stands, order included.\n *\n * Delivery is immediate, and nothing inside the library calls it: like\n * {@link ComponentContext.dispatchReRequestParentRoots} it is public so that a round can be run\n * at a moment of one's own choosing.\n */\n dispatchReRequestParentSiblings(component: ViewComponent, data: unknown = undefined) {\n const parent = component.parent;\n if (parent == null) {\n this.dispatchReRequestParentRoots();\n return;\n }\n // getChildren() hands out a fresh array, so a child that re-parents mid-loop cannot displace\n // the entry behind it \u2014 unlike #rootComponents, which is the live list\n for (const child of this.getChildren(parent)) {\n if (child !== component) {\n this.dispatchMessage(child.uuid, ComponentContext.ReRequestParent, data);\n }\n }\n }\n\n /**\n * The peers waiting for a round: sender by sender in arrival order, each with the data the\n * round it asks for would carry.\n */\n #peerReRequests = new MicrotaskCollector<ViewComponent, unknown>((pending) => this.#deliverPeerReRequests(pending));\n\n /**\n * Take a peer re-request from `sender` \u2014 an entity that has just become one and may be the new\n * closest ancestor for entities that bound while it was not yet answering.\n *\n * Everything that arrives in the same task shares one round. Alone, each arrival is a broadcast\n * over the whole candidate set: the root channel carries no sender and has to ask every root,\n * the sibling channel asks every child of one parent. n entities coming up together then cost\n * n(n+1)/2 messages, and each message is a full ancestor request through the DOM \u2014 for 600 roots\n * in one namespace that is 180 300 messages and some 257 ms on top of a build that takes 42 ms\n * with the channel switched off. One round per task costs 600 messages and 2 ms on top. The\n * point where a round per arrival costs more than a frame lies at about 145 roots in one\n * namespace; one round per task stays clear of it over the whole measured range, up to 600.\n *\n * Numbers measured 2026-08-22 in Chromium via Playwright 1.62.1 \u2014 a snapshot, not a guarantee;\n * the size series is in `packages/shadow-objects/docs/guides.md`, under \"How Many Entities Fit\n * in One Namespace\".\n *\n * @param data travels with the round as long as `sender` is the only one in it \u2014 see\n * {@link ComponentContext.dispatchReRequestParentSiblings} for what a receiver does with it.\n *\n * @internal\n */\n collectPeerReRequest(sender: ViewComponent, data: unknown = undefined): void {\n this.#peerReRequests.add(sender, data);\n }\n\n /** Run the collected rounds, one per candidate set. */\n #deliverPeerReRequests(pending: Map<ViewComponent, unknown>): void {\n // the candidate set is decided here and not when the request came in: a sender's parent can\n // have been settled since, and a sender that has left this context in the meantime is a new\n // ancestor for nobody. `null` stands for the roots, which is the candidate set of a sender\n // without a parent\n const rounds = new Map<ViewComponent | null, {data: unknown}>();\n\n for (const [sender, data] of pending) {\n // membership, and #componentInstances is the only thing that answers it: an entry in\n // #components outlives the departure of its component until the next change trail, so a\n // lookup by uuid still hands back the sender that has left \u2014 and hands back the entry of a\n // namesake that took the uuid over. Both are the same mistake, a round for an ancestor that\n // is not there any more\n if (!this.#componentInstances.has(sender)) continue;\n\n const key = sender.parent ?? null;\n const round = rounds.get(key);\n if (round === undefined) {\n rounds.set(key, {data});\n } else {\n // `data` names one new ancestor and a receiver can only be filtered against one. Where\n // several senders share a candidate set, the round asks unconditionally \u2014 the wider\n // answer, and the one a receiver gives itself when it is told no ancestor at all.\n //\n // What decides this is the number of senders, not how they compare to the candidate set:\n // two elements inserted at runtime below six hundred siblings already cost six hundred\n // ascents instead of two. The filter is kept for the case that produces it \u2014 a single\n // element arriving on its own \u2014 and the round stays linear either way\n round.data = undefined;\n }\n }\n\n // one hand-over is one round, not one message: a round over the roots leaves this method as a\n // single call into dispatchReRequestParentRoots(). A receiver that throws costs nothing at all\n // -- `ViewComponent.dispatchEvent()` delivers each message under a guarded dispatch, so the\n // failure never reaches the round it belongs to. This guard is the backstop behind that, for\n // the round itself rather than its receivers: what fails while a round is being assembled\n // costs the rest of that round and none of the rounds behind it.\n for (const [parent, round] of rounds) {\n runGuarded(\n this.#logger,\n () => {\n if (parent == null) {\n this.dispatchReRequestParentRoots();\n } else {\n // the sender is asked along with the rest: a second sender of the same round can sit\n // above it, and an element never answers its own request \u2014 the message costs it one\n // ascent and can save it a wrong parent.\n // getChildren() hands out a fresh array, so a child that re-parents mid-loop cannot\n // displace the entry behind it\n for (const child of this.getChildren(parent)) {\n this.dispatchMessage(child.uuid, ComponentContext.ReRequestParent, round.data);\n }\n }\n },\n 'a peer re-request round could not be delivered:',\n parent?.uuid ?? 'roots',\n );\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 * @param commit whether the trail counts as applied the moment it is built. Pass `false` when\n * the trail still has to travel to a Shadow Environment that may refuse it, and settle it\n * afterwards with {@link ComponentContext.commitChangeTrail}.\n *\n * @see {@link ComponentContext.commitChangeTrail}\n * @see {@link ComponentContext.reCreateChanges}\n */\n buildChangeTrails(commit = true): ChangeTrailType {\n // a collected round settles where entities hang, and a trail built before it ran would carry\n // the hierarchy of a moment that is already over. Running it here makes that a rule rather\n // than a matter of which microtask happens to come first\n this.#peerReRequests.flush();\n\n if (this.#uncommittedTrail != null) {\n // Two sync cycles can be in flight at once, and the older one no longer has a trail to\n // settle once this one has taken the diff. It falls back on the optimistic reading --\n // everything it carried counts as applied -- rather than on a state in which two trails\n // claim the same entries.\n this.#logger.debug('committing an open change trail because a second one is being built', this.#uncommittedTrail.entries);\n this.commitChangeTrail(this.#uncommittedTrail.entries.length);\n }\n\n const entries: IComponentChangeType[] = [];\n const owners: ComponentChanges[] = [];\n const participants = this.hasComponents() ? this.#buildPathOfChanges() : [];\n\n // The entry \u2192 component assignment is taken from the length of the trail before and after\n // each call, which keeps it out of the entries themselves: they travel to the Shadow\n // Environment, and nothing that is only this side's bookkeeping belongs on that wire.\n const build = (changes: ComponentChanges, phase: ChangeTrailPhase) => {\n const before = entries.length;\n changes.buildChangeTrail(entries, phase);\n for (let i = before; i < entries.length; i++) {\n owners[i] = changes;\n }\n };\n\n for (const changes of participants) build(changes, ChangeTrailPhase.StructuralChanges);\n for (const changes of participants) build(changes, ChangeTrailPhase.ContentUpdates);\n for (const changes of participants) build(changes, ChangeTrailPhase.Removal);\n\n // read while the build still stands: whether a component is spent is a statement about this\n // trail, and the round trip that follows must not be able to change the answer\n this.#uncommittedTrail = {entries, owners, retiring: this.#retiringComponents(participants)};\n\n if (commit) this.commitChangeTrail(entries.length);\n\n return entries;\n }\n\n /**\n * Fold the first `appliedCount` entries of the change trail this context built last into the\n * state the next trail is diffed against, and write them to the Component Memory. Every entry\n * behind that line stays pending and goes out again with the next trail.\n *\n * A component is retired -- its entry dropped -- only where the build read it as spent and every\n * entry it contributed is settled. One component can hold a creation and an event in the same\n * trail, and a creation sent twice is refused by the Shadow Environment, which already holds an\n * entity behind that uuid.\n *\n * @param appliedCount how many entries the Shadow Environment applied, counted from the front.\n * Clamped to the length of the trail.\n * @param changeTrail the trail this call settles. Given, the call is ignored unless it is the\n * very trail this context built last -- a cycle that lost its trail to a later build must not\n * draw a line through that later trail.\n */\n commitChangeTrail(appliedCount: number, changeTrail?: ChangeTrailType): void {\n const uncommitted = this.#uncommittedTrail;\n if (uncommitted == null) return;\n if (changeTrail != null && changeTrail !== uncommitted.entries) return;\n\n const {entries, owners, retiring} = uncommitted;\n const count = Math.min(Math.max(appliedCount, 0), entries.length);\n\n // released before anything is folded: a listener reached from here finds no half-settled record\n this.#uncommittedTrail = undefined;\n\n const stillPending = new Set(owners.slice(count));\n\n for (let i = 0; i < count; i++) {\n // `count` is clamped to `entries.length`, and `build()` above assigns an owner for every\n // index `entries` gains, so both arrays hold an entry at `i`.\n owners[i]!.commitChange(entries[i]!);\n }\n\n this.#componentMemory.write(count === entries.length ? entries : entries.slice(0, count));\n\n this.#retireComponents(retiring, stillPending);\n }\n\n /**\n * Whether the Component Memory holds a state for `uuid` \u2014 the state\n * {@link ComponentContext.reCreateChanges} would rebuild that component from.\n */\n hasComponentState(uuid: string): boolean {\n return this.#componentMemory.hasComponentState(uuid);\n }\n\n /**\n * The state the Component Memory holds for `uuid`, or `undefined` where it holds none.\n *\n * A snapshot, not the record: the property list of the record is rewritten in place as\n * trails come in, so a caller holding on to it would be reading a moving value \u2014 or\n * writing one. What it is a snapshot of is the memory at the moment of the call, and the\n * memory moves under several hands: {@link ComponentContext.commitChangeTrail} folds a\n * settled trail into it, {@link ComponentContext.buildChangeTrails} does the same for the\n * trail it builds unless it is told not to commit, {@link ComponentContext.reCreateChanges}\n * writes the trail it builds and empties the memory afterwards, and\n * {@link ComponentContext.clear} empties it outright. A snapshot taken before any of those\n * describes a state that is over; take it again to see the current one.\n *\n * This is the window a test or a diagnosis needs, and the one that leaves the context as it\n * found it \u2014 reading the same thing out of {@link ComponentContext.reCreateChanges} costs a\n * rebuild of every component in the namespace.\n */\n getComponentState(uuid: string): ComponentState | undefined {\n const state = this.#componentMemory.getComponentState(uuid);\n if (state === undefined) return undefined;\n return {\n ...state,\n properties: state.properties?.map((entry) => (entry.length === 1 ? [entry[0]] : [entry[0], entry[1]])),\n };\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 * The trail this produces belongs to a Shadow Environment that holds none of these uuids -- a\n * fresh proxy. One whose Kernel still holds them refuses the first re-created creation it reads,\n * and every cycle that follows, because a uuid names one entity at a time.\n *\n * @see {@link ComponentContext.buildChangeTrails}\n */\n reCreateChanges() {\n if (this.#componentMemory.isEmpty()) return;\n\n const trails = this.buildChangeTrails(false);\n\n // The trail is written to the memory but not folded back into the components: the recreation\n // below builds every one of them anew and needs the events of the instances it replaces, which\n // a commit would release. What the trail retires is retired here instead.\n this.#componentMemory.write(trails);\n this.#retireBuiltTrail();\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 entry of cMem.properties) {\n const key = entry[0];\n // the arity decides: a one-element entry is a property that is set without a value, and\n // reading it as `[key, undefined]` would hand a removal to a component that has nothing\n // to remove -- the key would fall out of the rebuild without a word\n if (entry.length === 1) {\n changes.setPropertyWithoutValue(key);\n } else {\n changes.changeProperty(key, entry[1], c.propIsEqual?.get(key));\n }\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. Every\n * {@link ViewComponent} this context holds is destroyed, so each of them reports\n * {@link ViewComponent#isDestroyed} and holds no context afterwards. The context itself stays\n * registered under its namespace and can be used again \u2014 assigning it to a component takes\n * that component back in under the same uuid.\n *\n * @see {@link ComponentContext.dispose} for the final teardown\n */\n clear() {\n this.#viewInstances = undefined;\n this.#componentMemory.clear();\n this.#uncommittedTrail = undefined;\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 // The members are what this set holds, and walking #components instead would reach past them:\n // an entry outlives the departure of its component until the next change trail\n for (const component of Array.from(this.#componentInstances)) {\n component.destroy();\n }\n\n // a safety net, not currently reachable: every instance the loop above destroys takes\n // itself out of this set on the way through destroyComponent(), so it should already be\n // empty here. Kept for the same reason as the two panics below \u2014 a future call path that\n // adds to this set during its own teardown must not leave anything past the sweep\n this.#componentInstances.clear();\n\n for (const uuid of [...this.#rootComponents.uuids]) {\n this.removeSubTree(uuid);\n }\n\n if (this.#rootComponents.size !== 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 `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 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 /**\n * Drop the component entry behind `uuid`, and with it the uuid's place in every children list.\n *\n * @param expectedChanges the bookkeeping that asked for the deletion. A round trip lies between\n * the build of a change trail and its commit, and an entry that a different bookkeeping stands\n * behind by then belongs to a component that joined in the meantime.\n */\n #deleteComponent(uuid: string, expectedChanges?: ComponentChanges) {\n const entry = this.#components.get(uuid);\n if (entry === undefined) return;\n if (expectedChanges !== undefined && entry.changes !== expectedChanges) 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 parentEntry.children.delete(uuid);\n }\n }\n\n this.#components.delete(uuid);\n this.#rootComponents.delete(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 * Two questions decide what one insertion costs, and a list that carries nothing but its uuids\n * has to be walked for both: once to see whether the uuid already stands in it, once to find the\n * place it sorts into. Filling such a list with n components costs n(n+1)/2 steps. `OrderedUuids`\n * answers the membership in one step, and the shortcut below answers the place in one more for\n * every component that sorts at or after the last member; a component that sorts ahead of it\n * still walks the list. Building n roots one after another, all on the default order, that is\n * 1.01 ms for 600 and 2.03 ms for 1200, against 4.44 ms and 16.04 ms for the walked list.\n * Numbers measured 2026-08-31 on node v25.9.0, on the context alone with no DOM around\n * it -- a snapshot, not a guarantee. The parent-resolution series in\n * `packages/shadow-objects/docs/guides.md` was measured in a browser and covers a different question.\n */\n #appendToOrdered(component: ViewComponent, childUuids: OrderedUuids) {\n if (childUuids.has(component.uuid)) {\n return;\n }\n\n const {order} = component;\n\n // The list is sorted by ascending order, so a component that sorts at or after its last member\n // sorts after every one of them: the scan below would walk to the end and push. Asking the last\n // member first turns the common case -- children arriving in document order, all on the default\n // order -- from a walk over the whole list into a single lookup. A last uuid whose entry is\n // already gone answers nothing, and then the scan runs as it did.\n const last = childUuids.size > 0 ? this.#components.get(childUuids.uuids[childUuids.size - 1]!)?.component : undefined;\n if (last !== undefined && order >= last.order) {\n childUuids.push(component.uuid);\n return;\n }\n\n for (let i = 0; i < childUuids.size; i++) {\n const other = this.#components.get(childUuids.uuids[i]!)?.component;\n if (other !== undefined && order < other.order) {\n childUuids.insertAt(i, component.uuid);\n return;\n }\n }\n\n childUuids.push(component.uuid);\n }\n\n #viewInstances?: ViewInstance[] | undefined;\n\n #traverseLevelOrderBFS(): ViewInstance[] {\n if (this.#viewInstances) return this.#viewInstances;\n\n const lvl = new Map<number, ViewInstance[]>();\n\n // The same set `#removeSubTree()` keeps, for the same reason: `addToChildren()` writes a children\n // list without taking the child out of the one it already stands in, so a component can be reached\n // twice and a children list can point back at an ancestor.\n const visited = new Set<string>();\n\n const traverse = (uuid: string, depth: number) => {\n if (visited.has(uuid)) return;\n visited.add(uuid);\n\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.uuids) {\n traverse(childUuid, depth + 1);\n }\n };\n\n for (const uuid of this.#rootComponents.uuids) {\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}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ComponentPropertiesType } from '../types.js';
|
|
2
2
|
export interface ComponentState {
|
|
3
3
|
token: string;
|
|
4
|
-
parentUuid?: string;
|
|
5
|
-
order
|
|
6
|
-
properties?: ComponentPropertiesType;
|
|
4
|
+
parentUuid?: string | undefined;
|
|
5
|
+
order: number;
|
|
6
|
+
properties?: ComponentPropertiesType | undefined;
|
|
7
7
|
autoDestructionOnParentRemoval?: boolean;
|
|
8
8
|
}
|
|
9
9
|
//# sourceMappingURL=ComponentMemory.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComponentMemory.d.ts","sourceRoot":"","sources":["../../../src/view/ComponentMemory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,uBAAuB,EAQxB,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ComponentMemory.d.ts","sourceRoot":"","sources":["../../../src/view/ComponentMemory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,uBAAuB,EAQxB,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;IACjD,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAC1C"}
|
|
@@ -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
|
|
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 | undefined;\n order: number;\n properties?: ComponentPropertiesType | undefined;\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}\n"],
|
|
5
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
|
}
|
|
@@ -3,14 +3,40 @@ import type { ChangeTrailType } from '../types.js';
|
|
|
3
3
|
export interface IShadowObjectEnvProxy {
|
|
4
4
|
start(): Promise<void>;
|
|
5
5
|
importScript(url: URL | string): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Hand a change trail to the Shadow Environment behind this proxy.
|
|
8
|
+
*
|
|
9
|
+
* An implementation that can say how far the Kernel got before it stopped rejects with a
|
|
10
|
+
* `ChangeTrailRefusedError`: its `appliedCount` names the length of the prefix the Kernel
|
|
11
|
+
* applied, and `ShadowEnv` folds exactly that prefix into its bookkeeping and sends the
|
|
12
|
+
* rest again with the next trail.
|
|
13
|
+
*
|
|
14
|
+
* Every other reason is read as "the whole trail counts as applied" -- a confirmation window
|
|
15
|
+
* that ran out or a proxy that says nothing about its Kernel leaves an environment that may
|
|
16
|
+
* well hold all of it, and a creation sent a second time to a Kernel that holds the entity is
|
|
17
|
+
* refused, so a trail kept pending on a guess would come back to that refusal cycle after
|
|
18
|
+
* cycle. An implementation that has always rejected with something else therefore keeps
|
|
19
|
+
* behaving exactly as it did.
|
|
20
|
+
*
|
|
21
|
+
* @param waitForConfirmation whether the caller waits for the environment to confirm the trail.
|
|
22
|
+
* A proxy that can only report a refusal on the confirmed route says nothing about a trail
|
|
23
|
+
* sent without it -- `RemoteWorkerEnv` is one of those.
|
|
24
|
+
*/
|
|
6
25
|
applyChangeTrail(data: ChangeTrailType, waitForConfirmation: boolean): Promise<void>;
|
|
7
26
|
destroy(): void;
|
|
8
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Called with a message on its way out of the Shadow Environment.
|
|
29
|
+
* `ShadowEnv` installs it on every proxy it is given and takes it back off a proxy
|
|
30
|
+
* it lets go -- one microtask after that proxy's `destroy()` has returned, so that what an
|
|
31
|
+
* `onDestroy` hands to the view during the teardown still arrives.
|
|
32
|
+
*/
|
|
33
|
+
onMessageToView?: ((event: Omit<MessageToViewEvent, 'transferables'>) => any) | undefined;
|
|
9
34
|
/**
|
|
10
35
|
* Called when the proxy has irrecoverably lost the environment it stands for.
|
|
11
|
-
*
|
|
36
|
+
* `ShadowEnv` installs it on every proxy it is given and takes it back off a proxy
|
|
37
|
+
* it lets go, the moment that proxy's `destroy()` has returned; an implementation
|
|
12
38
|
* that cannot fail simply never calls it.
|
|
13
39
|
*/
|
|
14
|
-
onProxyFailed?: (reason: unknown) => any;
|
|
40
|
+
onProxyFailed?: ((reason: unknown) => any) | undefined;
|
|
15
41
|
}
|
|
16
42
|
//# 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;;;;;;;;;;;;;;;;;;OAkBG;IACH,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,mBAAmB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErF,OAAO,IAAI,IAAI,CAAC;IAEhB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,eAAe,CAAC,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC;IAE1F;;;;;OAKG;IACH,aAAa,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC;CACxD"}
|
|
@@ -10,7 +10,7 @@ export declare class LocalShadowObjectEnv implements IShadowObjectEnvProxy {
|
|
|
10
10
|
disableStructuredClone: boolean;
|
|
11
11
|
constructor(registry?: Registry);
|
|
12
12
|
start(): Promise<void>;
|
|
13
|
-
applyChangeTrail(data: ChangeTrailType,
|
|
13
|
+
applyChangeTrail(data: ChangeTrailType, waitForConfirmation: boolean): Promise<void>;
|
|
14
14
|
importScript(url: URL | string): Promise<void>;
|
|
15
15
|
importModule(module: ShadowObjectsModule): Promise<void>;
|
|
16
16
|
destroy(): void;
|
|
@@ -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,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;
|
|
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;IAE/B,YAAY,QAAQ,CAAC,EAAE,QAAQ,EAqB9B;IAED,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAErB;IAED,gBAAgB,CAAC,IAAI,EAAE,eAAe,EAAE,mBAAmB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBnF;IAEK,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQnD;IAEK,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7D;IAED,OAAO,IAAI,IAAI,CAMd;CACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { on } from "@spearwolf/eventize";
|
|
2
2
|
import { MessageToView, ShadowObjectsExport } from "../constants.js";
|
|
3
|
-
import { importModule } from "../in-the-dark/importModule.js";
|
|
3
|
+
import { importModule, missingShadowObjectsExportMessage } from "../in-the-dark/importModule.js";
|
|
4
4
|
import { Kernel } from "../in-the-dark/Kernel.js";
|
|
5
5
|
import { Registry } from "../in-the-dark/Registry.js";
|
|
6
6
|
import { toUrlString } from "../utils/toUrlString.js";
|
|
@@ -16,7 +16,7 @@ class LocalShadowObjectEnv {
|
|
|
16
16
|
const onMessageToView = this.onMessageToView;
|
|
17
17
|
if (onMessageToView == null) return;
|
|
18
18
|
const { type, uuid, traverseChildren } = message;
|
|
19
|
-
const data = structuredClone(message.data, { transfer: message.transferables });
|
|
19
|
+
const data = structuredClone(message.data, { transfer: message.transferables ?? [] });
|
|
20
20
|
onMessageToView.call(this, { type, uuid, data, traverseChildren });
|
|
21
21
|
});
|
|
22
22
|
}
|
|
@@ -28,7 +28,7 @@ class LocalShadowObjectEnv {
|
|
|
28
28
|
start() {
|
|
29
29
|
return Promise.resolve();
|
|
30
30
|
}
|
|
31
|
-
applyChangeTrail(data,
|
|
31
|
+
applyChangeTrail(data, waitForConfirmation) {
|
|
32
32
|
const syncData = { changeTrail: this.disableStructuredClone ? data : cloneChangeTrail(data) };
|
|
33
33
|
let result;
|
|
34
34
|
try {
|
|
@@ -37,16 +37,18 @@ class LocalShadowObjectEnv {
|
|
|
37
37
|
} catch (error) {
|
|
38
38
|
result = Promise.reject(error);
|
|
39
39
|
}
|
|
40
|
-
return result;
|
|
40
|
+
if (!waitForConfirmation) return result;
|
|
41
|
+
return result.then(() => void 0);
|
|
41
42
|
}
|
|
42
43
|
async importScript(url) {
|
|
43
44
|
const module = await import(
|
|
44
45
|
/* @vite-ignore */
|
|
45
46
|
toUrlString(url)
|
|
46
47
|
);
|
|
47
|
-
if (module[ShadowObjectsExport]) {
|
|
48
|
-
|
|
48
|
+
if (!module[ShadowObjectsExport]) {
|
|
49
|
+
throw new Error(missingShadowObjectsExportMessage);
|
|
49
50
|
}
|
|
51
|
+
await this.importModule(module[ShadowObjectsExport]);
|
|
50
52
|
}
|
|
51
53
|
async importModule(module) {
|
|
52
54
|
return importModule(this.kernel, module, this.#importedModules);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/view/LocalShadowObjectEnv.ts"],
|
|
4
|
-
"sourcesContent": ["import {on} from '@spearwolf/eventize';\nimport {MessageToView, ShadowObjectsExport} from '../constants.js';\nimport {importModule} from '../in-the-dark/importModule.js';\nimport {Kernel, type MessageToViewEvent} from '../in-the-dark/Kernel.js';\nimport {Registry} from '../in-the-dark/Registry.js';\nimport type {ChangeTrailType, ShadowObjectsModule, SyncEvent} from '../types.js';\nimport {toUrlString} from '../utils/toUrlString.js';\nimport {cloneChangeTrail} from './cloneChangeTrail.js';\nimport type {IShadowObjectEnvProxy} from './IShadowObjectEnvProxy.js';\n\nexport class LocalShadowObjectEnv implements IShadowObjectEnvProxy {\n #importedModules: Set<ShadowObjectsModule> = new Set();\n readonly #usesDefaultRegistry: boolean;\n\n readonly kernel: Kernel;\n\n get registry(): Registry {\n return this.kernel.registry;\n }\n\n readonly isLocalEnv = true;\n\n disableStructuredClone = false;\n\n constructor(registry?: Registry) {\n this.kernel = new Kernel(registry);\n // The default registry is shared with every other environment in this thread and holds\n // everything `@ShadowObject` and `shadowObjects.define()` register without a registry of\n // their own, so `destroy()` must not clear it. This check only tells the default registry\n // apart from any other instance \u2014 a custom registry handed to more than one environment is\n // cleared by the first one of them to be destroyed, same as the default registry would be\n // without this guard.\n this.#usesDefaultRegistry = this.kernel.registry === Registry.get();\n\n on(this.kernel, MessageToView, (message: MessageToViewEvent) => {\n const onMessageToView = (this as IShadowObjectEnvProxy).onMessageToView;\n if (onMessageToView == null) return;\n\n const {type, uuid, traverseChildren} = message;\n const data = structuredClone(message.data, {transfer: message.transferables});\n // call() keeps the binding a plain method call would have given it: an outside\n // implementation of the proxy interface need not hand over a bound callback\n onMessageToView.call(this, {type, uuid, data, traverseChildren});\n });\n }\n\n start(): Promise<void> {\n return Promise.resolve();\n }\n\n applyChangeTrail(data: ChangeTrailType,
|
|
5
|
-
"mappings": "AAAA,SAAQ,UAAS;AACjB,SAAQ,eAAe,2BAA0B;AACjD,SAAQ,
|
|
4
|
+
"sourcesContent": ["import {on} from '@spearwolf/eventize';\nimport {MessageToView, ShadowObjectsExport} from '../constants.js';\nimport {importModule, missingShadowObjectsExportMessage} from '../in-the-dark/importModule.js';\nimport {Kernel, type MessageToViewEvent} from '../in-the-dark/Kernel.js';\nimport {Registry} from '../in-the-dark/Registry.js';\nimport type {ChangeTrailType, ShadowObjectsModule, SyncEvent} from '../types.js';\nimport {toUrlString} from '../utils/toUrlString.js';\nimport {cloneChangeTrail} from './cloneChangeTrail.js';\nimport type {IShadowObjectEnvProxy} from './IShadowObjectEnvProxy.js';\n\nexport class LocalShadowObjectEnv implements IShadowObjectEnvProxy {\n #importedModules: Set<ShadowObjectsModule> = new Set();\n readonly #usesDefaultRegistry: boolean;\n\n readonly kernel: Kernel;\n\n get registry(): Registry {\n return this.kernel.registry;\n }\n\n readonly isLocalEnv = true;\n\n disableStructuredClone = false;\n\n constructor(registry?: Registry) {\n this.kernel = new Kernel(registry);\n // The default registry is shared with every other environment in this thread and holds\n // everything `@ShadowObject` and `shadowObjects.define()` register without a registry of\n // their own, so `destroy()` must not clear it. This check only tells the default registry\n // apart from any other instance \u2014 a custom registry handed to more than one environment is\n // cleared by the first one of them to be destroyed, same as the default registry would be\n // without this guard.\n this.#usesDefaultRegistry = this.kernel.registry === Registry.get();\n\n on(this.kernel, MessageToView, (message: MessageToViewEvent) => {\n const onMessageToView = (this as IShadowObjectEnvProxy).onMessageToView;\n if (onMessageToView == null) return;\n\n const {type, uuid, traverseChildren} = message;\n // WebIDL defaults `transfer` to `[]`, so a missing key and an empty list are the same call.\n const data = structuredClone(message.data, {transfer: message.transferables ?? []});\n // call() keeps the binding a plain method call would have given it: an outside\n // implementation of the proxy interface need not hand over a bound callback\n onMessageToView.call(this, {type, uuid, data, traverseChildren});\n });\n }\n\n start(): Promise<void> {\n return Promise.resolve();\n }\n\n applyChangeTrail(data: ChangeTrailType, waitForConfirmation: boolean): Promise<void> {\n const syncData: SyncEvent = {changeTrail: this.disableStructuredClone ? data : cloneChangeTrail(data)};\n let result: Promise<void>;\n try {\n this.kernel.run(syncData);\n result = Promise.resolve();\n } catch (error) {\n result = Promise.reject(error);\n }\n if (!waitForConfirmation) return result;\n // The kernel above still runs synchronously, in the same tick this method is called in; only\n // the settling of the returned promise is deferred here, by one microtask, so it never\n // settles in the same microtask as the call that made it. That is the guarantee this gives \u2014\n // not the same relative ordering RemoteWorkerEnv has against its own promises, which settles\n // only after its worker round-trip and can land later still.\n return result.then(() => undefined);\n }\n\n async importScript(url: URL | string): Promise<void> {\n const module = await import(/* @vite-ignore */ toUrlString(url));\n // A module without this export is wrong in both environments, and a local run rejects it\n // right here instead of staying quiet -- so a developer sees it before switching to a worker.\n if (!module[ShadowObjectsExport]) {\n throw new Error(missingShadowObjectsExportMessage);\n }\n await this.importModule(module[ShadowObjectsExport]);\n }\n\n async importModule(module: ShadowObjectsModule): Promise<void> {\n return importModule(this.kernel, module, this.#importedModules);\n }\n\n destroy(): void {\n this.kernel.destroy();\n if (!this.#usesDefaultRegistry) {\n this.registry.clear();\n }\n this.#importedModules.clear();\n }\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAQ,UAAS;AACjB,SAAQ,eAAe,2BAA0B;AACjD,SAAQ,cAAc,yCAAwC;AAC9D,SAAQ,cAAsC;AAC9C,SAAQ,gBAAe;AAEvB,SAAQ,mBAAkB;AAC1B,SAAQ,wBAAuB;AAGxB,MAAM,qBAAsD;AAAA,EAcjE,YAAY,UAAqB;AAbjC,4BAA6C,oBAAI,IAAI;AASrD,SAAS,aAAa;AAEtB,kCAAyB;AAGvB,SAAK,SAAS,IAAI,OAAO,QAAQ;AAOjC,SAAK,uBAAuB,KAAK,OAAO,aAAa,SAAS,IAAI;AAElE,OAAG,KAAK,QAAQ,eAAe,CAAC,YAAgC;AAC9D,YAAM,kBAAmB,KAA+B;AACxD,UAAI,mBAAmB,KAAM;AAE7B,YAAM,EAAC,MAAM,MAAM,iBAAgB,IAAI;AAEvC,YAAM,OAAO,gBAAgB,QAAQ,MAAM,EAAC,UAAU,QAAQ,iBAAiB,CAAC,EAAC,CAAC;AAGlF,sBAAgB,KAAK,MAAM,EAAC,MAAM,MAAM,MAAM,iBAAgB,CAAC;AAAA,IACjE,CAAC;AAAA,EACH;AAAA,EAlCA;AAAA,EACS;AAAA,EAIT,IAAI,WAAqB;AACvB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EA6BA,QAAuB;AACrB,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAAA,EAEA,iBAAiB,MAAuB,qBAA6C;AACnF,UAAM,WAAsB,EAAC,aAAa,KAAK,yBAAyB,OAAO,iBAAiB,IAAI,EAAC;AACrG,QAAI;AACJ,QAAI;AACF,WAAK,OAAO,IAAI,QAAQ;AACxB,eAAS,QAAQ,QAAQ;AAAA,IAC3B,SAAS,OAAO;AACd,eAAS,QAAQ,OAAO,KAAK;AAAA,IAC/B;AACA,QAAI,CAAC,oBAAqB,QAAO;AAMjC,WAAO,OAAO,KAAK,MAAM,MAAS;AAAA,EACpC;AAAA,EAEA,MAAM,aAAa,KAAkC;AACnD,UAAM,SAAS,MAAM;AAAA;AAAA,MAA0B,YAAY,GAAG;AAAA;AAG9D,QAAI,CAAC,OAAO,mBAAmB,GAAG;AAChC,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,UAAM,KAAK,aAAa,OAAO,mBAAmB,CAAC;AAAA,EACrD;AAAA,EAEA,MAAM,aAAa,QAA4C;AAC7D,WAAO,aAAa,KAAK,QAAQ,QAAQ,KAAK,gBAAgB;AAAA,EAChE;AAAA,EAEA,UAAgB;AACd,SAAK,OAAO,QAAQ;AACpB,QAAI,CAAC,KAAK,sBAAsB;AAC9B,WAAK,SAAS,MAAM;AAAA,IACtB;AACA,SAAK,iBAAiB,MAAM;AAAA,EAC9B;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -17,6 +17,43 @@ export declare class WorkerFailedError extends Error {
|
|
|
17
17
|
export declare class WorkerDestroyedError extends Error {
|
|
18
18
|
constructor(message?: string);
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* The reason a request is rejected with when the worker reported a failure of its own -- a
|
|
22
|
+
* module that would not import, a change trail its Kernel refused. An error does not survive
|
|
23
|
+
* structured cloning as the object it is, so the two fields that do are rebuilt here, and
|
|
24
|
+
* `name` is the name the error called itself inside the worker: a caller reads it the same
|
|
25
|
+
* way it reads the name of an error a `LocalShadowObjectEnv` hands it. A name that is missing
|
|
26
|
+
* or empty names no class, and `Error` is what such a reason is called -- the same name a
|
|
27
|
+
* plain `new Error(message)` carries on the local side.
|
|
28
|
+
*
|
|
29
|
+
* What does not come across is the class and everything it added. `instanceof EntityUuidInUseError`
|
|
30
|
+
* is `false` here and there is no `uuid` field, whatever `name` says; `instanceof WorkerReportedError`
|
|
31
|
+
* is what tells such a reason apart from one raised on this side.
|
|
32
|
+
*/
|
|
33
|
+
export declare class WorkerReportedError extends Error {
|
|
34
|
+
constructor(name: string | undefined, message: string);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* How long a {@link RemoteWorkerEnv} waits for each of the four replies a worker owes it,
|
|
38
|
+
* in milliseconds.
|
|
39
|
+
*/
|
|
40
|
+
export interface WorkerTimeouts {
|
|
41
|
+
/** the `Loaded` handshake at the start */
|
|
42
|
+
loadTimeout: number;
|
|
43
|
+
/** the `ImportedModule` reply to an `importScript()` */
|
|
44
|
+
configureTimeout: number;
|
|
45
|
+
/** the `AppliedChangeTrail` confirmation of a change trail sent with `waitForConfirmation` */
|
|
46
|
+
changeTrailTimeout: number;
|
|
47
|
+
/** the `Destroyed` acknowledgement of a teardown */
|
|
48
|
+
destroyTimeout: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* What {@link RemoteWorkerEnv} takes. Every value left out keeps its default — the four
|
|
52
|
+
* `Worker*Timeout` constants. A value that is not a number of milliseconds from 1 to
|
|
53
|
+
* 2147483647 — close to 25 days, the longest delay a timer keeps — is reported through the
|
|
54
|
+
* logger and the default applies.
|
|
55
|
+
*/
|
|
56
|
+
export type RemoteWorkerEnvOptions = Partial<WorkerTimeouts>;
|
|
20
57
|
/** What {@link RemoteWorkerEnv.WorkerFailed} carries. */
|
|
21
58
|
export interface WorkerFailedEvent {
|
|
22
59
|
/** the environment whose worker failed */
|
|
@@ -34,7 +71,14 @@ export declare class RemoteWorkerEnv implements IShadowObjectEnvProxy {
|
|
|
34
71
|
#private;
|
|
35
72
|
static WorkerLoaded: string;
|
|
36
73
|
static WorkerFailed: string;
|
|
37
|
-
|
|
74
|
+
/** The logger this environment reports through. */
|
|
75
|
+
get logger(): ConsoleLogger;
|
|
76
|
+
/**
|
|
77
|
+
* The four timeouts this environment holds itself to, resolved once when it is built. The
|
|
78
|
+
* object is frozen and the slot holds no setter, so the constructor is the one way in --
|
|
79
|
+
* and `resolveTimeouts()` vets every value that goes through it.
|
|
80
|
+
*/
|
|
81
|
+
get timeouts(): Readonly<WorkerTimeouts>;
|
|
38
82
|
get isDestroyed(): boolean;
|
|
39
83
|
/**
|
|
40
84
|
* Resolves once the worker is up.
|
|
@@ -44,17 +88,57 @@ export declare class RemoteWorkerEnv implements IShadowObjectEnvProxy {
|
|
|
44
88
|
* `catch()` — otherwise a worker failure surfaces as an unhandled rejection.
|
|
45
89
|
*
|
|
46
90
|
* @throws {WorkerFailedError} if the worker fails before or after that happens
|
|
91
|
+
* @throws {WorkerDestroyedError} once the environment has been torn down — including every
|
|
92
|
+
* read after a load that had already succeeded, because there is no environment left to hand out
|
|
47
93
|
*/
|
|
48
94
|
get workerLoaded(): Promise<RemoteWorkerEnv>;
|
|
49
|
-
constructor();
|
|
95
|
+
constructor(options?: RemoteWorkerEnvOptions);
|
|
50
96
|
start(): Promise<void>;
|
|
51
97
|
applyChangeTrail(changeTrail: ChangeTrailType, waitForConfirmation: boolean): Promise<void>;
|
|
52
98
|
importScript(url: URL | string): Promise<void>;
|
|
53
99
|
destroy(): void;
|
|
54
|
-
private onWorkerError;
|
|
55
|
-
private onWorkerMessageError;
|
|
100
|
+
private readonly onWorkerError;
|
|
101
|
+
private readonly onWorkerMessageError;
|
|
56
102
|
private handleWorkerFailure;
|
|
57
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Announces the completed handshake to the consumers.
|
|
105
|
+
*
|
|
106
|
+
* `emitStrict()` rather than `emit()`, and the retain policy is what decides it. `workerLoaded`
|
|
107
|
+
* reads the retained value, and eventize writes that value only once the dispatch has run
|
|
108
|
+
* through: under the plain dispatch a single listener that throws would take the replay for
|
|
109
|
+
* every later subscriber with it, and every later read of `workerLoaded` would wait for a
|
|
110
|
+
* failure or a teardown instead of resolving. The guarded dispatch serves every listener and
|
|
111
|
+
* writes the retained value, because the event was delivered.
|
|
112
|
+
*
|
|
113
|
+
* What the listeners threw arrives here afterwards -- one of them unchanged, several as an
|
|
114
|
+
* `AggregateError` in dispatch order -- and is reported. It goes no further: this runs from a
|
|
115
|
+
* microtask, where a throw has no caller left to reach and would surface as an unhandled error.
|
|
116
|
+
*/
|
|
117
|
+
private announceLoaded;
|
|
118
|
+
/**
|
|
119
|
+
* Announces the failure to the consumers. The same guarded dispatch as
|
|
120
|
+
* {@link RemoteWorkerEnv.announceLoaded}, for the same reason: `WorkerFailed` is documented as
|
|
121
|
+
* retained, and a consumer that subscribes only after the failure has to be able to hear about
|
|
122
|
+
* it. Every listener is served, the retained value is written, and whatever was thrown is
|
|
123
|
+
* reported here and reaches no caller.
|
|
124
|
+
*/
|
|
125
|
+
private announceFailure;
|
|
126
|
+
private readonly onMessageFromWorker;
|
|
127
|
+
/**
|
|
128
|
+
* Takes every listener of this environment off a worker. Whoever registered them takes them
|
|
129
|
+
* off again -- between the teardown and the `terminate()` that ends it the worker stays
|
|
130
|
+
* alive, and through its listeners it keeps this environment and everything it references
|
|
131
|
+
* reachable for exactly that long.
|
|
132
|
+
*/
|
|
133
|
+
private stopListeningTo;
|
|
58
134
|
private configureConsoleLogger;
|
|
135
|
+
/**
|
|
136
|
+
* The console-logger config for the worker, read from the storage key this environment
|
|
137
|
+
* announces. The key is a diagnostic switch, set by hand and sharing its namespace with
|
|
138
|
+
* everything else on this origin, so its content decides nothing about whether the worker
|
|
139
|
+
* comes up: anything that is not a plain JSON object counts as no config at all, exactly
|
|
140
|
+
* like an absent key.
|
|
141
|
+
*/
|
|
142
|
+
private readWorkerConfig;
|
|
59
143
|
}
|
|
60
144
|
//# sourceMappingURL=RemoteWorkerEnv.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemoteWorkerEnv.d.ts","sourceRoot":"","sources":["../../../src/view/RemoteWorkerEnv.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RemoteWorkerEnv.d.ts","sourceRoot":"","sources":["../../../src/view/RemoteWorkerEnv.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAA0B,eAAe,EAAoD,MAAM,aAAa,CAAC;AAC7H,OAAO,EAAiB,aAAa,EAAkD,MAAM,2BAA2B,CAAC;AAGzH,OAAO,KAAK,EAAC,qBAAqB,EAAC,MAAM,4BAA4B,CAAC;AA8CtE;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,sHAAsH;IACtH,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC;IAExC,YAAY,IAAI,EAAE,OAAO,GAAG,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAIlF;CACF;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAO,SAA8C,EAGhE;CACF;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,EAGpD;CACF;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,gBAAgB,EAAE,MAAM,CAAC;IACzB,8FAA8F;IAC9F,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oDAAoD;IACpD,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;AAyC7D,yDAAyD;AACzD,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,GAAG,EAAE,eAAe,CAAC;IACrB,+BAA+B;IAC/B,IAAI,EAAE,OAAO,GAAG,cAAc,CAAC;IAC/B,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,MAAM,EAAE,iBAAiB,CAAC;IAC1B,iDAAiD;IACjD,KAAK,EAAE,UAAU,GAAG,YAAY,CAAC;CAClC;AAED,qBAAa,eAAgB,YAAW,qBAAqB;;IAC3D,MAAM,CAAC,YAAY,SAAkB;IACrC,MAAM,CAAC,YAAY,SAAkB;IAgBrC,mDAAmD;IACnD,IAAI,MAAM,IAAI,aAAa,CAE1B;IAID;;;;OAIG;IACH,IAAI,QAAQ,IAAI,QAAQ,CAAC,cAAc,CAAC,CAEvC;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;;;;;;;;OAUG;IACH,IAAI,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC,CA4B3C;IAED,YAAY,OAAO,CAAC,EAAE,sBAAsB,EAO3C;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA6D3B;IAED,gBAAgB,CAAC,WAAW,EAAE,eAAe,EAAE,mBAAmB,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA6C1F;IAED,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB7C;IAED,OAAO,IAAI,IAAI,CA8Bd;IAED,OAAO,CAAC,QAAQ,CAAC,aAAa,CAE5B;IAEF,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAEnC;IAEF,OAAO,CAAC,mBAAmB;IAkC3B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,cAAc;IAQtB;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAMlC;IAEF;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,sBAAsB;IAkB9B;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;CAoBzB"}
|