@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.
Files changed (210) hide show
  1. package/CHANGELOG.md +320 -61
  2. package/README.md +57 -13
  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 +39 -1
  36. package/src/elements/ShaeEntElement.d.ts.map +1 -1
  37. package/src/elements/ShaeEntElement.js +397 -167
  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 +52 -2
  44. package/src/elements/ShaePropElement.d.ts.map +1 -1
  45. package/src/elements/ShaePropElement.js +240 -219
  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 +204 -73
  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 +76 -17
  91. package/src/in-the-dark/Kernel.d.ts.map +1 -1
  92. package/src/in-the-dark/Kernel.js +410 -378
  93. package/src/in-the-dark/Kernel.js.map +3 -3
  94. package/src/in-the-dark/Registry.d.ts.map +1 -1
  95. package/src/in-the-dark/Registry.js +83 -14
  96. package/src/in-the-dark/Registry.js.map +2 -2
  97. package/src/in-the-dark/ShadowObject.d.ts.map +1 -1
  98. package/src/in-the-dark/ShadowObject.js +1 -0
  99. package/src/in-the-dark/ShadowObject.js.map +2 -2
  100. package/src/in-the-dark/ShadowObjectCreationScope.d.ts +126 -0
  101. package/src/in-the-dark/ShadowObjectCreationScope.d.ts.map +1 -0
  102. package/src/in-the-dark/ShadowObjectCreationScope.js +596 -0
  103. package/src/in-the-dark/ShadowObjectCreationScope.js.map +7 -0
  104. package/src/in-the-dark/SignalsPath.d.ts.map +1 -1
  105. package/src/in-the-dark/SignalsPath.js +2 -2
  106. package/src/in-the-dark/SignalsPath.js.map +2 -2
  107. package/src/in-the-dark/events.js.map +1 -1
  108. package/src/in-the-dark/importModule.d.ts +7 -0
  109. package/src/in-the-dark/importModule.d.ts.map +1 -1
  110. package/src/in-the-dark/importModule.js +5 -2
  111. package/src/in-the-dark/importModule.js.map +2 -2
  112. package/src/index.d.ts +7 -1
  113. package/src/index.d.ts.map +1 -1
  114. package/src/index.js +5 -1
  115. package/src/index.js.map +2 -2
  116. package/src/shadow-objects.d.ts +2 -0
  117. package/src/shadow-objects.d.ts.map +1 -1
  118. package/src/shadow-objects.js +2 -0
  119. package/src/shadow-objects.js.map +2 -2
  120. package/src/shadow-objects.worker.js +0 -1
  121. package/src/shadow-objects.worker.js.map +2 -2
  122. package/src/shae-ent.js.map +1 -1
  123. package/src/shae-prop.js +2 -2
  124. package/src/shae-prop.js.map +2 -2
  125. package/src/shae-worker.js.map +1 -1
  126. package/src/types.d.ts +35 -4
  127. package/src/types.d.ts.map +1 -1
  128. package/src/utils/ConsoleLogger.d.ts +45 -10
  129. package/src/utils/ConsoleLogger.d.ts.map +1 -1
  130. package/src/utils/ConsoleLogger.js +51 -26
  131. package/src/utils/ConsoleLogger.js.map +2 -2
  132. package/src/utils/FrameLoop.d.ts +42 -3
  133. package/src/utils/FrameLoop.d.ts.map +1 -1
  134. package/src/utils/FrameLoop.js +71 -10
  135. package/src/utils/FrameLoop.js.map +2 -2
  136. package/src/utils/MicrotaskCollector.d.ts +45 -0
  137. package/src/utils/MicrotaskCollector.d.ts.map +1 -0
  138. package/src/utils/MicrotaskCollector.js +33 -0
  139. package/src/utils/MicrotaskCollector.js.map +7 -0
  140. package/src/utils/MicrotaskGate.d.ts +17 -0
  141. package/src/utils/MicrotaskGate.d.ts.map +1 -0
  142. package/src/utils/MicrotaskGate.js +20 -0
  143. package/src/utils/MicrotaskGate.js.map +7 -0
  144. package/src/utils/array-utils.js.map +1 -1
  145. package/src/utils/attr-utils.d.ts +6 -0
  146. package/src/utils/attr-utils.d.ts.map +1 -1
  147. package/src/utils/attr-utils.js +3 -1
  148. package/src/utils/attr-utils.js.map +2 -2
  149. package/src/utils/constants.js.map +1 -1
  150. package/src/utils/generateUUID.d.ts +11 -0
  151. package/src/utils/generateUUID.d.ts.map +1 -1
  152. package/src/utils/generateUUID.js +31 -266
  153. package/src/utils/generateUUID.js.map +2 -2
  154. package/src/utils/props-utils.d.ts +3 -2
  155. package/src/utils/props-utils.d.ts.map +1 -1
  156. package/src/utils/props-utils.js +13 -24
  157. package/src/utils/props-utils.js.map +2 -2
  158. package/src/utils/runGuarded.d.ts +27 -0
  159. package/src/utils/runGuarded.d.ts.map +1 -0
  160. package/src/utils/runGuarded.js +11 -0
  161. package/src/utils/runGuarded.js.map +7 -0
  162. package/src/utils/toMaybe.d.ts.map +1 -1
  163. package/src/utils/toMaybe.js.map +1 -1
  164. package/src/utils/toNamespace.d.ts.map +1 -1
  165. package/src/utils/toNamespace.js.map +1 -1
  166. package/src/utils/toUrlString.d.ts +12 -0
  167. package/src/utils/toUrlString.d.ts.map +1 -1
  168. package/src/utils/toUrlString.js.map +2 -2
  169. package/src/utils/waitForMessageOfType.d.ts +12 -1
  170. package/src/utils/waitForMessageOfType.d.ts.map +1 -1
  171. package/src/utils/waitForMessageOfType.js +16 -1
  172. package/src/utils/waitForMessageOfType.js.map +2 -2
  173. package/src/view/ComponentChanges.d.ts +88 -1
  174. package/src/view/ComponentChanges.d.ts.map +1 -1
  175. package/src/view/ComponentChanges.js +243 -73
  176. package/src/view/ComponentChanges.js.map +2 -2
  177. package/src/view/ComponentContext.d.ts +206 -16
  178. package/src/view/ComponentContext.d.ts.map +1 -1
  179. package/src/view/ComponentContext.js +548 -91
  180. package/src/view/ComponentContext.js.map +2 -2
  181. package/src/view/ComponentMemory.d.ts +3 -3
  182. package/src/view/ComponentMemory.d.ts.map +1 -1
  183. package/src/view/ComponentMemory.js.map +1 -1
  184. package/src/view/IShadowObjectEnvProxy.d.ts +29 -3
  185. package/src/view/IShadowObjectEnvProxy.d.ts.map +1 -1
  186. package/src/view/LocalShadowObjectEnv.d.ts +1 -1
  187. package/src/view/LocalShadowObjectEnv.d.ts.map +1 -1
  188. package/src/view/LocalShadowObjectEnv.js +8 -6
  189. package/src/view/LocalShadowObjectEnv.js.map +2 -2
  190. package/src/view/RemoteWorkerEnv.d.ts +89 -5
  191. package/src/view/RemoteWorkerEnv.d.ts.map +1 -1
  192. package/src/view/RemoteWorkerEnv.js +195 -77
  193. package/src/view/RemoteWorkerEnv.js.map +2 -2
  194. package/src/view/ShadowEnv.d.ts +49 -2
  195. package/src/view/ShadowEnv.d.ts.map +1 -1
  196. package/src/view/ShadowEnv.js +223 -60
  197. package/src/view/ShadowEnv.js.map +2 -2
  198. package/src/view/ViewComponent.d.ts +78 -14
  199. package/src/view/ViewComponent.d.ts.map +1 -1
  200. package/src/view/ViewComponent.js +90 -14
  201. package/src/view/ViewComponent.js.map +2 -2
  202. package/src/view/cloneChangeTrail.js.map +2 -2
  203. package/src/worker/MessageRouter.d.ts +14 -0
  204. package/src/worker/MessageRouter.d.ts.map +1 -1
  205. package/src/worker/MessageRouter.js +75 -15
  206. package/src/worker/MessageRouter.js.map +2 -2
  207. package/src/worker/WorkerRuntime.d.ts +22 -1
  208. package/src/worker/WorkerRuntime.d.ts.map +1 -1
  209. package/src/worker/WorkerRuntime.js +60 -8
  210. package/src/worker/WorkerRuntime.js.map +2 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/elements/ShaeElement.ts"],
