@spearwolf/shadow-objects 0.32.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.
Files changed (213) hide show
  1. package/CHANGELOG.md +333 -10
  2. package/README.md +100 -20
  3. package/bundle.js +5 -54
  4. package/package.json +7 -3
  5. package/src/ChangeTrailRefusedError.d.ts +27 -0
  6. package/src/ChangeTrailRefusedError.d.ts.map +1 -0
  7. package/src/ChangeTrailRefusedError.js +12 -0
  8. package/src/ChangeTrailRefusedError.js.map +7 -0
  9. package/src/EntityUuidInUseError.d.ts +19 -0
  10. package/src/EntityUuidInUseError.d.ts.map +1 -0
  11. package/src/EntityUuidInUseError.js +11 -0
  12. package/src/EntityUuidInUseError.js.map +7 -0
  13. package/src/WorkerTimeoutError.d.ts +25 -0
  14. package/src/WorkerTimeoutError.d.ts.map +1 -0
  15. package/src/WorkerTimeoutError.js +12 -0
  16. package/src/WorkerTimeoutError.js.map +7 -0
  17. package/src/bundle.d.ts +1 -1
  18. package/src/bundle.d.ts.map +1 -1
  19. package/src/bundle.js +1 -1
  20. package/src/bundle.js.map +2 -2
  21. package/src/constants.d.ts +9 -2
  22. package/src/constants.d.ts.map +1 -1
  23. package/src/constants.js +1 -1
  24. package/src/constants.js.map +2 -2
  25. package/src/create-worker.bundle.d.ts +1 -1
  26. package/src/create-worker.bundle.d.ts.map +1 -1
  27. package/src/create-worker.bundle.js.map +1 -1
  28. package/src/create-worker.d.ts +1 -1
  29. package/src/create-worker.d.ts.map +1 -1
  30. package/src/create-worker.js.map +1 -1
  31. package/src/elements/ShaeElement.d.ts +70 -2
  32. package/src/elements/ShaeElement.d.ts.map +1 -1
  33. package/src/elements/ShaeElement.js +129 -25
  34. package/src/elements/ShaeElement.js.map +3 -3
  35. package/src/elements/ShaeEntElement.d.ts +43 -5
  36. package/src/elements/ShaeEntElement.d.ts.map +1 -1
  37. package/src/elements/ShaeEntElement.js +399 -170
  38. package/src/elements/ShaeEntElement.js.map +2 -2
  39. package/src/elements/ShaeLifecycleElement.d.ts +71 -0
  40. package/src/elements/ShaeLifecycleElement.d.ts.map +1 -0
  41. package/src/elements/ShaeLifecycleElement.js +83 -0
  42. package/src/elements/ShaeLifecycleElement.js.map +7 -0
  43. package/src/elements/ShaePropElement.d.ts +57 -7
  44. package/src/elements/ShaePropElement.d.ts.map +1 -1
  45. package/src/elements/ShaePropElement.js +241 -220
  46. package/src/elements/ShaePropElement.js.map +2 -2
  47. package/src/elements/ShaeWorkerElement.d.ts +49 -5
  48. package/src/elements/ShaeWorkerElement.d.ts.map +1 -1
  49. package/src/elements/ShaeWorkerElement.js +230 -74
  50. package/src/elements/ShaeWorkerElement.js.map +2 -2
  51. package/src/elements/constants.d.ts +6 -0
  52. package/src/elements/constants.d.ts.map +1 -1
  53. package/src/elements/constants.js +12 -0
  54. package/src/elements/constants.js.map +2 -2
  55. package/src/elements/deferredTeardown.d.ts +24 -0
  56. package/src/elements/deferredTeardown.d.ts.map +1 -0
  57. package/src/elements/deferredTeardown.js +30 -0
  58. package/src/elements/deferredTeardown.js.map +7 -0
  59. package/src/elements/displayContentsRule.d.ts +25 -0
  60. package/src/elements/displayContentsRule.d.ts.map +1 -0
  61. package/src/elements/displayContentsRule.js +37 -0
  62. package/src/elements/displayContentsRule.js.map +7 -0
  63. package/src/elements/events.d.ts +10 -7
  64. package/src/elements/events.d.ts.map +1 -1
  65. package/src/elements/forwardCustomEvents.d.ts +19 -0
  66. package/src/elements/forwardCustomEvents.d.ts.map +1 -0
  67. package/src/elements/forwardCustomEvents.js +47 -0
  68. package/src/elements/forwardCustomEvents.js.map +7 -0
  69. package/src/elements/hostedSlots.d.ts +36 -0
  70. package/src/elements/hostedSlots.d.ts.map +1 -0
  71. package/src/elements/hostedSlots.js +118 -0
  72. package/src/elements/hostedSlots.js.map +7 -0
  73. package/src/elements/parentRemoval.d.ts +18 -0
  74. package/src/elements/parentRemoval.d.ts.map +1 -0
  75. package/src/elements/parentRemoval.js +60 -0
  76. package/src/elements/parentRemoval.js.map +7 -0
  77. package/src/elements/propValueConverters.d.ts +3 -0
  78. package/src/elements/propValueConverters.d.ts.map +1 -0
  79. package/src/elements/propValueConverters.js +54 -0
  80. package/src/elements/propValueConverters.js.map +7 -0
  81. package/src/elements/requestEntAncestor.d.ts +32 -0
  82. package/src/elements/requestEntAncestor.d.ts.map +1 -0
  83. package/src/elements/requestEntAncestor.js +16 -0
  84. package/src/elements/requestEntAncestor.js.map +7 -0
  85. package/src/elements.js.map +1 -1
  86. package/src/in-the-dark/Entity.d.ts +113 -3
  87. package/src/in-the-dark/Entity.d.ts.map +1 -1
  88. package/src/in-the-dark/Entity.js +292 -63
  89. package/src/in-the-dark/Entity.js.map +3 -3
  90. package/src/in-the-dark/Kernel.d.ts +81 -17
  91. package/src/in-the-dark/Kernel.d.ts.map +1 -1
  92. package/src/in-the-dark/Kernel.js +449 -392
  93. package/src/in-the-dark/Kernel.js.map +3 -3
  94. package/src/in-the-dark/Registry.d.ts +1 -1
  95. package/src/in-the-dark/Registry.d.ts.map +1 -1
  96. package/src/in-the-dark/Registry.js +99 -26
  97. package/src/in-the-dark/Registry.js.map +2 -2
  98. package/src/in-the-dark/ShadowObject.d.ts +1 -1
  99. package/src/in-the-dark/ShadowObject.d.ts.map +1 -1
  100. package/src/in-the-dark/ShadowObject.js +3 -2
  101. package/src/in-the-dark/ShadowObject.js.map +2 -2
  102. package/src/in-the-dark/ShadowObjectCreationScope.d.ts +126 -0
  103. package/src/in-the-dark/ShadowObjectCreationScope.d.ts.map +1 -0
  104. package/src/in-the-dark/ShadowObjectCreationScope.js +596 -0
  105. package/src/in-the-dark/ShadowObjectCreationScope.js.map +7 -0
  106. package/src/in-the-dark/SignalsPath.d.ts.map +1 -1
  107. package/src/in-the-dark/SignalsPath.js +2 -2
  108. package/src/in-the-dark/SignalsPath.js.map +2 -2
  109. package/src/in-the-dark/events.js.map +1 -1
  110. package/src/in-the-dark/importModule.d.ts +7 -0
  111. package/src/in-the-dark/importModule.d.ts.map +1 -1
  112. package/src/in-the-dark/importModule.js +8 -5
  113. package/src/in-the-dark/importModule.js.map +2 -2
  114. package/src/index.d.ts +7 -1
  115. package/src/index.d.ts.map +1 -1
  116. package/src/index.js +5 -1
  117. package/src/index.js.map +2 -2
  118. package/src/shadow-objects.d.ts +2 -0
  119. package/src/shadow-objects.d.ts.map +1 -1
  120. package/src/shadow-objects.js +2 -0
  121. package/src/shadow-objects.js.map +2 -2
  122. package/src/shadow-objects.worker.js +0 -1
  123. package/src/shadow-objects.worker.js.map +2 -2
  124. package/src/shae-ent.js.map +1 -1
  125. package/src/shae-prop.js +2 -2
  126. package/src/shae-prop.js.map +2 -2
  127. package/src/shae-worker.js.map +1 -1
  128. package/src/types.d.ts +39 -8
  129. package/src/types.d.ts.map +1 -1
  130. package/src/utils/ConsoleLogger.d.ts +45 -10
  131. package/src/utils/ConsoleLogger.d.ts.map +1 -1
  132. package/src/utils/ConsoleLogger.js +54 -28
  133. package/src/utils/ConsoleLogger.js.map +2 -2
  134. package/src/utils/FrameLoop.d.ts +42 -3
  135. package/src/utils/FrameLoop.d.ts.map +1 -1
  136. package/src/utils/FrameLoop.js +71 -12
  137. package/src/utils/FrameLoop.js.map +2 -2
  138. package/src/utils/MicrotaskCollector.d.ts +45 -0
  139. package/src/utils/MicrotaskCollector.d.ts.map +1 -0
  140. package/src/utils/MicrotaskCollector.js +33 -0
  141. package/src/utils/MicrotaskCollector.js.map +7 -0
  142. package/src/utils/MicrotaskGate.d.ts +17 -0
  143. package/src/utils/MicrotaskGate.d.ts.map +1 -0
  144. package/src/utils/MicrotaskGate.js +20 -0
  145. package/src/utils/MicrotaskGate.js.map +7 -0
  146. package/src/utils/array-utils.js.map +1 -1
  147. package/src/utils/attr-utils.d.ts +6 -0
  148. package/src/utils/attr-utils.d.ts.map +1 -1
  149. package/src/utils/attr-utils.js +4 -2
  150. package/src/utils/attr-utils.js.map +2 -2
  151. package/src/utils/constants.js.map +1 -1
  152. package/src/utils/generateUUID.d.ts +12 -1
  153. package/src/utils/generateUUID.d.ts.map +1 -1
  154. package/src/utils/generateUUID.js +31 -266
  155. package/src/utils/generateUUID.js.map +2 -2
  156. package/src/utils/props-utils.d.ts +3 -2
  157. package/src/utils/props-utils.d.ts.map +1 -1
  158. package/src/utils/props-utils.js +13 -24
  159. package/src/utils/props-utils.js.map +2 -2
  160. package/src/utils/runGuarded.d.ts +27 -0
  161. package/src/utils/runGuarded.d.ts.map +1 -0
  162. package/src/utils/runGuarded.js +11 -0
  163. package/src/utils/runGuarded.js.map +7 -0
  164. package/src/utils/toMaybe.d.ts.map +1 -1
  165. package/src/utils/toMaybe.js.map +1 -1
  166. package/src/utils/toNamespace.d.ts.map +1 -1
  167. package/src/utils/toNamespace.js.map +1 -1
  168. package/src/utils/toUrlString.d.ts +12 -0
  169. package/src/utils/toUrlString.d.ts.map +1 -1
  170. package/src/utils/toUrlString.js.map +2 -2
  171. package/src/utils/waitForMessageOfType.d.ts +16 -1
  172. package/src/utils/waitForMessageOfType.d.ts.map +1 -1
  173. package/src/utils/waitForMessageOfType.js +28 -3
  174. package/src/utils/waitForMessageOfType.js.map +2 -2
  175. package/src/view/ComponentChanges.d.ts +91 -1
  176. package/src/view/ComponentChanges.d.ts.map +1 -1
  177. package/src/view/ComponentChanges.js +253 -69
  178. package/src/view/ComponentChanges.js.map +2 -2
  179. package/src/view/ComponentContext.d.ts +239 -7
  180. package/src/view/ComponentContext.d.ts.map +1 -1
  181. package/src/view/ComponentContext.js +648 -115
  182. package/src/view/ComponentContext.js.map +2 -2
  183. package/src/view/ComponentMemory.d.ts +3 -3
  184. package/src/view/ComponentMemory.d.ts.map +1 -1
  185. package/src/view/ComponentMemory.js +3 -1
  186. package/src/view/ComponentMemory.js.map +2 -2
  187. package/src/view/IShadowObjectEnvProxy.d.ts +33 -1
  188. package/src/view/IShadowObjectEnvProxy.d.ts.map +1 -1
  189. package/src/view/LocalShadowObjectEnv.d.ts +2 -2
  190. package/src/view/LocalShadowObjectEnv.d.ts.map +1 -1
  191. package/src/view/LocalShadowObjectEnv.js +18 -11
  192. package/src/view/LocalShadowObjectEnv.js.map +2 -2
  193. package/src/view/RemoteWorkerEnv.d.ts +129 -3
  194. package/src/view/RemoteWorkerEnv.d.ts.map +1 -1
  195. package/src/view/RemoteWorkerEnv.js +290 -60
  196. package/src/view/RemoteWorkerEnv.js.map +2 -2
  197. package/src/view/ShadowEnv.d.ts +73 -2
  198. package/src/view/ShadowEnv.d.ts.map +1 -1
  199. package/src/view/ShadowEnv.js +301 -64
  200. package/src/view/ShadowEnv.js.map +2 -2
  201. package/src/view/ViewComponent.d.ts +93 -8
  202. package/src/view/ViewComponent.d.ts.map +1 -1
  203. package/src/view/ViewComponent.js +148 -28
  204. package/src/view/ViewComponent.js.map +2 -2
  205. package/src/view/cloneChangeTrail.js.map +2 -2
  206. package/src/worker/MessageRouter.d.ts +14 -0
  207. package/src/worker/MessageRouter.d.ts.map +1 -1
  208. package/src/worker/MessageRouter.js +80 -18
  209. package/src/worker/MessageRouter.js.map +2 -2
  210. package/src/worker/WorkerRuntime.d.ts +22 -1
  211. package/src/worker/WorkerRuntime.d.ts.map +1 -1
  212. package/src/worker/WorkerRuntime.js +60 -8
  213. package/src/worker/WorkerRuntime.js.map +2 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/elements/ShaeWorkerElement.ts"],