4
- "sourcesContent": ["import {createSignal, Signal} from '@spearwolf/signalize';\nimport {GlobalNS} from '../constants.js';\nimport type {NamespaceType} from '../types.ts';\nimport {readNamespaceAttribute} from '../utils/attr-utils.js';\nimport {toNamespace} from '../utils/toNamespace.js';\nimport {ShadowEnv} from '../view/ShadowEnv.js';\nimport {ATTR_NS} from './constants.js';\n\nconst updateNamespace = (el: HTMLElement, ns: Signal<NamespaceType>) => {\n ns.set(readNamespaceAttribute(el));\n};\n\nconst SyncNamespaces = new Set<NamespaceType>();\nlet nextSyncIsScheduled = false;\n\nconst syncShadowObjects = (ns: NamespaceType) => {\n SyncNamespaces.add(ns);\n if (!nextSyncIsScheduled) {\n nextSyncIsScheduled = true;\n queueMicrotask(() => {\n nextSyncIsScheduled = false;\n for (const ns of SyncNamespaces) {\n ShadowEnv.get(ns)?.sync();\n }\n SyncNamespaces.clear();\n });\n }\n};\n\nexport class ShaeElement extends HTMLElement {\n static observedAttributes = [ATTR_NS];\n\n readonly isShaeElement = true;\n\n readonly ns$ = createSignal<NamespaceType>(GlobalNS);\n\n get ns(): NamespaceType {\n return this.ns$.value;\n }\n\n set ns(ns: NamespaceType) {\n if (typeof ns === 'symbol') {\n this.ns$.set(ns);\n } else {\n this.ns$.set(toNamespace(ns));\n }\n }\n\n constructor() {\n super();\n\n this.ns$.onChange((ns) => {\n if (typeof ns === 'string' && ns.length > 0) {\n if (this.getAttribute(ATTR_NS) !== ns) {\n this.setAttribute(ATTR_NS, ns);\n }\n } else {\n this.removeAttribute(ATTR_NS);\n }\n });\n\n updateNamespace(this, this.ns$);\n }\n\n attributeChangedCallback(name: string) {\n if (name === ATTR_NS) {\n updateNamespace(this, this.ns$);\n }\n }\n\n syncShadowObjects() {\n syncShadowObjects(this.ns);\n }\n}"],
5
- "mappings": "AAAA,SAAQ,cAAc,cAAa;AACnC,SAAQ,gBAAe;AAEvB,SAAQ,8BAA6B;AACrC,SAAQ,mBAAkB;AAC1B,SAAQ,iBAAgB;AACxB,SAAQ,eAAc;AAEtB,MAAM,kBAAkB,CAAC,IAAiB,OAA8B;AACtE,KAAG,IAAI,uBAAuB,EAAE,CAAC;AACnC;AAEA,MAAM,iBAAiB,oBAAI,IAAmB;AAC9C,IAAI,sBAAsB;AAE1B,MAAM,oBAAoB,CAAC,OAAsB;AAC/C,iBAAe,IAAI,EAAE;AACrB,MAAI,CAAC,qBAAqB;AACxB,0BAAsB;AACtB,mBAAe,MAAM;AACnB,4BAAsB;AACtB,iBAAWA,OAAM,gBAAgB;AAC/B,kBAAU,IAAIA,GAAE,GAAG,KAAK;AAAA,MAC1B;AACA,qBAAe,MAAM;AAAA,IACvB,CAAC;AAAA,EACH;AACF;AAEO,MAAM,oBAAoB,YAAY;AAAA,EAmB3C,cAAc;AACZ,UAAM;AAjBR,SAAS,gBAAgB;AAEzB,SAAS,MAAM,aAA4B,QAAQ;AAiBjD,SAAK,IAAI,SAAS,CAAC,OAAO;AACxB,UAAI,OAAO,OAAO,YAAY,GAAG,SAAS,GAAG;AAC3C,YAAI,KAAK,aAAa,OAAO,MAAM,IAAI;AACrC,eAAK,aAAa,SAAS,EAAE;AAAA,QAC/B;AAAA,MACF,OAAO;AACL,aAAK,gBAAgB,OAAO;AAAA,MAC9B;AAAA,IACF,CAAC;AAED,oBAAgB,MAAM,KAAK,GAAG;AAAA,EAChC;AAAA,EAhCA;AAAA,SAAO,qBAAqB,CAAC,OAAO;AAAA;AAAA,EAMpC,IAAI,KAAoB;AACtB,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA,EAEA,IAAI,GAAG,IAAmB;AACxB,QAAI,OAAO,OAAO,UAAU;AAC1B,WAAK,IAAI,IAAI,EAAE;AAAA,IACjB,OAAO;AACL,WAAK,IAAI,IAAI,YAAY,EAAE,CAAC;AAAA,IAC9B;AAAA,EACF;AAAA,EAkBA,yBAAyB,MAAc;AACrC,QAAI,SAAS,SAAS;AACpB,sBAAgB,MAAM,KAAK,GAAG;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,oBAAoB;AAClB,sBAAkB,KAAK,EAAE;AAAA,EAC3B;AACF;",
6
- "names": ["ns"]
4
+ "sourcesContent": ["import {createSignal, hibernate, Signal} from '@spearwolf/signalize';\nimport {GlobalNS} from '../constants.js';\nimport type {NamespaceType} from '../types.js';\nimport {readNamespaceAttribute} from '../utils/attr-utils.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 {ShadowEnv} from '../view/ShadowEnv.js';\nimport {ATTR_NS} from './constants.js';\nimport {ShaeLifecycleElement} from './ShaeLifecycleElement.js';\n\nconst updateNamespace = (el: HTMLElement, ns: Signal<NamespaceType>) => {\n ns.set(readNamespaceAttribute(el));\n};\n\nconst logger = new ConsoleLogger('ShaeElement');\n\n// Module-wide, and one collector for every element in the realm: the key *is* the namespace and\n// `ShadowEnv.get(ns)` resolves it realm-wide, so two environments of one realm can take nothing\n// from each other here.\n//\n// One hand-over is one namespace: the call for each of them stands on its own, so none can take\n// the rest of the round with it, and what comes up while handing one over is reported instead of\n// carried out of the loop. What becomes of the trail is settled inside the environment, a\n// microtask later, and does not travel back through here.\nconst syncCollector = new MicrotaskCollector<NamespaceType>((namespaces) => {\n for (const ns of namespaces.keys()) {\n runGuarded(logger, () => ShadowEnv.get(ns)?.sync(), 'a namespace could not be synced:', ns);\n }\n});\n\nconst collectForSync = (ns: NamespaceType) => {\n syncCollector.add(ns);\n};\n\n/**\n * The base of the custom elements that pick an environment through their `ns` attribute.\n *\n * What it adds to {@link ShaeLifecycleElement} is the namespace: the `ns` attribute, the signal\n * behind it, the reflection back onto the attribute, and the two ways to hand an environment on to\n * the next sync. When such an element starts listening and when it lets go is the base's answer,\n * and it is the same answer `<shae-prop>` gets, which shares that base without this layer.\n */\nexport class ShaeElement extends ShaeLifecycleElement {\n static observedAttributes = [ATTR_NS];\n\n readonly isShaeElement = true;\n\n readonly ns$ = createSignal<NamespaceType>(GlobalNS);\n\n get ns(): NamespaceType {\n return this.ns$.value;\n }\n\n set ns(ns: NamespaceType) {\n if (typeof ns === 'symbol') {\n this.ns$.set(ns);\n } else {\n this.ns$.set(toNamespace(ns));\n }\n }\n\n /** Whether this element has been in a tree at least once. */\n #wasConnected = false;\n\n /** Attribute writes that came in before the first connect, the latest one per attribute. */\n #pendingReflections?: Map<string, () => void> | undefined;\n\n /** Takes the namespace reflection off again. */\n #nsReflection?: (() => void) | undefined;\n\n constructor() {\n super();\n\n // Nothing is listening at this point, and the read does not need anything to: it puts into the\n // signal what the attribute spells, normalised \u2014 `ns=\" local \"` becomes `local`. The\n // normalised value reaches the attribute at the first connect, where `restore()` writes every\n // reflecting signal back out.\n updateNamespace(this, this.ns$);\n }\n\n /**\n * Take up everything this element listens to.\n *\n * Private rather than overridable, and called from {@link ShaeElement.restore} alone: a subclass\n * extends the pair `restore()`/`teardown()`, which is where its own signals are there to be\n * subscribed to.\n */\n #subscribe(): void {\n this.#nsReflection = this.ns$.onChange((ns) => this.#reflectNamespace(ns));\n }\n\n #reflectNamespace(ns: NamespaceType): void {\n this.reflectAttribute(ATTR_NS, () => {\n if (typeof ns === 'string' && ns.length > 0) {\n if (this.getAttribute(ATTR_NS) !== ns) {\n this.setAttribute(ATTR_NS, ns);\n }\n } else {\n this.removeAttribute(ATTR_NS);\n }\n });\n }\n\n /**\n * Take the namespace subscription up, and catch up on what changed while nothing was listening.\n * The namespace half of {@link ShaeLifecycleElement.restore}.\n *\n * The catch-up is the half that is easy to leave out and expensive to miss. A released element\n * still takes writes \u2014 the signals are alive \u2014 but nothing carries them onto the attributes, so\n * the two drift apart. Writing the signal's value back here settles that before anything reads an\n * attribute again: without it, the attribute read on the way in would push the *old* value back\n * into the signal and the write would be lost without a word. At the first connect the same\n * write is what carries the normalisation of the constructor's attribute read onto the attribute.\n */\n protected override restore(): void {\n super.restore();\n\n this.#subscribe();\n this.#reflectNamespace(this.ns$.value);\n }\n\n /**\n * Writes an attribute back from a signal, or holds the write until the element first connects.\n *\n * A write is parked whenever it happens before the element has connected once \u2014 `restore()`'s\n * own writes on the very first connect are one source, carrying every reflecting signal out to\n * its attribute, including whatever the constructor's attribute read normalised; any other\n * write that lands ahead of that first connect is parked the same way. `restore()`'s call sits\n * in front of the gate on purpose: a `setAttribute` from inside it would re-enter\n * `attributeChangedCallback` while the subscriptions are still being set up, and running the\n * writes a few lines further on, once the element is whole, is cheaper than making every\n * subscription survive being read halfway through. A later write for the same attribute\n * replaces the parked one \u2014 only the value the signal ends up with is worth writing.\n *\n * What is written back on connect is what the signals already carry, so the\n * `attributeChangedCallback` it triggers sets each signal to the value it is already on. For a\n * signal holding a scalar that is no change and reaches no handler at all; for one holding a\n * fresh object on every read \u2014 `forward-custom-events` builds a new `Set` per read \u2014 the write\n * counts as a change by identity and the reflecting handler runs once more, where the guard on\n * the attribute value it already wrote stops the second write. Either way the attribute ends up\n * on the value the signal carries.\n */\n protected reflectAttribute(name: string, write: () => void): void {\n if (this.#wasConnected) {\n write();\n } else {\n this.#pendingReflections ??= new Map();\n this.#pendingReflections.set(name, write);\n }\n }\n\n override connectedCallback() {\n // the whole body outside whatever reactive context the caller is in, for the reason spelled out\n // in `ShaeLifecycleElement.connectedCallback`. Nesting is fine: `super.connectedCallback()`\n // opens a frame of its own inside this one\n hibernate(() => {\n super.connectedCallback();\n\n // the gate is \"has been connected once\", not \"is connected now\": what is held back is only\n // what accrues before the very first connect \u2014 the reflections `restore()` just wrote among\n // them, which is why the flag falls behind that call. An element between its teardown and its\n // return reflects nothing for a different reason \u2014 it has no reflecting handler at that\n // point, and `restore()` settles the difference on the way back in. And the flag is set\n // before the parked writes run, so a write that triggers another one goes straight through\n // instead of landing in a map nobody reads again\n this.#wasConnected = true;\n\n const pending = this.#pendingReflections;\n this.#pendingReflections = undefined;\n if (pending) {\n for (const write of pending.values()) {\n write();\n }\n }\n });\n }\n\n /**\n * Release the namespace reflection. The namespace half of {@link ShaeLifecycleElement.teardown}.\n *\n * `#pendingReflections` is left alone on purpose: it holds every write parked before the\n * element's first connect, and that connect is what drains it \u2014 a `destroy()` reached first\n * leaves the map standing for whichever connect comes next.\n */\n protected override teardown(): void {\n this.#nsReflection?.();\n this.#nsReflection = undefined;\n\n super.teardown();\n }\n\n attributeChangedCallback(name: string) {\n if (name === ATTR_NS) {\n updateNamespace(this, this.ns$);\n }\n }\n\n /**\n * Hand the environment of this element's namespace on to the next `sync()` \u2014 the unconfirmed\n * path.\n *\n * Over a worker it learns nothing of a confirmation the Shadow Environment refused, and no\n * `syncfailed` event follows. Whoever needs to know switches `auto-sync` off and runs\n * `syncWait()` from their own loop.\n */\n syncShadowObjects() {\n collectForSync(this.ns);\n }\n\n /**\n * Sync the environment of `ns` instead of the one this element sits in right now.\n *\n * For the moment an element changes namespaces: the environment it leaves has a change trail\n * waiting for it, and `this.ns` no longer points at it.\n */\n protected syncShadowObjectsOf(ns: NamespaceType) {\n collectForSync(ns);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
7
  }
@@ -1,3 +1,4 @@
1
+ import { ConsoleLogger } from '../utils/ConsoleLogger.js';
1
2
  import { ComponentContext } from '../view/ComponentContext.js';
2
3
  import { ViewComponent } from '../view/ViewComponent.js';
3
4
  import { ShaeElement } from './ShaeElement.js';
@@ -9,18 +10,55 @@ export declare class ShaeEntElement extends ShaeElement {
9
10
  readonly viewComponent$: import("@spearwolf/signalize").Signal<ViewComponent | undefined>;
10
11
  readonly token$: import("@spearwolf/signalize").Signal<string | undefined>;
11
12
  readonly forwardCustomEvents$: import("@spearwolf/signalize").Signal<boolean | Set<string>>;
13
+ /** The logger this element reports through: a subclass reads it and does not replace it. */
14
+ protected get logger(): ConsoleLogger;
12
15
  get componentContext(): ComponentContext | undefined;
13
16
  get viewComponent(): ViewComponent | undefined;
14
17
  get uuid(): string | undefined;
15
18
  get token(): string | undefined;
16
19
  set token(token: string | undefined);
17
- entParentNode?: ShaeEntElement;
20
+ entParentNode?: ShaeEntElement | undefined;
18
21
  constructor();
22
+ /**
23
+ * Take the subscriptions up and settle what drifted while none of them were listening.
24
+ *
25
+ * Runs on the first connect, where this element has never listened to anything, and again for one
26
+ * that comes back after a teardown.
27
+ *
28
+ * The three catch-up calls are not decoration. A released element still takes writes, so `token`,
29
+ * `ns` and `forward-custom-events` can each stand on a value its attribute never heard about —
30
+ * and `connectedCallback` reads exactly those attributes back into exactly those signals a few
31
+ * lines further on. Without the catch-up that read would overwrite the newer value with the older
32
+ * one, and the entity would go on carrying a token nobody wrote.
33
+ *
34
+ * `super.restore()` runs first and takes `ns` with it. That it writes the `ns` attribute before
35
+ * this class has re-subscribed to `ns$` costs nothing: the write puts the value the signal
36
+ * already holds onto the attribute, so the read it triggers changes no signal and reaches no
37
+ * handler.
38
+ */
39
+ protected restore(): void;
19
40
  findShadowRootHost(): HTMLElement | undefined;
20
41
  protected getParentNodeForObserver(): Node | undefined;
21
42
  connectedCallback(): void;
22
43
  onParentChanged(_newParent: Node | undefined, _oldParent: Node): void;
23
44
  attributeChangedCallback(name: string): void;
24
45
  disconnectedCallback(): void;
46
+ /**
47
+ * Let go of everything this element listens to, and leave what it is made of standing.
48
+ *
49
+ * The signals are not destroyed — they are what carries this element's state across a teardown,
50
+ * and {@link ShaeEntElement.restore} subscribes to them again on the way back in.
51
+ *
52
+ * The `ViewComponent` stays too. `disconnectedCallback` has already taken it out of its
53
+ * `ComponentContext`, which is what unbinds it from this element's position; ending it on top of
54
+ * that would write a destroy entry into the change trail and take the entity down in the worker
55
+ * — a decision about the entity, not about this element. It is also what lets an element that
56
+ * comes back carry the same entity and the same uuid it left with.
57
+ *
58
+ * Both effects run their cleanup on `destroy()`, which is what this depends on: the one on the
59
+ * `dispatchEvent` patch has to, or the patched function would go on holding the component and
60
+ * everything reachable from it.
61
+ */
62
+ protected teardown(): void;
25
63
  }