4
- "sourcesContent": ["import {on} from '@spearwolf/eventize';\nimport {batch, createEffect, createSignal, destroySignal, Effect} from '@spearwolf/signalize';\nimport {readBooleanAttribute} from '../utils/attr-utils.js';\nimport {ConsoleLogger} from '../utils/ConsoleLogger.js';\nimport {FrameLoop} from '../utils/FrameLoop.js';\nimport {ComponentContext} from '../view/ComponentContext.js';\nimport {LocalShadowObjectEnv} from '../view/LocalShadowObjectEnv.js';\nimport {RemoteWorkerEnv} from '../view/RemoteWorkerEnv.js';\nimport {ShadowEnv} from '../view/ShadowEnv.js';\nimport {ATTR_AUTO_SYNC, ATTR_LOCAL, ATTR_NO_AUTOSTART, ATTR_NO_STRUCTURED_CLONE, ATTR_SRC} from './constants.js';\nimport {ShaeElement} from './ShaeElement.js';\n\nexport class ShaeWorkerElement extends ShaeElement {\n static override observedAttributes = [\n ...ShaeElement.observedAttributes,\n ATTR_LOCAL,\n ATTR_SRC,\n ATTR_NO_STRUCTURED_CLONE,\n ATTR_AUTO_SYNC,\n ];\n\n static DefaultAutoSync = 'frame';\n\n readonly isShaeWorkerElement = true;\n\n readonly shadowEnv = new ShadowEnv();\n\n readonly logger = new ConsoleLogger('ShaeWorkerElement');\n\n autostart = true;\n\n isConnected$ = createSignal(false);\n autoSync$ = createSignal(ShaeWorkerElement.DefaultAutoSync);\n src$ = createSignal('');\n\n #shouldDestroy = false;\n #started = false;\n\n #frameLoop?: FrameLoop;\n #autoSync?: Effect;\n #importScript?: Effect;\n\n constructor() {\n super();\n\n this.ns$.onChange((ns) => {\n this.shadowEnv.view = ComponentContext.get(ns);\n });\n\n on(this.shadowEnv, ShadowEnv.ContextCreated, () => {\n this.#importScript?.run();\n this.dispatchEvent(\n new CustomEvent(ShadowEnv.ContextCreated.toLowerCase(), {\n bubbles: false,\n detail: {shadowEnv: this.shadowEnv},\n }),\n );\n });\n\n on(this.shadowEnv, ShadowEnv.ContextLost, () => {\n this.dispatchEvent(\n new CustomEvent(ShadowEnv.ContextLost.toLowerCase(), {\n bubbles: false,\n detail: {shadowEnv: this.shadowEnv},\n }),\n );\n });\n\n this.autoSync$.onChange((sVal) => {\n const hasAttr = this.hasAttribute(ATTR_AUTO_SYNC);\n const attrVal = hasAttr ? this.getAttribute(ATTR_AUTO_SYNC) : undefined;\n\n if (sVal === ShaeWorkerElement.DefaultAutoSync) {\n if (hasAttr && attrVal !== sVal) {\n this.setAttribute(ATTR_AUTO_SYNC, sVal);\n }\n } else if (attrVal !== sVal) {\n this.setAttribute(ATTR_AUTO_SYNC, sVal);\n }\n });\n\n this.#createAutoSyncEffect();\n this.#createImportScriptEffect();\n\n this.style.display = 'contents';\n }\n\n #createImportScriptEffect() {\n this.#importScript = createEffect(\n () => {\n const src = this.src$.get();\n if (src) {\n this.importScript(src);\n }\n },\n {autorun: false},\n );\n }\n\n get shouldAutostart(): boolean {\n return this.autostart && !readBooleanAttribute(this, ATTR_NO_AUTOSTART);\n }\n\n get autoSync() {\n return this.autoSync$.value;\n }\n\n set autoSync(val: any) {\n if (typeof val !== 'string') {\n val = val ? ShaeWorkerElement.DefaultAutoSync : 'no';\n }\n this.autoSync$.set(`${val}`.trim().toLowerCase());\n }\n\n get frameLoop(): FrameLoop {\n this.#frameLoop ??= new FrameLoop();\n return this.#frameLoop;\n }\n\n /**\n * The frameLoop (if activated) calls this method on every frame\n */\n [FrameLoop.OnFrame]() {\n this.syncShadowObjects();\n }\n\n async importScript(src: URL | string): Promise<ShaeWorkerElement> {\n if (!src) {\n throw new Error('src is blank');\n }\n const shadowEnv = await this.shadowEnv.ready();\n if (this.logger.isInfo) {\n this.logger.info('shadowEnv importScript:', src, {shadowEnv});\n }\n await shadowEnv.envProxy.importScript(src);\n return this;\n }\n\n connectedCallback() {\n batch(() => {\n if (this.hasAttribute(ATTR_AUTO_SYNC)) {\n this.autoSync$.set(this.getAttribute(ATTR_AUTO_SYNC));\n }\n this.isConnected$.set(true);\n });\n if (this.shouldAutostart) {\n this.start();\n }\n }\n\n disconnectedCallback() {\n this.isConnected$.set(false);\n this.#deferDestroy();\n }\n\n override attributeChangedCallback(name: string) {\n super.attributeChangedCallback(name);\n\n if (name === ATTR_LOCAL) {\n if (this.shadowEnv.envProxy != null) {\n throw new Error('Changing the \"local\" attribute after the shadowEnv has been created is not supported.');\n }\n }\n\n if (name === ATTR_NO_STRUCTURED_CLONE) {\n this.#disableStructuredClone();\n }\n\n if (name === ATTR_AUTO_SYNC) {\n this.autoSync = this.hasAttribute(ATTR_AUTO_SYNC) ? this.getAttribute(ATTR_AUTO_SYNC) : true;\n }\n\n if (name === ATTR_SRC) {\n const src = (this.getAttribute(ATTR_SRC) || '').trim();\n this.src$.set(src);\n if (this.shadowEnv.isReady) {\n this.#importScript?.run();\n }\n }\n }\n\n start(): Promise<ShadowEnv> {\n if (!this.#started) {\n this.#shouldDestroy = false;\n\n this.shadowEnv.view ??= ComponentContext.get(this.ns);\n\n if (this.shadowEnv.envProxy == null) {\n const envProxy = readBooleanAttribute(this, ATTR_LOCAL) ? new LocalShadowObjectEnv() : new RemoteWorkerEnv();\n this.shadowEnv.envProxy = envProxy;\n this.#disableStructuredClone();\n }\n\n this.#started = true;\n }\n\n return this.shadowEnv.ready();\n }\n\n destroy() {\n this.#autoSync?.destroy();\n this.#importScript?.destroy();\n destroySignal(this.isConnected$, this.autoSync$, this.src$);\n this.shadowEnv.envProxy = undefined;\n this.shadowEnv.destroy();\n }\n\n #deferDestroy() {\n // NOTE The destruction is halted until the next microtask\u2014but a reconnect (adding the element back to the DOM before the next microtask)\n // cannot stop this process, and that's okay. Once destroyed, it's destroyed forever.\n if (!this.#shouldDestroy) {\n this.#shouldDestroy = true;\n queueMicrotask(() => {\n if (this.#shouldDestroy) {\n this.destroy();\n }\n });\n }\n }\n\n #createAutoSyncEffect() {\n this.#autoSync = createEffect(() => {\n if (this.isConnected$.get()) {\n const autoSync = (this.autoSync$.get() || ShaeWorkerElement.DefaultAutoSync).trim().toLowerCase();\n let delay;\n\n if (['true', 'yes', 'on', 'frame', 'auto-sync'].includes(autoSync)) {\n if (this.logger.isDebug) {\n this.logger.debug('auto-sync', autoSync, this);\n }\n this.frameLoop.start(this);\n return () => {\n this.frameLoop.stop(this);\n };\n } else if (autoSync.toLowerCase().endsWith('fps')) {\n const fps = parseInt(autoSync, 10);\n if (fps > 0) {\n delay = Math.floor(1000 / fps);\n } else if (this.logger.isWarn) {\n this.logger.warn(`invalid auto-sync value: ${autoSync}`);\n }\n } else {\n delay = parseInt(autoSync, 10);\n if (isNaN(delay)) {\n delay = undefined;\n if (!['false', 'no', 'off'].includes(autoSync)) {\n this.logger.error(`invalid auto-sync value: ${autoSync}`);\n }\n }\n }\n\n if (delay !== undefined && delay > 0) {\n if (this.logger.isDebug) {\n this.logger.debug('auto-sync interval (ms)', delay, this);\n }\n const id = setInterval(() => {\n this.syncShadowObjects();\n }, delay);\n return () => {\n clearInterval(id);\n };\n } else if (this.logger.isDebug) {\n this.logger.debug('auto-sync off', this);\n }\n }\n }, [this.autoSync$, this.isConnected$]);\n }\n\n #disableStructuredClone() {\n const env = this.shadowEnv.envProxy as LocalShadowObjectEnv;\n if (env?.isLocalEnv) {\n env.disableStructuredClone = this.hasAttribute(ATTR_NO_STRUCTURED_CLONE);\n }\n }\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {on} from '@spearwolf/eventize';\nimport {batch, createEffect, createSignal, destroySignal, Effect, hibernate} from '@spearwolf/signalize';\nimport {readBooleanAttribute, readNumberAttribute} from '../utils/attr-utils.js';\nimport {ConsoleLogger} from '../utils/ConsoleLogger.js';\nimport {FrameLoop} from '../utils/FrameLoop.js';\nimport {ComponentContext} from '../view/ComponentContext.js';\nimport {LocalShadowObjectEnv} from '../view/LocalShadowObjectEnv.js';\nimport {RemoteWorkerEnv, type RemoteWorkerEnvOptions} from '../view/RemoteWorkerEnv.js';\nimport {ShadowEnv, ShadowEnvDestroyedError} from '../view/ShadowEnv.js';\nimport {\n ATTR_AUTO_SYNC,\n ATTR_CHANGE_TRAIL_TIMEOUT,\n ATTR_CONFIGURE_TIMEOUT,\n ATTR_DESTROY_TIMEOUT,\n ATTR_LOAD_TIMEOUT,\n ATTR_LOCAL,\n ATTR_NO_AUTOSTART,\n ATTR_NO_STRUCTURED_CLONE,\n ATTR_SRC,\n} from './constants.js';\nimport {ensureDisplayContentsRule} from './displayContentsRule.js';\nimport {ShaeElement} from './ShaeElement.js';\n\nconst WorkerTimeoutAttributes: [keyof RemoteWorkerEnvOptions, string][] = [\n ['loadTimeout', ATTR_LOAD_TIMEOUT],\n ['configureTimeout', ATTR_CONFIGURE_TIMEOUT],\n ['changeTrailTimeout', ATTR_CHANGE_TRAIL_TIMEOUT],\n ['destroyTimeout', ATTR_DESTROY_TIMEOUT],\n];\n\n/**\n * The one place the `auto-sync` spelling rule lives: a string is trimmed and lower-cased,\n * and anything else is read as a flag \u2014 a truthy value asks for the frame default, a falsy\n * one for no syncing at all. Every write into `autoSync$` this element makes goes through\n * here, so the canonical spelling does not depend on which write ran first.\n */\nfunction normaliseAutoSync(value: unknown): string {\n if (typeof value !== 'string') {\n return value ? ShaeWorkerElement.DefaultAutoSync : 'no';\n }\n return value.trim().toLowerCase();\n}\n\nexport class ShaeWorkerElement extends ShaeElement {\n static override observedAttributes = [\n ...ShaeElement.observedAttributes,\n ATTR_LOCAL,\n ATTR_SRC,\n ATTR_NO_STRUCTURED_CLONE,\n ATTR_AUTO_SYNC,\n ];\n\n static DefaultAutoSync = 'frame';\n\n readonly isShaeWorkerElement = true;\n\n readonly shadowEnv = new ShadowEnv();\n\n readonly #logger = new ConsoleLogger('ShaeWorkerElement');\n\n /** The logger this element reports through. */\n get logger(): ConsoleLogger {\n return this.#logger;\n }\n\n autostart = true;\n\n isConnected$ = createSignal(false);\n autoSync$ = createSignal(ShaeWorkerElement.DefaultAutoSync);\n src$ = createSignal('');\n\n #started = false;\n\n #autoSync?: Effect;\n #importScript?: Effect;\n\n /**\n * Points the environment at the namespace this element names.\n *\n * It hangs on `ns$`, which belongs to the base class and outlives this element's teardown, so\n * the handle is kept and released by hand \u2014 a listener left on a living signal is a listener the\n * global signal queue goes on holding, and with it this element.\n */\n #envViewBinding?: (() => void) | undefined;\n\n /**\n * Take the subscriptions up. Runs exactly once for this element, on the first connect.\n *\n * The return that `restore()` stands for on `<shae-ent>` and `<shae-prop>` does not exist here:\n * `connectedCallback` turns a torn-down `<shae-worker>` away, so nothing ever calls this a second\n * time.\n *\n * One path runs ahead of it, and it is the only one: `start()` is public, and an element started\n * by hand while it is out of the document builds its environment before anything below is\n * listening. Two things are lost there and stay lost, because both are moments rather than\n * values, and there is no honest way to replay a moment that has passed:\n *\n * - the `contextcreated` \u2014 and, should the environment lose its connection first, the\n * `contextlost` \u2014 DOM event for that environment. `ShadowEnv.ContextCreated` fires once, with\n * nobody on the element listening for it; re-dispatching it from here would announce as new an\n * environment that has been up for a while.\n * - the namespace the environment points at, where `ns` changed between that `start()` and the\n * first connect. `start()` resolves the view once with `??=`, the binding below only reacts to\n * *changes*, and the change already happened. `shadowEnv.view` then names the context of the\n * namespace the element carried when it was started. A write of `ns` after the first connect\n * moves it, as it always does.\n *\n * A `<shae-worker>` that connects before it starts \u2014 the ordinary way, and the only way the\n * declarative form has \u2014 meets neither. The import of `src` is the one case of this shape that\n * *is* caught up, at the end of this method, because a pending import is a value and not a\n * moment.\n */\n protected override restore(): void {\n super.restore();\n\n this.#envViewBinding = this.ns$.onChange((ns) => {\n this.shadowEnv.view = ComponentContext.get(ns);\n });\n\n on(this.shadowEnv, ShadowEnv.ContextCreated, () => {\n this.#importScript?.run();\n this.dispatchEvent(\n new CustomEvent(ShadowEnv.ContextCreated.toLowerCase(), {\n bubbles: false,\n detail: {shadowEnv: this.shadowEnv},\n }),\n );\n });\n\n on(this.shadowEnv, ShadowEnv.ContextLost, () => {\n this.dispatchEvent(\n new CustomEvent(ShadowEnv.ContextLost.toLowerCase(), {\n bubbles: false,\n detail: {shadowEnv: this.shadowEnv},\n }),\n );\n });\n\n on(this.shadowEnv, ShadowEnv.ProxyFailed, (reason: unknown) => {\n this.dispatchEvent(\n new CustomEvent(ShadowEnv.ProxyFailed.toLowerCase(), {\n bubbles: false,\n detail: {shadowEnv: this.shadowEnv, reason},\n }),\n );\n });\n\n on(this.shadowEnv, ShadowEnv.SyncFailed, (reason: unknown, changeTrail: unknown) => {\n this.dispatchEvent(\n new CustomEvent(ShadowEnv.SyncFailed.toLowerCase(), {\n bubbles: false,\n detail: {shadowEnv: this.shadowEnv, reason, changeTrail},\n }),\n );\n });\n\n this.autoSync$.onChange((sVal) => this.#reflectAutoSync(sVal));\n\n // the catch-up half of `restore()`: the signal carries the canonical spelling, and this is\n // what puts it on the attribute \u2014 `auto-sync=\"YES\"` is what an author writes, `auto-sync=\"yes\"`\n // is what the element syncs on, and a reader of the DOM sees the second\n this.#reflectAutoSync(this.autoSync$.value);\n\n // no catch-up for the namespace binding, and that is deliberate: the environment gets its view\n // from `start()`, which resolves the namespace at the one moment it needs it. Resolving it here\n // would build a `ComponentContext` for every `<shae-worker>` that has merely been connected,\n // and a context that exists is a context entities join\n this.#createAutoSyncEffect();\n this.#createImportScriptEffect();\n\n // a `src` that arrived while the environment was already up \u2014 only reachable through a\n // `start()` made by hand on an element outside the document \u2014 has nothing that would import it:\n // the effect is built without an autorun, and both callers that run it were registered a few\n // lines above. The same test `attributeChangedCallback` makes for `src`\n if (this.shadowEnv.isReady) {\n this.#importScript?.run();\n }\n }\n\n #reflectAutoSync(sVal: string): void {\n this.reflectAttribute(ATTR_AUTO_SYNC, () => {\n const hasAttr = this.hasAttribute(ATTR_AUTO_SYNC);\n const attrVal = hasAttr ? this.getAttribute(ATTR_AUTO_SYNC) : undefined;\n\n if (sVal === ShaeWorkerElement.DefaultAutoSync) {\n if (hasAttr && attrVal !== sVal) {\n this.setAttribute(ATTR_AUTO_SYNC, sVal);\n }\n } else if (attrVal !== sVal) {\n this.setAttribute(ATTR_AUTO_SYNC, sVal);\n }\n });\n }\n\n #createImportScriptEffect() {\n this.#importScript = createEffect(\n () => {\n const src = this.src$.get();\n if (src) {\n this.importScript(src).catch(this.#onUnobservedRejection);\n }\n },\n {autorun: false},\n );\n }\n\n /**\n * Both {@link ShaeWorkerElement.start} and {@link ShaeWorkerElement.importScript} await\n * {@link ShadowEnv.ready}, which rejects once the environment is destroyed \u2014 the normal\n * outcome for an element that connects and disconnects within the same task. Nothing in the\n * element waits on those promises, so the rejection has to end here instead of surfacing as\n * an unhandled rejection in the browser or as a hard failure in a test runner.\n */\n #onUnobservedRejection = (error: unknown) => {\n if (error instanceof ShadowEnvDestroyedError) return;\n this.logger.error('shadowEnv failed', error);\n };\n\n get shouldAutostart(): boolean {\n return this.autostart && !readBooleanAttribute(this, ATTR_NO_AUTOSTART);\n }\n\n get autoSync() {\n return this.autoSync$.value;\n }\n\n set autoSync(val: string | boolean | number) {\n this.autoSync$.set(normaliseAutoSync(val));\n }\n\n get frameLoop(): FrameLoop {\n return FrameLoop.get();\n }\n\n /**\n * The frameLoop (if activated) calls this method on every frame\n */\n [FrameLoop.OnFrame]() {\n this.syncShadowObjects();\n }\n\n async importScript(src: URL | string): Promise<ShaeWorkerElement> {\n if (!src) {\n throw new Error('src is blank');\n }\n const shadowEnv = await this.shadowEnv.ready();\n this.logger.info('shadowEnv importScript:', src, {shadowEnv});\n // ready() only vouches for the proxy at the moment it resolves; a teardown can slip in\n // between that microtask and this line\n const envProxy = shadowEnv.envProxy;\n if (envProxy == null) {\n throw new ShadowEnvDestroyedError();\n }\n\n await envProxy.importScript(src);\n return this;\n }\n\n override connectedCallback() {\n // the whole body outside any reactive context of the caller \u2014 same reason as in\n // `ShaeLifecycleElement.connectedCallback`, and the frames nest without trouble\n hibernate(() => {\n // this element does not come back, and the refusal has to stand in front of `super`: the base\n // takes an element's subscriptions up there, and for a torn-down one there is nothing to take\n // up \u2014 the teardown took the environment with it, and an environment cannot be rebuilt around\n // a proxy that is gone. A `<shae-worker>` that is needed again is a new one.\n //\n // How the element renders is a separate question from whether it still listens, so the rule\n // is installed before the refusal returns\n if (this.isDestroyed) {\n ensureDisplayContentsRule(this.getRootNode(), this.localName);\n return;\n }\n\n super.connectedCallback();\n\n batch(() => {\n const autoSync = this.getAttribute(ATTR_AUTO_SYNC);\n if (autoSync != null) {\n this.autoSync = autoSync;\n }\n this.isConnected$.set(true);\n });\n if (this.shouldAutostart) {\n this.start().catch(this.#onUnobservedRejection);\n }\n });\n }\n\n override disconnectedCallback() {\n this.isConnected$.set(false);\n super.disconnectedCallback();\n }\n\n override attributeChangedCallback(name: string) {\n // the signals of this class are destroyed, so an attribute write would land in a value that\n // notifies nobody \u2014 and there is no return that would ever read it back\n if (this.isDestroyed) return;\n\n super.attributeChangedCallback(name);\n\n if (name === ATTR_LOCAL) {\n this.#refuseLocalChange();\n }\n\n if (name === ATTR_NO_STRUCTURED_CLONE) {\n this.#disableStructuredClone();\n }\n\n if (name === ATTR_AUTO_SYNC) {\n this.autoSync = this.getAttribute(ATTR_AUTO_SYNC) ?? true;\n }\n\n if (name === ATTR_SRC) {\n const src = (this.getAttribute(ATTR_SRC) || '').trim();\n this.src$.set(src);\n if (this.shadowEnv.isReady) {\n this.#importScript?.run();\n }\n }\n }\n\n /**\n * The timeout attributes, read at the one moment they are needed: when the worker environment\n * is built. An attribute that is not there is left out, so the environment keeps its default,\n * and a value the environment does not accept is reported there. They are not observed \u2014\n * setting one afterwards changes nothing about an environment that already exists, and a\n * `local` element builds no worker environment at all, so they do nothing there.\n */\n #readWorkerTimeouts(): RemoteWorkerEnvOptions {\n const options: RemoteWorkerEnvOptions = {};\n\n for (const [key, attr] of WorkerTimeoutAttributes) {\n const value = readNumberAttribute(this, attr);\n if (value !== undefined) options[key] = value;\n }\n\n return options;\n }\n\n start(): Promise<ShadowEnv> {\n if (!this.#started) {\n this.shadowEnv.view ??= ComponentContext.get(this.ns);\n\n if (this.shadowEnv.envProxy == null) {\n const envProxy = readBooleanAttribute(this, ATTR_LOCAL)\n ? new LocalShadowObjectEnv()\n : new RemoteWorkerEnv(this.#readWorkerTimeouts());\n this.shadowEnv.envProxy = envProxy;\n this.#disableStructuredClone();\n }\n\n this.#started = true;\n }\n\n return this.shadowEnv.ready();\n }\n\n /**\n * Tear this element down \u2014 for good.\n *\n * The effects and signals below belong to the element alone, so the element is what decides\n * whether they have already been released; the guard for that sits in\n * `ShaeLifecycleElement.destroy()`, which has already set the flag by the time this runs. Here\n * that matters more than anywhere else: `shadowEnv.destroy()` dispatches a `contextlost`\n * `CustomEvent` on this element on its way out, and a listener on it that reaches back into\n * `destroy()` finds the flag down and turns around instead of tearing the same environment down\n * a second time.\n *\n * Unlike `<shae-ent>` and `<shae-prop>`, this teardown is final: it destroys the signals and\n * takes the environment down with them, and neither comes back. `connectedCallback` turns a\n * returning element away rather than handing it a half of what it had, which is what makes\n * {@link ShaeWorkerElement.restore} a method that runs once and never again.\n */\n protected override teardown() {\n this.#envViewBinding?.();\n this.#envViewBinding = undefined;\n\n this.#autoSync?.destroy();\n this.#importScript?.destroy();\n destroySignal(this.isConnected$, this.autoSync$, this.src$);\n this.shadowEnv.envProxy = undefined;\n this.shadowEnv.destroy();\n\n super.teardown();\n }\n\n #createAutoSyncEffect() {\n this.#autoSync = createEffect(() => {\n if (this.isConnected$.get()) {\n const autoSync = normaliseAutoSync(this.autoSync$.get() || ShaeWorkerElement.DefaultAutoSync);\n let delay;\n\n if (['true', 'yes', 'on', 'frame', 'auto-sync'].includes(autoSync)) {\n this.logger.debug('auto-sync', autoSync, this);\n this.frameLoop.start(this);\n return () => {\n this.frameLoop.stop(this);\n };\n } else if (autoSync.endsWith('fps')) {\n const fps = parseInt(autoSync, 10);\n if (fps > 0) {\n delay = Math.floor(1000 / fps);\n } else {\n this.logger.warn(`invalid auto-sync value: ${autoSync}`);\n }\n } else {\n delay = parseInt(autoSync, 10);\n if (isNaN(delay)) {\n delay = undefined;\n if (!['false', 'no', 'off'].includes(autoSync)) {\n this.logger.error(`invalid auto-sync value: ${autoSync}`);\n }\n }\n }\n\n if (delay !== undefined && delay > 0) {\n this.logger.debug('auto-sync interval (ms)', delay, this);\n const id = setInterval(() => {\n this.syncShadowObjects();\n }, delay);\n return () => {\n clearInterval(id);\n };\n } else {\n this.logger.debug('auto-sync off', this);\n }\n }\n }, [this.autoSync$, this.isConnected$]);\n }\n\n #disableStructuredClone() {\n const env = this.shadowEnv.envProxy as LocalShadowObjectEnv;\n if (env?.isLocalEnv) {\n env.disableStructuredClone = this.hasAttribute(ATTR_NO_STRUCTURED_CLONE);\n }\n }\n\n /**\n * `local` picks the environment kind once, at `start()`. The proxy, its kernel and its\n * entities all belong to the side they were built on, and there is no way to move them onto\n * the other one afterwards \u2014 a later write to this attribute is refused, not carried out.\n *\n * A throw from this reaction would not reach the caller of `setAttribute` either way: per spec,\n * a Custom Element reaction reports its own exceptions to the global `error` event instead of\n * propagating them synchronously, so a `try`/`catch` around the write would catch nothing. The\n * refusal writes the attribute back through `reflectAttribute`, the one path this element uses\n * to write its own attributes from inside, and reports the refusal separately through the\n * `ConsoleLogger`. `logger.error` and not `logger.warn`: `logger.error` always prints, where\n * `logger.warn` is gated behind `isWarn`, which is off outside `localhost`, and a refusal that\n * goes silent there is exactly what this call needs to avoid.\n *\n * The write back re-enters `attributeChangedCallback` once, where the attribute now matches\n * the effective state and the check below returns before logging again. On an element built\n * and started by hand while it was never in the document, that write is parked until the first\n * connect (see `reflectAttribute`), while the log line above runs immediately.\n */\n #refuseLocalChange(): void {\n const envProxy = this.shadowEnv.envProxy;\n if (envProxy == null) return;\n\n const isLocalEnv = Boolean((envProxy as LocalShadowObjectEnv).isLocalEnv);\n if (readBooleanAttribute(this, ATTR_LOCAL) === isLocalEnv) return;\n\n this.logger.error(\n `the \"local\" attribute cannot change once the shadowEnv is built; it is reset to ${\n isLocalEnv ? 'the bare \"local\" form' : 'its absence'\n } \u2014 build a new <shae-worker> element to switch environments`,\n );\n\n this.reflectAttribute(ATTR_LOCAL, () => {\n if (isLocalEnv) {\n this.setAttribute(ATTR_LOCAL, '');\n } else {\n this.removeAttribute(ATTR_LOCAL);\n }\n });\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,16 +1,22 @@
1
1
  export declare const RequestEntParentEventName = "shaeRequestEntParent";
2
2
  export declare const ReRequestEntParentEventName = "shaeReRequestEntParent";
3
+ export declare const ReRequestEntHostEventName = "shaeReRequestEntHost";
3
4
  export declare const SHAE_WORKER = "shae-worker";
4
5
  export declare const SHAE_ENT = "shae-ent";
5
6
  export declare const SHAE_PROP = "shae-prop";
6
7
  export declare const ATTR_TOKEN = "token";
7
8
  export declare const ATTR_FORWARD_CUSTOM_EVENTS = "forward-custom-events";
9
+ export declare const ATTR_AUTO_DESTRUCT = "auto-destruct";
8
10
  export declare const ATTR_NS = "ns";
9
11
  export declare const ATTR_LOCAL = "local";
10
12
  export declare const ATTR_NO_AUTOSTART = "no-autostart";
11
13
  export declare const ATTR_NO_STRUCTURED_CLONE = "no-structured-clone";
12
14
  export declare const ATTR_AUTO_SYNC = "auto-sync";
13
15
  export declare const ATTR_SRC = "src";
16
+ export declare const ATTR_LOAD_TIMEOUT = "load-timeout";
17
+ export declare const ATTR_CONFIGURE_TIMEOUT = "configure-timeout";
18
+ export declare const ATTR_CHANGE_TRAIL_TIMEOUT = "change-trail-timeout";
19
+ export declare const ATTR_DESTROY_TIMEOUT = "destroy-timeout";
14
20
  export declare const ATTR_NAME = "name";
15
21
  export declare const ATTR_VALUE = "value";
16
22
  export declare const ATTR_TYPE = "type";
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/elements/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAChE,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AAEpE,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,QAAQ,aAAa,CAAC;AACnC,eAAO,MAAM,SAAS,cAAc,CAAC;AAGrC,eAAO,MAAM,UAAU,UAAU,CAAC;AAClC,eAAO,MAAM,0BAA0B,0BAA0B,CAAC;AAGlE,eAAO,MAAM,OAAO,OAAO,CAAC;AAG5B,eAAO,MAAM,UAAU,UAAU,CAAC;AAClC,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAC9D,eAAO,MAAM,cAAc,cAAc,CAAC;AAC1C,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAG9B,eAAO,MAAM,SAAS,SAAS,CAAC;AAChC,eAAO,MAAM,UAAU,UAAU,CAAC;AAClC,eAAO,MAAM,SAAS,SAAS,CAAC;AAChC,eAAO,MAAM,YAAY,YAAY,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/elements/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAChE,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AACpE,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAEhE,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,QAAQ,aAAa,CAAC;AACnC,eAAO,MAAM,SAAS,cAAc,CAAC;AAGrC,eAAO,MAAM,UAAU,UAAU,CAAC;AAClC,eAAO,MAAM,0BAA0B,0BAA0B,CAAC;AAClE,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAGlD,eAAO,MAAM,OAAO,OAAO,CAAC;AAG5B,eAAO,MAAM,UAAU,UAAU,CAAC;AAClC,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAC9D,eAAO,MAAM,cAAc,cAAc,CAAC;AAC1C,eAAO,MAAM,QAAQ,QAAQ,CAAC;AAC9B,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAChD,eAAO,MAAM,sBAAsB,sBAAsB,CAAC;AAC1D,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAChE,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAGtD,eAAO,MAAM,SAAS,SAAS,CAAC;AAChC,eAAO,MAAM,UAAU,UAAU,CAAC;AAClC,eAAO,MAAM,SAAS,SAAS,CAAC;AAChC,eAAO,MAAM,YAAY,YAAY,CAAC"}
@@ -1,23 +1,34 @@
1
1
  const RequestEntParentEventName = "shaeRequestEntParent";
2
2
  const ReRequestEntParentEventName = "shaeReRequestEntParent";
3
+ const ReRequestEntHostEventName = "shaeReRequestEntHost";
3
4
  const SHAE_WORKER = "shae-worker";
4
5
  const SHAE_ENT = "shae-ent";
5
6
  const SHAE_PROP = "shae-prop";
6
7
  const ATTR_TOKEN = "token";
7
8
  const ATTR_FORWARD_CUSTOM_EVENTS = "forward-custom-events";
9
+ const ATTR_AUTO_DESTRUCT = "auto-destruct";
8
10
  const ATTR_NS = "ns";
9
11
  const ATTR_LOCAL = "local";
10
12
  const ATTR_NO_AUTOSTART = "no-autostart";
11
13
  const ATTR_NO_STRUCTURED_CLONE = "no-structured-clone";
12
14
  const ATTR_AUTO_SYNC = "auto-sync";
13
15
  const ATTR_SRC = "src";
16
+ const ATTR_LOAD_TIMEOUT = "load-timeout";
17
+ const ATTR_CONFIGURE_TIMEOUT = "configure-timeout";
18
+ const ATTR_CHANGE_TRAIL_TIMEOUT = "change-trail-timeout";
19
+ const ATTR_DESTROY_TIMEOUT = "destroy-timeout";
14
20
  const ATTR_NAME = "name";
15
21
  const ATTR_VALUE = "value";
16
22
  const ATTR_TYPE = "type";
17
23
  const ATTR_NO_TRIM = "no-trim";
18
24
  export {
25
+ ATTR_AUTO_DESTRUCT,
19
26
  ATTR_AUTO_SYNC,
27
+ ATTR_CHANGE_TRAIL_TIMEOUT,
28
+ ATTR_CONFIGURE_TIMEOUT,
29
+ ATTR_DESTROY_TIMEOUT,
20
30
  ATTR_FORWARD_CUSTOM_EVENTS,
31
+ ATTR_LOAD_TIMEOUT,
21
32
  ATTR_LOCAL,
22
33
  ATTR_NAME,
23
34
  ATTR_NO_AUTOSTART,
@@ -28,6 +39,7 @@ export {
28
39
  ATTR_TOKEN,
29
40
  ATTR_TYPE,
30
41
  ATTR_VALUE,
42
+ ReRequestEntHostEventName,
31
43
  ReRequestEntParentEventName,
32
44
  RequestEntParentEventName,
33
45
  SHAE_ENT,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/elements/constants.ts"],
4
- "sourcesContent": ["export const RequestEntParentEventName = 'shaeRequestEntParent';\nexport const ReRequestEntParentEventName = 'shaeReRequestEntParent';\n\nexport const SHAE_WORKER = 'shae-worker';\nexport const SHAE_ENT = 'shae-ent';\nexport const SHAE_PROP = 'shae-prop';\n\n// <shae-ent> attributes\nexport const ATTR_TOKEN = 'token';\nexport const ATTR_FORWARD_CUSTOM_EVENTS = 'forward-custom-events';\n\n// <shae-ent> + <shae-worker> attributes\nexport const ATTR_NS = 'ns';\n\n// <shae-worker> attributes\nexport const ATTR_LOCAL = 'local';\nexport const ATTR_NO_AUTOSTART = 'no-autostart';\nexport const ATTR_NO_STRUCTURED_CLONE = 'no-structured-clone';\nexport const ATTR_AUTO_SYNC = 'auto-sync';\nexport const ATTR_SRC = 'src';\n\n// <shae-prop> attributes\nexport const ATTR_NAME = 'name';\nexport const ATTR_VALUE = 'value';\nexport const ATTR_TYPE = 'type';\nexport const ATTR_NO_TRIM = 'no-trim';"],
5
- "mappings": "AAAO,MAAM,4BAA4B;AAClC,MAAM,8BAA8B;AAEpC,MAAM,cAAc;AACpB,MAAM,WAAW;AACjB,MAAM,YAAY;AAGlB,MAAM,aAAa;AACnB,MAAM,6BAA6B;AAGnC,MAAM,UAAU;AAGhB,MAAM,aAAa;AACnB,MAAM,oBAAoB;AAC1B,MAAM,2BAA2B;AACjC,MAAM,iBAAiB;AACvB,MAAM,WAAW;AAGjB,MAAM,YAAY;AAClB,MAAM,aAAa;AACnB,MAAM,YAAY;AAClB,MAAM,eAAe;",
4
+ "sourcesContent": ["export const RequestEntParentEventName = 'shaeRequestEntParent';\nexport const ReRequestEntParentEventName = 'shaeReRequestEntParent';\nexport const ReRequestEntHostEventName = 'shaeReRequestEntHost';\n\nexport const SHAE_WORKER = 'shae-worker';\nexport const SHAE_ENT = 'shae-ent';\nexport const SHAE_PROP = 'shae-prop';\n\n// <shae-ent> attributes\nexport const ATTR_TOKEN = 'token';\nexport const ATTR_FORWARD_CUSTOM_EVENTS = 'forward-custom-events';\nexport const ATTR_AUTO_DESTRUCT = 'auto-destruct';\n\n// <shae-ent> + <shae-worker> attributes\nexport const ATTR_NS = 'ns';\n\n// <shae-worker> attributes\nexport const ATTR_LOCAL = 'local';\nexport const ATTR_NO_AUTOSTART = 'no-autostart';\nexport const ATTR_NO_STRUCTURED_CLONE = 'no-structured-clone';\nexport const ATTR_AUTO_SYNC = 'auto-sync';\nexport const ATTR_SRC = 'src';\nexport const ATTR_LOAD_TIMEOUT = 'load-timeout';\nexport const ATTR_CONFIGURE_TIMEOUT = 'configure-timeout';\nexport const ATTR_CHANGE_TRAIL_TIMEOUT = 'change-trail-timeout';\nexport const ATTR_DESTROY_TIMEOUT = 'destroy-timeout';\n\n// <shae-prop> attributes\nexport const ATTR_NAME = 'name';\nexport const ATTR_VALUE = 'value';\nexport const ATTR_TYPE = 'type';\nexport const ATTR_NO_TRIM = 'no-trim';\n"],
5
+ "mappings": "AAAO,MAAM,4BAA4B;AAClC,MAAM,8BAA8B;AACpC,MAAM,4BAA4B;AAElC,MAAM,cAAc;AACpB,MAAM,WAAW;AACjB,MAAM,YAAY;AAGlB,MAAM,aAAa;AACnB,MAAM,6BAA6B;AACnC,MAAM,qBAAqB;AAG3B,MAAM,UAAU;AAGhB,MAAM,aAAa;AACnB,MAAM,oBAAoB;AAC1B,MAAM,2BAA2B;AACjC,MAAM,iBAAiB;AACvB,MAAM,WAAW;AACjB,MAAM,oBAAoB;AAC1B,MAAM,yBAAyB;AAC/B,MAAM,4BAA4B;AAClC,MAAM,uBAAuB;AAG7B,MAAM,YAAY;AAClB,MAAM,aAAa;AACnB,MAAM,YAAY;AAClB,MAAM,eAAe;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * A teardown that waits for the next microtask before it commits.
3
+ *
4
+ * Leaving the tree is not the same as ending. A re-render takes an element out and puts it back
5
+ * inside one task, and everything hanging on it — an environment, its proxy, every entity in it —
6
+ * has to come through that move untouched. So the teardown is booked instead of run, and the
7
+ * microtask that follows asks where the element stands by then: whoever moved it in the meantime
8
+ * has left the answer here, and being back in the tree calls the teardown off. However often the
9
+ * element is moved inside that one window, only the first booking queues a microtask, so the
10
+ * question is asked once. An element that is still out when the microtask runs is torn down.
11
+ *
12
+ * A cancelled booking leaves its microtask standing — it wakes up, finds nothing booked and
13
+ * returns. Running twice is not guarded against here: that guard belongs to the teardown itself,
14
+ * which is callable by hand as well and has to carry it in either case.
15
+ */
16
+ export declare class DeferredTeardown {
17
+ #private;
18
+ constructor(run: () => void);
19
+ /** Book the teardown, and make sure someone comes asking. */
20
+ schedule(): void;
21
+ /** Take the booking back. */
22
+ cancel(): void;
23
+ }
24
+ //# sourceMappingURL=deferredTeardown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deferredTeardown.d.ts","sourceRoot":"","sources":["../../../src/elements/deferredTeardown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,qBAAa,gBAAgB;;IAS3B,YAAY,GAAG,EAAE,MAAM,IAAI,EAE1B;IAED,6DAA6D;IAC7D,QAAQ,IAAI,IAAI,CAgBf;IAED,6BAA6B;IAC7B,MAAM,IAAI,IAAI,CAEb;CACF"}
@@ -0,0 +1,30 @@
1
+ class DeferredTeardown {
2
+ #run;
3
+ /** Whether a teardown is booked right now. */
4
+ #isBooked = false;
5
+ /** Whether a microtask is already on its way to ask. */
6
+ #isAsking = false;
7
+ constructor(run) {
8
+ this.#run = run;
9
+ }
10
+ /** Book the teardown, and make sure someone comes asking. */
11
+ schedule() {
12
+ this.#isBooked = true;
13
+ if (this.#isAsking) return;
14
+ this.#isAsking = true;
15
+ queueMicrotask(() => {
16
+ this.#isAsking = false;
17
+ if (!this.#isBooked) return;
18
+ this.#isBooked = false;
19
+ this.#run();
20
+ });
21
+ }
22
+ /** Take the booking back. */
23
+ cancel() {
24
+ this.#isBooked = false;
25
+ }
26
+ }
27
+ export {
28
+ DeferredTeardown
29
+ };
30
+ //# sourceMappingURL=deferredTeardown.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/elements/deferredTeardown.ts"],
4
+ "sourcesContent": ["/**\n * A teardown that waits for the next microtask before it commits.\n *\n * Leaving the tree is not the same as ending. A re-render takes an element out and puts it back\n * inside one task, and everything hanging on it \u2014 an environment, its proxy, every entity in it \u2014\n * has to come through that move untouched. So the teardown is booked instead of run, and the\n * microtask that follows asks where the element stands by then: whoever moved it in the meantime\n * has left the answer here, and being back in the tree calls the teardown off. However often the\n * element is moved inside that one window, only the first booking queues a microtask, so the\n * question is asked once. An element that is still out when the microtask runs is torn down.\n *\n * A cancelled booking leaves its microtask standing \u2014 it wakes up, finds nothing booked and\n * returns. Running twice is not guarded against here: that guard belongs to the teardown itself,\n * which is callable by hand as well and has to carry it in either case.\n */\nexport class DeferredTeardown {\n readonly #run: () => void;\n\n /** Whether a teardown is booked right now. */\n #isBooked = false;\n\n /** Whether a microtask is already on its way to ask. */\n #isAsking = false;\n\n constructor(run: () => void) {\n this.#run = run;\n }\n\n /** Book the teardown, and make sure someone comes asking. */\n schedule(): void {\n this.#isBooked = true;\n\n if (this.#isAsking) return;\n this.#isAsking = true;\n\n queueMicrotask(() => {\n this.#isAsking = false;\n if (!this.#isBooked) return;\n // the booking is cleared in front of the run, not behind it: the field says whether a\n // teardown is waiting, and one that is being carried out is not waiting. It also decides what\n // a `schedule()` from inside the teardown means \u2014 a fresh round, rather than a booking that\n // the line behind the call would wipe out\n this.#isBooked = false;\n this.#run();\n });\n }\n\n /** Take the booking back. */\n cancel(): void {\n this.#isBooked = false;\n }\n}\n"],
5
+ "mappings": "AAeO,MAAM,iBAAiB;AAAA,EACnB;AAAA;AAAA,EAGT,YAAY;AAAA;AAAA,EAGZ,YAAY;AAAA,EAEZ,YAAY,KAAiB;AAC3B,SAAK,OAAO;AAAA,EACd;AAAA;AAAA,EAGA,WAAiB;AACf,SAAK,YAAY;AAEjB,QAAI,KAAK,UAAW;AACpB,SAAK,YAAY;AAEjB,mBAAe,MAAM;AACnB,WAAK,YAAY;AACjB,UAAI,CAAC,KAAK,UAAW;AAKrB,WAAK,YAAY;AACjB,WAAK,KAAK;AAAA,IACZ,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,SAAe;AACb,SAAK,YAAY;AAAA,EACnB;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Makes sure `root` carries a `display: contents` rule for `tagName`, and does so once per root.
3
+ *
4
+ * The elements of this library carry no box of their own: they wire DOM structure into entities
5
+ * and must leave the layout of whatever sits inside them untouched. That is a styling statement,
6
+ * and a stylesheet rule is where it belongs — an element constructor cannot make it, because the
7
+ * Custom Elements specification forbids a constructor from giving its element attributes, and an
8
+ * inline style is written as the `style` attribute. A constructor that writes one makes the
9
+ * browser abort the upgrade and hand back an `HTMLUnknownElement`.
10
+ *
11
+ * The rule is keyed by the tag name the element actually connects under, not by a fixed list:
12
+ * a subclass registered under a tag of its own — the extension point the guides describe — lays
13
+ * out no box either, and is covered the moment one of its instances connects. A tag that joins
14
+ * later widens the selector of the rule already there instead of adding a second one, so the
15
+ * position of the rule in the cascade never moves.
16
+ *
17
+ * The rule goes to the root the element stands in, not to `document`: style rules do not cross a
18
+ * shadow boundary, so an element inside a shadow root needs the rule inside that root.
19
+ *
20
+ * It is prepended rather than appended. Its specificity is 0-0-1, so a rule of the consumer's with
21
+ * the same specificity decides by order — coming later, it wins, and nobody needs `!important` to
22
+ * override the default.
23
+ */
24
+ export declare const ensureDisplayContentsRule: (root: Node, tagName: string) => void;
25
+ //# sourceMappingURL=displayContentsRule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"displayContentsRule.d.ts","sourceRoot":"","sources":["../../../src/elements/displayContentsRule.ts"],"names":[],"mappings":"AAyBA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,yBAAyB,SAAU,IAAI,WAAW,MAAM,KAAG,IAyCvE,CAAC"}
@@ -0,0 +1,37 @@
1
+ const RuleStatePerRoot = /* @__PURE__ */ new WeakMap();
2
+ const buildRule = (tags) => `${Array.from(tags, (tag) => CSS.escape(tag)).join(",")}{display:contents}`;
3
+ const isDocument = (node) => node.nodeType === 9;
4
+ const isShadowRoot = (node) => node.nodeType === 11 && node.host != null;
5
+ const ensureDisplayContentsRule = (root, tagName) => {
6
+ let mountPoint;
7
+ let doc;
8
+ let key;
9
+ if (isDocument(root)) {
10
+ mountPoint = root.head ?? root.documentElement ?? root;
11
+ doc = root;
12
+ key = root;
13
+ } else if (isShadowRoot(root)) {
14
+ mountPoint = root;
15
+ doc = root.ownerDocument;
16
+ key = root;
17
+ } else {
18
+ return;
19
+ }
20
+ const state = RuleStatePerRoot.get(key);
21
+ if (state?.style.isConnected) {
22
+ if (state.tags.has(tagName)) return;
23
+ state.tags.add(tagName);
24
+ state.style.textContent = buildRule(state.tags);
25
+ return;
26
+ }
27
+ const tags = state?.tags ?? /* @__PURE__ */ new Set();
28
+ tags.add(tagName);
29
+ const style = doc.createElement("style");
30
+ style.textContent = buildRule(tags);
31
+ mountPoint.prepend(style);
32
+ RuleStatePerRoot.set(key, { tags, style });
33
+ };
34
+ export {
35
+ ensureDisplayContentsRule
36
+ };
37
+ //# sourceMappingURL=displayContentsRule.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/elements/displayContentsRule.ts"],
4
+ "sourcesContent": ["/** What a root already carries: the tag names covered, and the element holding the rule. */\ninterface DisplayRuleState {\n tags: Set<string>;\n style: HTMLStyleElement;\n}\n\nconst RuleStatePerRoot = new WeakMap<Document | ShadowRoot, DisplayRuleState>();\n\n// `CSS.escape` guards a tag name that carries a character the selector grammar would otherwise\n// read as a combinator \u2014 a dot is legal in a custom element name and would parse as a class\n// selector instead of naming the tag it belongs to\nconst buildRule = (tags: Set<string>): string => `${Array.from(tags, (tag) => CSS.escape(tag)).join(',')}{display:contents}`;\n\n/**\n * Whether `node` is a document \u2014 across realms.\n *\n * `instanceof Document` reads the constructor of the realm this module was loaded in, so an\n * element adopted into a document from another realm \u2014 an iframe, most of all \u2014 would fall\n * through it and quietly get no rule at all. The node type is the same number everywhere.\n */\nconst isDocument = (node: Node): node is Document => node.nodeType === 9;\n\n/** Whether `node` is a shadow root, by the same reasoning \u2014 a document fragment carrying a host. */\nconst isShadowRoot = (node: Node): node is ShadowRoot => node.nodeType === 11 && (node as ShadowRoot).host != null;\n\n/**\n * Makes sure `root` carries a `display: contents` rule for `tagName`, and does so once per root.\n *\n * The elements of this library carry no box of their own: they wire DOM structure into entities\n * and must leave the layout of whatever sits inside them untouched. That is a styling statement,\n * and a stylesheet rule is where it belongs \u2014 an element constructor cannot make it, because the\n * Custom Elements specification forbids a constructor from giving its element attributes, and an\n * inline style is written as the `style` attribute. A constructor that writes one makes the\n * browser abort the upgrade and hand back an `HTMLUnknownElement`.\n *\n * The rule is keyed by the tag name the element actually connects under, not by a fixed list:\n * a subclass registered under a tag of its own \u2014 the extension point the guides describe \u2014 lays\n * out no box either, and is covered the moment one of its instances connects. A tag that joins\n * later widens the selector of the rule already there instead of adding a second one, so the\n * position of the rule in the cascade never moves.\n *\n * The rule goes to the root the element stands in, not to `document`: style rules do not cross a\n * shadow boundary, so an element inside a shadow root needs the rule inside that root.\n *\n * It is prepended rather than appended. Its specificity is 0-0-1, so a rule of the consumer's with\n * the same specificity decides by order \u2014 coming later, it wins, and nobody needs `!important` to\n * override the default.\n */\nexport const ensureDisplayContentsRule = (root: Node, tagName: string): void => {\n let mountPoint: ParentNode;\n let doc: Document;\n let key: Document | ShadowRoot;\n\n if (isDocument(root)) {\n // `head` is typed non-null but a document can be built without one \u2014 an XML document, or a\n // `createDocument()` \u2014 so the rule falls back to whatever parent the document offers\n mountPoint = root.head ?? root.documentElement ?? root;\n doc = root;\n key = root;\n } else if (isShadowRoot(root)) {\n mountPoint = root;\n doc = root.ownerDocument;\n key = root;\n } else {\n // an element that has entered neither a document nor a shadow root is its own root: nothing\n // to style yet, and the next connect asks again\n return;\n }\n\n const state = RuleStatePerRoot.get(key);\n\n // a root that gets its content replaced wholesale \u2014 a shadow root re-filled through `innerHTML`,\n // most of all \u2014 takes the `<style>` the rule lives in down with the rest of the markup, so the\n // root can look known while the element carrying its rule is no longer in it. Rebuilding the\n // `<style>` here covers both a root seen for the first time and one whose rule element fell out.\n if (state?.style.isConnected) {\n if (state.tags.has(tagName)) return;\n state.tags.add(tagName);\n state.style.textContent = buildRule(state.tags);\n return;\n }\n\n const tags = state?.tags ?? new Set();\n tags.add(tagName);\n const style = doc.createElement('style');\n style.textContent = buildRule(tags);\n mountPoint.prepend(style);\n\n RuleStatePerRoot.set(key, {tags, style});\n};\n"],
5
+ "mappings": "AAMA,MAAM,mBAAmB,oBAAI,QAAiD;AAK9E,MAAM,YAAY,CAAC,SAA8B,GAAG,MAAM,KAAK,MAAM,CAAC,QAAQ,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC;AASxG,MAAM,aAAa,CAAC,SAAiC,KAAK,aAAa;AAGvE,MAAM,eAAe,CAAC,SAAmC,KAAK,aAAa,MAAO,KAAoB,QAAQ;AAyBvG,MAAM,4BAA4B,CAAC,MAAY,YAA0B;AAC9E,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,MAAI,WAAW,IAAI,GAAG;AAGpB,iBAAa,KAAK,QAAQ,KAAK,mBAAmB;AAClD,UAAM;AACN,UAAM;AAAA,EACR,WAAW,aAAa,IAAI,GAAG;AAC7B,iBAAa;AACb,UAAM,KAAK;AACX,UAAM;AAAA,EACR,OAAO;AAGL;AAAA,EACF;AAEA,QAAM,QAAQ,iBAAiB,IAAI,GAAG;AAMtC,MAAI,OAAO,MAAM,aAAa;AAC5B,QAAI,MAAM,KAAK,IAAI,OAAO,EAAG;AAC7B,UAAM,KAAK,IAAI,OAAO;AACtB,UAAM,MAAM,cAAc,UAAU,MAAM,IAAI;AAC9C;AAAA,EACF;AAEA,QAAM,OAAO,OAAO,QAAQ,oBAAI,IAAI;AACpC,OAAK,IAAI,OAAO;AAChB,QAAM,QAAQ,IAAI,cAAc,OAAO;AACvC,QAAM,cAAc,UAAU,IAAI;AAClC,aAAW,QAAQ,KAAK;AAExB,mBAAiB,IAAI,KAAK,EAAC,MAAM,MAAK,CAAC;AACzC;",
6
+ "names": []
7
+ }
@@ -1,24 +1,27 @@
1
- import type { RequestEntParentEventName, ReRequestEntParentEventName } from './constants.js';
1
+ import type { RequestEntParentEventName, ReRequestEntHostEventName, ReRequestEntParentEventName } from './constants.js';
2
+ import type { EntAncestorRequest } from './requestEntAncestor.js';
2
3
  import type { ShaeEntElement } from './ShaeEntElement.js';
3
4
  export interface RequestEntParentEvent extends CustomEvent {
5
+ detail: EntAncestorRequest;
6
+ }
7
+ export interface ReRequestEntParentEvent extends CustomEvent {
4
8
  detail: {
5
9
  requester: ShaeEntElement;
10
+ shadowRootHost: HTMLElement;
6
11
  };
7
12
  }
8
- export interface ReRequestEntParentEvent extends CustomEvent {
13
+ export interface ReRequestEntHostEvent extends CustomEvent {
9
14
  detail: {
10
15
  requester: ShaeEntElement;
11
- shadowRootHost: HTMLElement;
12
16
  };
13
17
  }
14
- export interface ShadowEntsEventMap {
18
+ export interface ShadowObjectsEventMap {
15
19
  [RequestEntParentEventName]: RequestEntParentEvent;
16
20
  [ReRequestEntParentEventName]: ReRequestEntParentEvent;
21
+ [ReRequestEntHostEventName]: ReRequestEntHostEvent;
17
22
  }
18
23
  declare global {
19
- interface HTMLElementEventMap extends ShadowEntsEventMap {
20
- addEventListener<K extends keyof ShadowEntsEventMap>(type: K, listener: (this: Document, ev: ShadowEntsEventMap[K]) => void): void;
21
- dispatchEvent<K extends keyof ShadowEntsEventMap>(ev: ShadowEntsEventMap[K]): void;
24
+ interface HTMLElementEventMap extends ShadowObjectsEventMap {
22
25
  }
23
26
  }
24
27
  //# sourceMappingURL=events.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/elements/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAE,2BAA2B,EAAC,MAAM,gBAAgB,CAAC;AAC3F,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD,MAAM,EAAE;QACN,SAAS,EAAE,cAAc,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,WAAW,uBAAwB,SAAQ,WAAW;IAC1D,MAAM,EAAE;QACN,SAAS,EAAE,cAAc,CAAC;QAC1B,cAAc,EAAE,WAAW,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,kBAAkB;IACjC,CAAC,yBAAyB,CAAC,EAAE,qBAAqB,CAAC;IACnD,CAAC,2BAA2B,CAAC,EAAE,uBAAuB,CAAC;CACxD;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,mBAAoB,SAAQ,kBAAkB;QACtD,gBAAgB,CAAC,CAAC,SAAS,MAAM,kBAAkB,EACjD,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,IAAI,GAC5D,IAAI,CAAC;QACR,aAAa,CAAC,CAAC,SAAS,MAAM,kBAAkB,EAAE,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;KACpF;CACF"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/elements/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAE,yBAAyB,EAAE,2BAA2B,EAAC,MAAM,gBAAgB,CAAC;AACtH,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAwB,SAAQ,WAAW;IAC1D,MAAM,EAAE;QACN,SAAS,EAAE,cAAc,CAAC;QAC1B,cAAc,EAAE,WAAW,CAAC;KAC7B,CAAC;CACH;AAED,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD,MAAM,EAAE;QACN,SAAS,EAAE,cAAc,CAAC;KAC3B,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,CAAC,yBAAyB,CAAC,EAAE,qBAAqB,CAAC;IACnD,CAAC,2BAA2B,CAAC,EAAE,uBAAuB,CAAC;IACvD,CAAC,yBAAyB,CAAC,EAAE,qBAAqB,CAAC;CACpD;AAED,OAAO,CAAC,MAAM,CAAC;IAGb,UAAU,mBAAoB,SAAQ,qBAAqB;KAAG;CAC/D"}
@@ -0,0 +1,19 @@
1
+ import type { ViewComponent } from '../view/ViewComponent.js';
2
+ /** An allow-list without entries forwards nothing — the same thing `false` says. */
3
+ export declare const isEmptyFilter: (val: Set<string> | boolean) => boolean;
4
+ /**
5
+ * Whether two filter values are the same value — a `Set` by its entries rather than by identity.
6
+ *
7
+ * This is not the question {@link isEmptyFilter} answers. An empty `Set` and `false` forward the
8
+ * same nothing, and they are still two different values: only a write that replaces the one with
9
+ * the other reaches the subscribers of the signal, and the read-back on connect depends on it.
10
+ */
11
+ export declare const isSameFilter: (a: Set<string> | boolean, b: Set<string> | boolean) => boolean;
12
+ /**
13
+ * Carry the events a component dispatches out to `target` as DOM events, as far as `filter` allows.
14
+ *
15
+ * Answers with the call that takes the forwarding back, or with `undefined` where `filter` forwards
16
+ * nothing and no patch was set.
17
+ */
18
+ export declare const forwardCustomEventsFrom: (vc: ViewComponent, target: EventTarget, filter: Set<string> | boolean) => (() => void) | undefined;
19
+ //# sourceMappingURL=forwardCustomEvents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forwardCustomEvents.d.ts","sourceRoot":"","sources":["../../../src/elements/forwardCustomEvents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAE5D,oFAAoF;AACpF,eAAO,MAAM,aAAa,QAAS,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,KAAG,OAA+C,CAAC;AAE3G;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,MAAO,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,KAAK,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,KAAG,OAUjF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,OAC9B,aAAa,UACT,WAAW,UACX,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,KAC5B,CAAC,MAAM,IAAI,CAAC,GAAG,SA+CjB,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { ComponentContext } from "../view/ComponentContext.js";
2
+ const isEmptyFilter = (val) => val instanceof Set && val.size === 0;
3
+ const isSameFilter = (a, b) => {
4
+ if (a === b) return true;
5
+ if (a instanceof Set && b instanceof Set) {
6
+ if (a.size !== b.size) return false;
7
+ for (const type of a) {
8
+ if (!b.has(type)) return false;
9
+ }
10
+ return true;
11
+ }
12
+ return false;
13
+ };
14
+ const forwardCustomEventsFrom = (vc, target, filter) => {
15
+ if (!filter || isEmptyFilter(filter)) return;
16
+ const originalDispatchEvent = Object.hasOwn(vc, "dispatchEvent") ? Object.getPrototypeOf(vc).dispatchEvent : vc.dispatchEvent;
17
+ const allowedTypes = filter instanceof Set ? filter : void 0;
18
+ const newDispatch = (type, data, traverseChildren) => {
19
+ originalDispatchEvent.call(vc, type, data, traverseChildren);
20
+ if (type === ComponentContext.ReRequestParentRoots || type === ComponentContext.ReRequestParent || type === ComponentContext.ReRequestEntHost)
21
+ return;
22
+ if (allowedTypes && !allowedTypes.has(type)) return;
23
+ target.dispatchEvent(
24
+ new CustomEvent(type, {
25
+ bubbles: true,
26
+ composed: true,
27
+ detail: data
28
+ })
29
+ );
30
+ };
31
+ Object.defineProperty(vc, "dispatchEvent", {
32
+ value: newDispatch,
33
+ writable: true,
34
+ configurable: true
35
+ });
36
+ return () => {
37
+ if (Object.hasOwn(vc, "dispatchEvent") && vc.dispatchEvent === newDispatch) {
38
+ delete vc.dispatchEvent;
39
+ }
40
+ };
41
+ };
42
+ export {
43
+ forwardCustomEventsFrom,
44
+ isEmptyFilter,
45
+ isSameFilter
46
+ };
47
+ //# sourceMappingURL=forwardCustomEvents.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/elements/forwardCustomEvents.ts"],
4
+ "sourcesContent": ["import {ComponentContext} from '../view/ComponentContext.js';\nimport type {ViewComponent} from '../view/ViewComponent.js';\n\n/** An allow-list without entries forwards nothing \u2014 the same thing `false` says. */\nexport const isEmptyFilter = (val: Set<string> | boolean): boolean => val instanceof Set && val.size === 0;\n\n/**\n * Whether two filter values are the same value \u2014 a `Set` by its entries rather than by identity.\n *\n * This is not the question {@link isEmptyFilter} answers. An empty `Set` and `false` forward the\n * same nothing, and they are still two different values: only a write that replaces the one with\n * the other reaches the subscribers of the signal, and the read-back on connect depends on it.\n */\nexport const isSameFilter = (a: Set<string> | boolean, b: Set<string> | boolean): boolean => {\n if (a === b) return true;\n if (a instanceof Set && b instanceof Set) {\n if (a.size !== b.size) return false;\n for (const type of a) {\n if (!b.has(type)) return false;\n }\n return true;\n }\n return false;\n};\n\n/**\n * Carry the events a component dispatches out to `target` as DOM events, as far as `filter` allows.\n *\n * Answers with the call that takes the forwarding back, or with `undefined` where `filter` forwards\n * nothing and no patch was set.\n */\nexport const forwardCustomEventsFrom = (\n vc: ViewComponent,\n target: EventTarget,\n filter: Set<string> | boolean,\n): (() => void) | undefined => {\n if (!filter || isEmptyFilter(filter)) return;\n\n // the patch goes on the instance, so a component that already carries one shadows the very\n // method the new patch has to call through to: that original sits on the prototype\n const originalDispatchEvent = Object.hasOwn(vc, 'dispatchEvent') ? Object.getPrototypeOf(vc).dispatchEvent : vc.dispatchEvent;\n\n const allowedTypes = filter instanceof Set ? filter : undefined;\n\n const newDispatch = (type: string, data: unknown, traverseChildren: boolean) => {\n originalDispatchEvent.call(vc, type, data, traverseChildren);\n\n // the internal signals of the parent resolution never leave the view side as a DOM event,\n // not even under `forward-custom-events` without a filter list\n if (\n type === ComponentContext.ReRequestParentRoots ||\n type === ComponentContext.ReRequestParent ||\n type === ComponentContext.ReRequestEntHost\n )\n return;\n\n if (allowedTypes && !allowedTypes.has(type)) return;\n\n target.dispatchEvent(\n new CustomEvent(type, {\n bubbles: true,\n composed: true,\n detail: data,\n }),\n );\n };\n\n // We use defineProperty to ensure it is writable and configurable\n Object.defineProperty(vc, 'dispatchEvent', {\n value: newDispatch,\n writable: true,\n configurable: true,\n });\n\n return () => {\n if (Object.hasOwn(vc, 'dispatchEvent') && vc.dispatchEvent === newDispatch) {\n // the property lives on the instance (defineProperty above), the method it shadows lives\n // on the prototype: deleting the own property restores the original, it does not remove\n // the method\n delete (vc as {dispatchEvent?: ViewComponent['dispatchEvent']}).dispatchEvent;\n }\n };\n};\n"],
5
+ "mappings": "AAAA,SAAQ,wBAAuB;AAIxB,MAAM,gBAAgB,CAAC,QAAwC,eAAe,OAAO,IAAI,SAAS;AASlG,MAAM,eAAe,CAAC,GAA0B,MAAsC;AAC3F,MAAI,MAAM,EAAG,QAAO;AACpB,MAAI,aAAa,OAAO,aAAa,KAAK;AACxC,QAAI,EAAE,SAAS,EAAE,KAAM,QAAO;AAC9B,eAAW,QAAQ,GAAG;AACpB,UAAI,CAAC,EAAE,IAAI,IAAI,EAAG,QAAO;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAQO,MAAM,0BAA0B,CACrC,IACA,QACA,WAC6B;AAC7B,MAAI,CAAC,UAAU,cAAc,MAAM,EAAG;AAItC,QAAM,wBAAwB,OAAO,OAAO,IAAI,eAAe,IAAI,OAAO,eAAe,EAAE,EAAE,gBAAgB,GAAG;AAEhH,QAAM,eAAe,kBAAkB,MAAM,SAAS;AAEtD,QAAM,cAAc,CAAC,MAAc,MAAe,qBAA8B;AAC9E,0BAAsB,KAAK,IAAI,MAAM,MAAM,gBAAgB;AAI3D,QACE,SAAS,iBAAiB,wBAC1B,SAAS,iBAAiB,mBAC1B,SAAS,iBAAiB;AAE1B;AAEF,QAAI,gBAAgB,CAAC,aAAa,IAAI,IAAI,EAAG;AAE7C,WAAO;AAAA,MACL,IAAI,YAAY,MAAM;AAAA,QACpB,SAAS;AAAA,QACT,UAAU;AAAA,QACV,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AAAA,EACF;AAGA,SAAO,eAAe,IAAI,iBAAiB;AAAA,IACzC,OAAO;AAAA,IACP,UAAU;AAAA,IACV,cAAc;AAAA,EAChB,CAAC;AAED,SAAO,MAAM;AACX,QAAI,OAAO,OAAO,IAAI,eAAe,KAAK,GAAG,kBAAkB,aAAa;AAI1E,aAAQ,GAAwD;AAAA,IAClE;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,36 @@
1
+ import type { ShaeEntElement } from './ShaeEntElement.js';
2
+ /**
3
+ * The `<slot>`s one entity element answers for.
4
+ *
5
+ * The owner asks it to take up what it finds — {@link HostedSlots.collect} on the way into the
6
+ * tree, {@link HostedSlots.takeUp} for a slot that reports — and to let go of everything at
7
+ * once with {@link HostedSlots.releaseAll}. Everything beyond that it decides for itself.
8
+ */
9
+ export declare class HostedSlots {
10
+ #private;
11
+ constructor(owner: ShaeEntElement);
12
+ /**
13
+ * Take up the `<slot>`s below this element that project something.
14
+ *
15
+ * A slot is answered for from the moment it reports an assignment, and an entity leaving the
16
+ * tree lets go of every slot it holds. Entering the tree is the counterpart: the entity takes
17
+ * up the slots below it, because the assignment inside a shadow root does not change while
18
+ * its host is out of the document — nothing reports on the way back in, so the entity has to
19
+ * look for itself.
20
+ *
21
+ * Only inside a shadow root, and that test is exact rather than an optimization: a `<slot>`
22
+ * in a node tree that is not a shadow tree has no assignment and never reports one, so there
23
+ * is nothing below such an element to take up.
24
+ */
25
+ collect(): void;
26
+ /**
27
+ * Take up the slot a `slotchange` names, if this element is the closest entity above it.
28
+ *
29
+ * `event.target` is the slot that reports, which is what the bubbling channel at the element
30
+ * carries — a different reading from the one {@link HostedSlots} makes of a `slotchange` on a
31
+ * slot it listens to itself, where the slot in question is the one the listener hangs on.
32
+ */
33
+ takeUp(event: Event): void;
34
+ releaseAll(): void;
35
+ }
36
+ //# sourceMappingURL=hostedSlots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hostedSlots.d.ts","sourceRoot":"","sources":["../../../src/elements/hostedSlots.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,qBAAqB,CAAC;AAiDxD;;;;;;GAMG;AACH,qBAAa,WAAW;;IAUtB,YAAY,KAAK,EAAE,cAAc,EAEhC;IAoDD;;;;;;;;;;;;OAYG;IACH,OAAO,SASN;IAED;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,EAAE,KAAK,QAgBlB;IAED,UAAU,SAKT;CACF"}