26
64
  //# sourceMappingURL=ShaeEntElement.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ShaeEntElement.d.ts","sourceRoot":"","sources":["../../../src/elements/ShaeEntElement.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AAE7D,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAE7C,qBAAa,cAAe,SAAQ,WAAW;;IAC7C,OAAgB,kBAAkB,WAA+E;IAEjH,QAAQ,CAAC,gBAAgB,QAAQ;IAEjC,QAAQ,CAAC,iBAAiB,sEAAgD;IAC1E,QAAQ,CAAC,cAAc,mEAA6C;IACpE,QAAQ,CAAC,MAAM,4DAAsC;IACrD,QAAQ,CAAC,oBAAoB,+DAA8C;IAE3E,IAAI,gBAAgB,IAAI,gBAAgB,GAAG,SAAS,CAEnD;IAED,IAAI,aAAa,IAAI,aAAa,GAAG,SAAS,CAE7C;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;IAED,IAAI,KAAK,IAAI,MAAM,GAAG,SAAS,CAE9B;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAElC;IAED,aAAa,CAAC,EAAE,cAAc,CAAC;;IAoJ/B,kBAAkB,IAAI,WAAW,GAAG,SAAS;IAmB7C,SAAS,CAAC,wBAAwB,IAAI,IAAI,GAAG,SAAS;IAOtD,iBAAiB;IAmDjB,eAAe,CAAC,UAAU,EAAE,IAAI,GAAG,SAAS,EAAE,UAAU,EAAE,IAAI;IAUrD,wBAAwB,CAAC,IAAI,EAAE,MAAM;IAS9C,oBAAoB;CAgJrB"}
1
+ {"version":3,"file":"ShaeEntElement.d.ts","sourceRoot":"","sources":["../../../src/elements/ShaeEntElement.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,aAAa,EAAC,MAAM,2BAA2B,CAAC;AAExD,OAAO,EAAC,gBAAgB,EAAC,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAavD,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAiD7C,qBAAa,cAAe,SAAQ,WAAW;;IAC7C,OAAgB,kBAAkB,WAA+E;IAEjH,QAAQ,CAAC,gBAAgB,QAAQ;IAEjC,QAAQ,CAAC,iBAAiB,sEAAgD;IAC1E,QAAQ,CAAC,cAAc,mEAA6C;IACpE,QAAQ,CAAC,MAAM,4DAAsC;IACrD,QAAQ,CAAC,oBAAoB,+DAA8C;IAI3E,4FAA4F;IAC5F,SAAS,KAAK,MAAM,IAAI,aAAa,CAEpC;IAED,IAAI,gBAAgB,IAAI,gBAAgB,GAAG,SAAS,CAEnD;IAED,IAAI,aAAa,IAAI,aAAa,GAAG,SAAS,CAE7C;IAED,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;IAED,IAAI,KAAK,IAAI,MAAM,GAAG,SAAS,CAE9B;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAElC;IAED,aAAa,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IAuD3C,cAOC;IAgID;;;;;;;;;;;;;;;;OAgBG;IACH,UAAmB,OAAO,IAAI,IAAI,CAOjC;IAuED,kBAAkB,IAAI,WAAW,GAAG,SAAS,CAM5C;IAED,SAAS,CAAC,wBAAwB,IAAI,IAAI,GAAG,SAAS,CAKrD;IAEQ,iBAAiB,SA0EzB;IA8ED,eAAe,CAAC,UAAU,EAAE,IAAI,GAAG,SAAS,EAAE,UAAU,EAAE,IAAI,QAO7D;IAEQ,wBAAwB,CAAC,IAAI,EAAE,MAAM,QAO7C;IAEQ,oBAAoB,SAwC5B;IAED;;;;;;;;;;;;;;;OAeG;IACH,UAAmB,QAAQ,SA2C1B;CAsOF"}