@llui/dom 0.0.20 → 0.0.22

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 (106) hide show
  1. package/README.md +16 -14
  2. package/dist/addressed.d.ts +1 -1
  3. package/dist/addressed.d.ts.map +1 -1
  4. package/dist/addressed.js.map +1 -1
  5. package/dist/binding.d.ts +2 -2
  6. package/dist/binding.d.ts.map +1 -1
  7. package/dist/binding.js +2 -2
  8. package/dist/binding.js.map +1 -1
  9. package/dist/devtools.d.ts +3 -3
  10. package/dist/devtools.d.ts.map +1 -1
  11. package/dist/devtools.js +14 -12
  12. package/dist/devtools.js.map +1 -1
  13. package/dist/el-split.js +3 -3
  14. package/dist/el-split.js.map +1 -1
  15. package/dist/el-template.js +3 -3
  16. package/dist/el-template.js.map +1 -1
  17. package/dist/elements.js +1 -1
  18. package/dist/elements.js.map +1 -1
  19. package/dist/hmr.d.ts +1 -1
  20. package/dist/hmr.d.ts.map +1 -1
  21. package/dist/hmr.js +6 -6
  22. package/dist/hmr.js.map +1 -1
  23. package/dist/index.d.ts +5 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/internal.d.ts +1 -1
  28. package/dist/internal.d.ts.map +1 -1
  29. package/dist/internal.js +1 -1
  30. package/dist/internal.js.map +1 -1
  31. package/dist/lifetime.d.ts +39 -0
  32. package/dist/lifetime.d.ts.map +1 -0
  33. package/dist/lifetime.js +250 -0
  34. package/dist/lifetime.js.map +1 -0
  35. package/dist/mathml-elements.js +1 -1
  36. package/dist/mathml-elements.js.map +1 -1
  37. package/dist/mount.d.ts +11 -9
  38. package/dist/mount.d.ts.map +1 -1
  39. package/dist/mount.js +15 -31
  40. package/dist/mount.js.map +1 -1
  41. package/dist/primitives/branch.d.ts +1 -1
  42. package/dist/primitives/branch.d.ts.map +1 -1
  43. package/dist/primitives/branch.js +30 -20
  44. package/dist/primitives/branch.js.map +1 -1
  45. package/dist/primitives/child.js +12 -12
  46. package/dist/primitives/child.js.map +1 -1
  47. package/dist/primitives/context.js +6 -6
  48. package/dist/primitives/context.js.map +1 -1
  49. package/dist/primitives/each.d.ts.map +1 -1
  50. package/dist/primitives/each.js +37 -32
  51. package/dist/primitives/each.js.map +1 -1
  52. package/dist/primitives/error-boundary.js +7 -7
  53. package/dist/primitives/error-boundary.js.map +1 -1
  54. package/dist/primitives/foreign.js +3 -3
  55. package/dist/primitives/foreign.js.map +1 -1
  56. package/dist/primitives/lazy.js +11 -11
  57. package/dist/primitives/lazy.js.map +1 -1
  58. package/dist/primitives/on-mount.js +2 -2
  59. package/dist/primitives/on-mount.js.map +1 -1
  60. package/dist/primitives/portal.js +4 -4
  61. package/dist/primitives/portal.js.map +1 -1
  62. package/dist/primitives/sample.d.ts +18 -0
  63. package/dist/primitives/sample.d.ts.map +1 -0
  64. package/dist/primitives/sample.js +22 -0
  65. package/dist/primitives/sample.js.map +1 -0
  66. package/dist/primitives/scope.d.ts +25 -0
  67. package/dist/primitives/scope.d.ts.map +1 -0
  68. package/dist/primitives/scope.js +36 -0
  69. package/dist/primitives/scope.js.map +1 -0
  70. package/dist/primitives/selector.js +4 -4
  71. package/dist/primitives/selector.js.map +1 -1
  72. package/dist/primitives/show.d.ts.map +1 -1
  73. package/dist/primitives/show.js +4 -1
  74. package/dist/primitives/show.js.map +1 -1
  75. package/dist/primitives/slice.d.ts.map +1 -1
  76. package/dist/primitives/slice.js +18 -2
  77. package/dist/primitives/slice.js.map +1 -1
  78. package/dist/primitives/text.js +3 -3
  79. package/dist/primitives/text.js.map +1 -1
  80. package/dist/primitives/virtual-each.d.ts.map +1 -1
  81. package/dist/primitives/virtual-each.js +9 -9
  82. package/dist/primitives/virtual-each.js.map +1 -1
  83. package/dist/render-context.d.ts +2 -2
  84. package/dist/render-context.d.ts.map +1 -1
  85. package/dist/render-context.js.map +1 -1
  86. package/dist/ssr.d.ts +4 -4
  87. package/dist/ssr.d.ts.map +1 -1
  88. package/dist/ssr.js +3 -3
  89. package/dist/ssr.js.map +1 -1
  90. package/dist/svg-elements.js +1 -1
  91. package/dist/svg-elements.js.map +1 -1
  92. package/dist/tracking/disposer-log.d.ts +4 -4
  93. package/dist/tracking/disposer-log.d.ts.map +1 -1
  94. package/dist/tracking/disposer-log.js.map +1 -1
  95. package/dist/types.d.ts +79 -10
  96. package/dist/types.d.ts.map +1 -1
  97. package/dist/types.js.map +1 -1
  98. package/dist/update-loop.d.ts +3 -3
  99. package/dist/update-loop.d.ts.map +1 -1
  100. package/dist/update-loop.js +12 -8
  101. package/dist/update-loop.js.map +1 -1
  102. package/dist/view-helpers.d.ts +10 -2
  103. package/dist/view-helpers.d.ts.map +1 -1
  104. package/dist/view-helpers.js +4 -0
  105. package/dist/view-helpers.js.map +1 -1
  106. package/package.json +1 -1
package/dist/hmr.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { flushInstance } from './update-loop.js';
2
- import { createScope, disposeScope } from './scope.js';
2
+ import { createLifetime, disposeLifetime } from './lifetime.js';
3
3
  import { setRenderContext, clearRenderContext } from './render-context.js';
4
4
  import { setFlatBindings } from './binding.js';
5
5
  import { unregisterInstance } from './runtime.js';
@@ -65,7 +65,7 @@ export function replaceComponent(name, newDef) {
65
65
  __update: newDef.__update,
66
66
  __handlers: newDef.__handlers,
67
67
  };
68
- disposeScope(typedInst.rootScope);
68
+ disposeLifetime(typedInst.rootLifetime);
69
69
  // Clear the owned region per-kind.
70
70
  if (entry.kind === 'container') {
71
71
  entry.container.textContent = '';
@@ -80,13 +80,13 @@ export function replaceComponent(name, newDef) {
80
80
  sib = next;
81
81
  }
82
82
  }
83
- typedInst.rootScope = createScope(null);
84
- typedInst.rootScope._kind = 'root';
83
+ typedInst.rootLifetime = createLifetime(null);
84
+ typedInst.rootLifetime._kind = 'root';
85
85
  typedInst.allBindings = [];
86
86
  typedInst.structuralBlocks = [];
87
87
  setFlatBindings(typedInst.allBindings);
88
88
  setRenderContext({
89
- rootScope: typedInst.rootScope,
89
+ rootLifetime: typedInst.rootLifetime,
90
90
  state: typedInst.state,
91
91
  allBindings: typedInst.allBindings,
92
92
  structuralBlocks: typedInst.structuralBlocks,
@@ -120,7 +120,7 @@ function makeReplacementHandle(name, entry, typedInst) {
120
120
  unregisterForHmr(name, entry.inst);
121
121
  entry.inst.abortController.abort();
122
122
  unregisterInstance(entry.inst);
123
- disposeScope(typedInst.rootScope);
123
+ disposeLifetime(typedInst.rootLifetime);
124
124
  if (entry.kind === 'container') {
125
125
  entry.container.textContent = '';
126
126
  }
package/dist/hmr.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hmr.js","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ComponentDef, AppHandle } from './types.js'\nimport type { ComponentInstance } from './update-loop.js'\nimport { flushInstance } from './update-loop.js'\nimport { createScope, disposeScope } from './scope.js'\nimport { setRenderContext, clearRenderContext } from './render-context.js'\nimport { setFlatBindings } from './binding.js'\nimport { unregisterInstance } from './runtime.js'\nimport { _setHmrModule } from './mount.js'\nimport { createView } from './view-helpers.js'\n\n/**\n * Enable HMR state preservation. Called by compiler-generated dev code.\n * Importing this module registers it with mountApp for hot-swapping.\n */\nexport function enableHmr(): void {\n _setHmrModule({\n enableHmr,\n registerForHmr,\n registerForAnchor,\n unregisterForHmr,\n replaceComponent,\n })\n}\n\n// ── HMR Registry ─────────────────────────────────────────────────\n\ntype HmrEntry =\n | {\n kind: 'container'\n inst: ComponentInstance\n container: HTMLElement\n }\n | {\n kind: 'anchor'\n inst: ComponentInstance\n anchor: Comment\n endSentinel: Comment\n }\n\nconst hmrRegistry = new Map<string, HmrEntry[]>()\n\nexport function registerForHmr(name: string, inst: object, container: HTMLElement): void {\n const entries = hmrRegistry.get(name) ?? []\n entries.push({ kind: 'container', inst: inst as ComponentInstance, container })\n hmrRegistry.set(name, entries)\n}\n\nexport function registerForAnchor(\n name: string,\n inst: object,\n anchor: Comment,\n endSentinel: Comment,\n): void {\n const entries = hmrRegistry.get(name) ?? []\n entries.push({ kind: 'anchor', inst: inst as ComponentInstance, anchor, endSentinel })\n hmrRegistry.set(name, entries)\n}\n\nexport function unregisterForHmr(name: string, inst: object): void {\n const entries = hmrRegistry.get(name)\n if (!entries) return\n const idx = entries.findIndex((e) => e.inst === inst)\n if (idx !== -1) entries.splice(idx, 1)\n if (entries.length === 0) hmrRegistry.delete(name)\n}\n\n/**\n * Hot-swap a component definition on all live instances.\n *\n * Preserves the current state. Replaces update, view, onEffect, and __dirty.\n * Disposes the old scope tree (removing old DOM and bindings),\n * re-runs view(currentState, send) to rebuild fresh DOM.\n *\n * Returns an AppHandle for the first instance (for mountApp compatibility),\n * or null if no instances are registered (first mount).\n */\nexport function replaceComponent<S, M, E>(\n name: string,\n newDef: ComponentDef<S, M, E>,\n): AppHandle | null {\n const entries = hmrRegistry.get(name)\n if (!entries || entries.length === 0) return null\n\n let handle: AppHandle | null = null\n\n for (const entry of entries) {\n const typedInst = entry.inst as ComponentInstance<S, M, E>\n\n typedInst.def = {\n ...typedInst.def,\n update: newDef.update,\n view: newDef.view,\n onEffect: newDef.onEffect,\n __dirty: newDef.__dirty,\n __update: newDef.__update,\n __handlers: newDef.__handlers,\n }\n\n disposeScope(typedInst.rootScope)\n\n // Clear the owned region per-kind.\n if (entry.kind === 'container') {\n entry.container.textContent = ''\n } else {\n // anchor kind — wipe siblings between anchor and endSentinel, keep the\n // anchor AND the end sentinel (they bracket the fresh render).\n let sib = entry.anchor.nextSibling\n while (sib !== null && sib !== entry.endSentinel) {\n const next = sib.nextSibling\n sib.parentNode!.removeChild(sib)\n sib = next\n }\n }\n\n typedInst.rootScope = createScope(null)\n typedInst.rootScope._kind = 'root'\n typedInst.allBindings = []\n typedInst.structuralBlocks = []\n\n setFlatBindings(typedInst.allBindings)\n setRenderContext({\n rootScope: typedInst.rootScope,\n state: typedInst.state,\n allBindings: typedInst.allBindings,\n structuralBlocks: typedInst.structuralBlocks,\n container:\n entry.kind === 'container' ? entry.container : (entry.anchor.parentElement ?? undefined),\n send: typedInst.send as (msg: unknown) => void,\n instance: typedInst as ComponentInstance,\n })\n const nodes = typedInst.def.view(createView<S, M>(typedInst.send))\n clearRenderContext()\n setFlatBindings(null)\n\n if (entry.kind === 'container') {\n for (const node of nodes) {\n entry.container.appendChild(node)\n }\n } else {\n for (const node of nodes) {\n entry.anchor.parentNode!.insertBefore(node, entry.endSentinel)\n }\n }\n\n if (!handle) {\n handle = makeReplacementHandle(name, entry, typedInst)\n }\n }\n\n console.log(`[LLui HMR] ${name} updated — state preserved`)\n\n return handle\n}\n\nfunction makeReplacementHandle<S, M, E>(\n name: string,\n entry: HmrEntry,\n typedInst: ComponentInstance<S, M, E>,\n): AppHandle {\n return {\n dispose() {\n unregisterForHmr(name, entry.inst)\n entry.inst.abortController.abort()\n unregisterInstance(entry.inst)\n disposeScope(typedInst.rootScope)\n if (entry.kind === 'container') {\n entry.container.textContent = ''\n } else {\n let sib = entry.anchor.nextSibling\n while (sib !== null && sib !== entry.endSentinel) {\n const next = sib.nextSibling\n sib.parentNode!.removeChild(sib)\n sib = next\n }\n entry.endSentinel.parentNode?.removeChild(entry.endSentinel)\n }\n },\n flush() {\n flushInstance(entry.inst)\n },\n send(msg: unknown) {\n ;(typedInst.send as (m: unknown) => void)(msg)\n },\n }\n}\n"]}
1
+ {"version":3,"file":"hmr.js","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ComponentDef, AppHandle } from './types.js'\nimport type { ComponentInstance } from './update-loop.js'\nimport { flushInstance } from './update-loop.js'\nimport { createLifetime, disposeLifetime } from './lifetime.js'\nimport { setRenderContext, clearRenderContext } from './render-context.js'\nimport { setFlatBindings } from './binding.js'\nimport { unregisterInstance } from './runtime.js'\nimport { _setHmrModule } from './mount.js'\nimport { createView } from './view-helpers.js'\n\n/**\n * Enable HMR state preservation. Called by compiler-generated dev code.\n * Importing this module registers it with mountApp for hot-swapping.\n */\nexport function enableHmr(): void {\n _setHmrModule({\n enableHmr,\n registerForHmr,\n registerForAnchor,\n unregisterForHmr,\n replaceComponent,\n })\n}\n\n// ── HMR Registry ─────────────────────────────────────────────────\n\ntype HmrEntry =\n | {\n kind: 'container'\n inst: ComponentInstance\n container: HTMLElement\n }\n | {\n kind: 'anchor'\n inst: ComponentInstance\n anchor: Comment\n endSentinel: Comment\n }\n\nconst hmrRegistry = new Map<string, HmrEntry[]>()\n\nexport function registerForHmr(name: string, inst: object, container: HTMLElement): void {\n const entries = hmrRegistry.get(name) ?? []\n entries.push({ kind: 'container', inst: inst as ComponentInstance, container })\n hmrRegistry.set(name, entries)\n}\n\nexport function registerForAnchor(\n name: string,\n inst: object,\n anchor: Comment,\n endSentinel: Comment,\n): void {\n const entries = hmrRegistry.get(name) ?? []\n entries.push({ kind: 'anchor', inst: inst as ComponentInstance, anchor, endSentinel })\n hmrRegistry.set(name, entries)\n}\n\nexport function unregisterForHmr(name: string, inst: object): void {\n const entries = hmrRegistry.get(name)\n if (!entries) return\n const idx = entries.findIndex((e) => e.inst === inst)\n if (idx !== -1) entries.splice(idx, 1)\n if (entries.length === 0) hmrRegistry.delete(name)\n}\n\n/**\n * Hot-swap a component definition on all live instances.\n *\n * Preserves the current state. Replaces update, view, onEffect, and __dirty.\n * Disposes the old scope tree (removing old DOM and bindings),\n * re-runs view(currentState, send) to rebuild fresh DOM.\n *\n * Returns an AppHandle for the first instance (for mountApp compatibility),\n * or null if no instances are registered (first mount).\n */\nexport function replaceComponent<S, M, E, D = void>(\n name: string,\n newDef: ComponentDef<S, M, E, D>,\n): AppHandle | null {\n const entries = hmrRegistry.get(name)\n if (!entries || entries.length === 0) return null\n\n let handle: AppHandle | null = null\n\n for (const entry of entries) {\n const typedInst = entry.inst as ComponentInstance<S, M, E>\n\n typedInst.def = {\n ...typedInst.def,\n update: newDef.update,\n view: newDef.view,\n onEffect: newDef.onEffect,\n __dirty: newDef.__dirty,\n __update: newDef.__update,\n __handlers: newDef.__handlers,\n }\n\n disposeLifetime(typedInst.rootLifetime)\n\n // Clear the owned region per-kind.\n if (entry.kind === 'container') {\n entry.container.textContent = ''\n } else {\n // anchor kind — wipe siblings between anchor and endSentinel, keep the\n // anchor AND the end sentinel (they bracket the fresh render).\n let sib = entry.anchor.nextSibling\n while (sib !== null && sib !== entry.endSentinel) {\n const next = sib.nextSibling\n sib.parentNode!.removeChild(sib)\n sib = next\n }\n }\n\n typedInst.rootLifetime = createLifetime(null)\n typedInst.rootLifetime._kind = 'root'\n typedInst.allBindings = []\n typedInst.structuralBlocks = []\n\n setFlatBindings(typedInst.allBindings)\n setRenderContext({\n rootLifetime: typedInst.rootLifetime,\n state: typedInst.state,\n allBindings: typedInst.allBindings,\n structuralBlocks: typedInst.structuralBlocks,\n container:\n entry.kind === 'container' ? entry.container : (entry.anchor.parentElement ?? undefined),\n send: typedInst.send as (msg: unknown) => void,\n instance: typedInst as ComponentInstance,\n })\n const nodes = typedInst.def.view(createView<S, M>(typedInst.send))\n clearRenderContext()\n setFlatBindings(null)\n\n if (entry.kind === 'container') {\n for (const node of nodes) {\n entry.container.appendChild(node)\n }\n } else {\n for (const node of nodes) {\n entry.anchor.parentNode!.insertBefore(node, entry.endSentinel)\n }\n }\n\n if (!handle) {\n handle = makeReplacementHandle(name, entry, typedInst)\n }\n }\n\n console.log(`[LLui HMR] ${name} updated — state preserved`)\n\n return handle\n}\n\nfunction makeReplacementHandle<S, M, E>(\n name: string,\n entry: HmrEntry,\n typedInst: ComponentInstance<S, M, E>,\n): AppHandle {\n return {\n dispose() {\n unregisterForHmr(name, entry.inst)\n entry.inst.abortController.abort()\n unregisterInstance(entry.inst)\n disposeLifetime(typedInst.rootLifetime)\n if (entry.kind === 'container') {\n entry.container.textContent = ''\n } else {\n let sib = entry.anchor.nextSibling\n while (sib !== null && sib !== entry.endSentinel) {\n const next = sib.nextSibling\n sib.parentNode!.removeChild(sib)\n sib = next\n }\n entry.endSentinel.parentNode?.removeChild(entry.endSentinel)\n }\n },\n flush() {\n flushInstance(entry.inst)\n },\n send(msg: unknown) {\n ;(typedInst.send as (m: unknown) => void)(msg)\n },\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export type { ComponentDef, Send, Props, AppHandle, Scope, Binding, BindingKind, TransitionOptions, BranchOptions, ShowOptions, EachOptions, ItemAccessor, PortalOptions, ForeignOptions, ChildOptions, } from './types.js';
1
+ export type { ComponentDef, Send, Props, AppHandle, Lifetime, Binding, BindingKind, TransitionOptions, BranchOptions, ShowOptions, EachOptions, ItemAccessor, PortalOptions, ForeignOptions, ChildOptions, } from './types.js';
2
2
  export { component } from './component.js';
3
3
  export { createView, type View } from './view-helpers.js';
4
4
  export { mountApp, hydrateApp, mountAtAnchor, hydrateAtAnchor, type MountOptions } from './mount.js';
@@ -7,7 +7,7 @@ export type { CoverageSnapshot } from './tracking/coverage.js';
7
7
  export type { EachDiff } from './tracking/each-diff.js';
8
8
  export type { DisposerEvent } from './tracking/disposer-log.js';
9
9
  export type { PendingEffect, EffectTimelineEntry, EffectMatch } from './tracking/effect-timeline.js';
10
- export type { ScopeNode } from './types.js';
10
+ export type { LifetimeNode } from './types.js';
11
11
  export { flush } from './runtime.js';
12
12
  export { addressOf } from './addressed.js';
13
13
  export { renderToString, renderNodes, serializeNodes } from './ssr.js';
@@ -21,6 +21,8 @@ export { branch } from './primitives/branch.js';
21
21
  export { each } from './primitives/each.js';
22
22
  export { virtualEach, type VirtualEachOptions } from './primitives/virtual-each.js';
23
23
  export { show } from './primitives/show.js';
24
+ export { scope } from './primitives/scope.js';
25
+ export type { ScopeOptions } from './types.js';
24
26
  export { slice } from './primitives/slice.js';
25
27
  export { portal } from './primitives/portal.js';
26
28
  export { foreign } from './primitives/foreign.js';
@@ -28,6 +30,7 @@ export { child } from './primitives/child.js';
28
30
  export { lazy, type LazyOptions } from './primitives/lazy.js';
29
31
  export type { LazyDef, AnyComponentDef } from './types.js';
30
32
  export { memo } from './primitives/memo.js';
33
+ export { sample } from './primitives/sample.js';
31
34
  export { selector } from './primitives/selector.js';
32
35
  export { onMount } from './primitives/on-mount.js';
33
36
  export { errorBoundary } from './primitives/error-boundary.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -19,12 +19,14 @@ export { branch } from './primitives/branch.js';
19
19
  export { each } from './primitives/each.js';
20
20
  export { virtualEach } from './primitives/virtual-each.js';
21
21
  export { show } from './primitives/show.js';
22
+ export { scope } from './primitives/scope.js';
22
23
  export { slice } from './primitives/slice.js';
23
24
  export { portal } from './primitives/portal.js';
24
25
  export { foreign } from './primitives/foreign.js';
25
26
  export { child } from './primitives/child.js';
26
27
  export { lazy } from './primitives/lazy.js';
27
28
  export { memo } from './primitives/memo.js';
29
+ export { sample } from './primitives/sample.js';
28
30
  export { selector } from './primitives/selector.js';
29
31
  export { onMount } from './primitives/on-mount.js';
30
32
  export { errorBoundary } from './primitives/error-boundary.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// ── Types ─────────────────────────────────────────────────────────\n\nexport type {\n ComponentDef,\n Send,\n Props,\n AppHandle,\n Scope,\n Binding,\n BindingKind,\n TransitionOptions,\n BranchOptions,\n ShowOptions,\n EachOptions,\n ItemAccessor,\n PortalOptions,\n ForeignOptions,\n ChildOptions,\n} from './types.js'\n\n// ── Component ─────────────────────────────────────────────────────\n\nexport { component } from './component.js'\nexport { createView, type View } from './view-helpers.js'\n\n// ── Mount ─────────────────────────────────────────────────────────\n\nexport { mountApp, hydrateApp, mountAtAnchor, hydrateAtAnchor, type MountOptions } from './mount.js'\n// installDevTools is NOT re-exported here to keep it out of production bundles.\n// Import directly: import { installDevTools } from '@llui/dom/devtools'\nexport type { LluiDebugAPI, ElementReport, MessageRecord, StateDiff } from './devtools.js'\nexport type { CoverageSnapshot } from './tracking/coverage.js'\nexport type { EachDiff } from './tracking/each-diff.js'\nexport type { DisposerEvent } from './tracking/disposer-log.js'\nexport type { PendingEffect, EffectTimelineEntry, EffectMatch } from './tracking/effect-timeline.js'\nexport type { ScopeNode } from './types.js'\n\n// ── Runtime ───────────────────────────────────────────────────────\n\nexport { flush } from './runtime.js'\nexport { addressOf } from './addressed.js'\nexport { renderToString, renderNodes, serializeNodes } from './ssr.js'\nexport { mergeHandlers } from './merge-handlers.js'\nexport {\n createContext,\n provide,\n provideValue,\n useContext,\n useContextValue,\n type Context,\n} from './primitives/context.js'\nexport { sliceHandler } from './slice-handler.js'\nexport {\n childHandlers,\n type ChildState,\n type ChildMsg,\n type ModuleState,\n type ModuleMsg,\n} from './compose.js'\n\n// ── View Primitives ───────────────────────────────────────────────\n\nexport { text } from './primitives/text.js'\nexport { unsafeHtml } from './primitives/unsafe-html.js'\nexport { branch } from './primitives/branch.js'\nexport { each } from './primitives/each.js'\nexport { virtualEach, type VirtualEachOptions } from './primitives/virtual-each.js'\nexport { show } from './primitives/show.js'\nexport { slice } from './primitives/slice.js'\nexport { portal } from './primitives/portal.js'\nexport { foreign } from './primitives/foreign.js'\nexport { child } from './primitives/child.js'\nexport { lazy, type LazyOptions } from './primitives/lazy.js'\nexport type { LazyDef, AnyComponentDef } from './types.js'\nexport { memo } from './primitives/memo.js'\nexport { selector } from './primitives/selector.js'\nexport { onMount } from './primitives/on-mount.js'\nexport { errorBoundary } from './primitives/error-boundary.js'\n\n// ── Element Helpers ───────────────────────────────────────────────\n\nexport {\n a,\n abbr,\n article,\n aside,\n b,\n blockquote,\n br,\n button,\n canvas,\n code,\n dd,\n details,\n dialog,\n div,\n dl,\n dt,\n em,\n fieldset,\n figcaption,\n figure,\n footer,\n form,\n h1,\n h2,\n h3,\n h4,\n h5,\n h6,\n header,\n hr,\n i,\n iframe,\n img,\n input,\n label,\n legend,\n li,\n main,\n mark,\n nav,\n ol,\n optgroup,\n option,\n output,\n p,\n pre,\n progress,\n section,\n select,\n small,\n span,\n strong,\n sub,\n summary,\n sup,\n table,\n tbody,\n td,\n textarea,\n tfoot,\n th,\n thead,\n time,\n tr,\n ul,\n video,\n} from './elements.js'\n\n// ── SVG Elements ─────────────────────────────────────────────────\n\nexport {\n svg,\n g,\n defs,\n symbol,\n use,\n circle,\n ellipse,\n line,\n path,\n polygon,\n polyline,\n rect,\n text as svgText,\n tspan,\n textPath,\n clipPath,\n linearGradient,\n radialGradient,\n stop,\n mask,\n pattern,\n marker,\n filter,\n feBlend,\n feColorMatrix,\n feComponentTransfer,\n feComposite,\n feConvolveMatrix,\n feDiffuseLighting,\n feDisplacementMap,\n feDropShadow,\n feFlood,\n feGaussianBlur,\n feImage,\n feMerge,\n feMergeNode,\n feMorphology,\n feOffset,\n feSpecularLighting,\n feTile,\n feTurbulence,\n fePointLight,\n feSpotLight,\n feDistantLight,\n feFuncR,\n feFuncG,\n feFuncB,\n feFuncA,\n image,\n foreignObject,\n animate,\n animateMotion,\n animateTransform,\n set,\n mpath,\n desc,\n title as svgTitle,\n metadata,\n} from './svg-elements.js'\n\n// ── MathML Elements ──────────────────────────────────────────────\n\nexport {\n math,\n mi,\n mn,\n mo,\n ms,\n mtext,\n mrow,\n mfrac,\n msqrt,\n mroot,\n msup,\n msub,\n msubsup,\n munder,\n mover,\n munderover,\n mmultiscripts,\n mprescripts,\n mnone,\n mtable,\n mtr,\n mtd,\n mspace,\n mpadded,\n mphantom,\n menclose,\n merror,\n maction,\n semantics,\n annotation,\n annotationXml,\n} from './mathml-elements.js'\n\n// ── Form Utilities ────────────────────────────────────────────────\n\nexport { applyField, type FieldMsg } from './form.js'\n\n// ── Compiler Target ───────────────────────────────────────────────\n\nexport { elSplit } from './el-split.js'\nexport { elTemplate } from './el-template.js'\nexport { _runPhase2 as __runPhase2, _handleMsg as __handleMsg } from './update-loop.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// ── Types ─────────────────────────────────────────────────────────\n\nexport type {\n ComponentDef,\n Send,\n Props,\n AppHandle,\n Lifetime,\n Binding,\n BindingKind,\n TransitionOptions,\n BranchOptions,\n ShowOptions,\n EachOptions,\n ItemAccessor,\n PortalOptions,\n ForeignOptions,\n ChildOptions,\n} from './types.js'\n\n// ── Component ─────────────────────────────────────────────────────\n\nexport { component } from './component.js'\nexport { createView, type View } from './view-helpers.js'\n\n// ── Mount ─────────────────────────────────────────────────────────\n\nexport { mountApp, hydrateApp, mountAtAnchor, hydrateAtAnchor, type MountOptions } from './mount.js'\n// installDevTools is NOT re-exported here to keep it out of production bundles.\n// Import directly: import { installDevTools } from '@llui/dom/devtools'\nexport type { LluiDebugAPI, ElementReport, MessageRecord, StateDiff } from './devtools.js'\nexport type { CoverageSnapshot } from './tracking/coverage.js'\nexport type { EachDiff } from './tracking/each-diff.js'\nexport type { DisposerEvent } from './tracking/disposer-log.js'\nexport type { PendingEffect, EffectTimelineEntry, EffectMatch } from './tracking/effect-timeline.js'\nexport type { LifetimeNode } from './types.js'\n\n// ── Runtime ───────────────────────────────────────────────────────\n\nexport { flush } from './runtime.js'\nexport { addressOf } from './addressed.js'\nexport { renderToString, renderNodes, serializeNodes } from './ssr.js'\nexport { mergeHandlers } from './merge-handlers.js'\nexport {\n createContext,\n provide,\n provideValue,\n useContext,\n useContextValue,\n type Context,\n} from './primitives/context.js'\nexport { sliceHandler } from './slice-handler.js'\nexport {\n childHandlers,\n type ChildState,\n type ChildMsg,\n type ModuleState,\n type ModuleMsg,\n} from './compose.js'\n\n// ── View Primitives ───────────────────────────────────────────────\n\nexport { text } from './primitives/text.js'\nexport { unsafeHtml } from './primitives/unsafe-html.js'\nexport { branch } from './primitives/branch.js'\nexport { each } from './primitives/each.js'\nexport { virtualEach, type VirtualEachOptions } from './primitives/virtual-each.js'\nexport { show } from './primitives/show.js'\nexport { scope } from './primitives/scope.js'\nexport type { ScopeOptions } from './types.js'\nexport { slice } from './primitives/slice.js'\nexport { portal } from './primitives/portal.js'\nexport { foreign } from './primitives/foreign.js'\nexport { child } from './primitives/child.js'\nexport { lazy, type LazyOptions } from './primitives/lazy.js'\nexport type { LazyDef, AnyComponentDef } from './types.js'\nexport { memo } from './primitives/memo.js'\nexport { sample } from './primitives/sample.js'\nexport { selector } from './primitives/selector.js'\nexport { onMount } from './primitives/on-mount.js'\nexport { errorBoundary } from './primitives/error-boundary.js'\n\n// ── Element Helpers ───────────────────────────────────────────────\n\nexport {\n a,\n abbr,\n article,\n aside,\n b,\n blockquote,\n br,\n button,\n canvas,\n code,\n dd,\n details,\n dialog,\n div,\n dl,\n dt,\n em,\n fieldset,\n figcaption,\n figure,\n footer,\n form,\n h1,\n h2,\n h3,\n h4,\n h5,\n h6,\n header,\n hr,\n i,\n iframe,\n img,\n input,\n label,\n legend,\n li,\n main,\n mark,\n nav,\n ol,\n optgroup,\n option,\n output,\n p,\n pre,\n progress,\n section,\n select,\n small,\n span,\n strong,\n sub,\n summary,\n sup,\n table,\n tbody,\n td,\n textarea,\n tfoot,\n th,\n thead,\n time,\n tr,\n ul,\n video,\n} from './elements.js'\n\n// ── SVG Elements ─────────────────────────────────────────────────\n\nexport {\n svg,\n g,\n defs,\n symbol,\n use,\n circle,\n ellipse,\n line,\n path,\n polygon,\n polyline,\n rect,\n text as svgText,\n tspan,\n textPath,\n clipPath,\n linearGradient,\n radialGradient,\n stop,\n mask,\n pattern,\n marker,\n filter,\n feBlend,\n feColorMatrix,\n feComponentTransfer,\n feComposite,\n feConvolveMatrix,\n feDiffuseLighting,\n feDisplacementMap,\n feDropShadow,\n feFlood,\n feGaussianBlur,\n feImage,\n feMerge,\n feMergeNode,\n feMorphology,\n feOffset,\n feSpecularLighting,\n feTile,\n feTurbulence,\n fePointLight,\n feSpotLight,\n feDistantLight,\n feFuncR,\n feFuncG,\n feFuncB,\n feFuncA,\n image,\n foreignObject,\n animate,\n animateMotion,\n animateTransform,\n set,\n mpath,\n desc,\n title as svgTitle,\n metadata,\n} from './svg-elements.js'\n\n// ── MathML Elements ──────────────────────────────────────────────\n\nexport {\n math,\n mi,\n mn,\n mo,\n ms,\n mtext,\n mrow,\n mfrac,\n msqrt,\n mroot,\n msup,\n msub,\n msubsup,\n munder,\n mover,\n munderover,\n mmultiscripts,\n mprescripts,\n mnone,\n mtable,\n mtr,\n mtd,\n mspace,\n mpadded,\n mphantom,\n menclose,\n merror,\n maction,\n semantics,\n annotation,\n annotationXml,\n} from './mathml-elements.js'\n\n// ── Form Utilities ────────────────────────────────────────────────\n\nexport { applyField, type FieldMsg } from './form.js'\n\n// ── Compiler Target ───────────────────────────────────────────────\n\nexport { elSplit } from './el-split.js'\nexport { elTemplate } from './el-template.js'\nexport { _runPhase2 as __runPhase2, _handleMsg as __handleMsg } from './update-loop.js'\n"]}
@@ -18,5 +18,5 @@
18
18
  */
19
19
  export { getRenderContext, setRenderContext, clearRenderContext } from './render-context.js';
20
20
  export type { RenderContext } from './render-context.js';
21
- export { createScope, disposeScope, addDisposer } from './scope.js';
21
+ export { createLifetime, disposeLifetime, addDisposer } from './lifetime.js';
22
22
  //# sourceMappingURL=internal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC5F,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAC5F,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
package/dist/internal.js CHANGED
@@ -17,5 +17,5 @@
17
17
  * low-level glue.
18
18
  */
19
19
  export { getRenderContext, setRenderContext, clearRenderContext } from './render-context.js';
20
- export { createScope, disposeScope, addDisposer } from './scope.js';
20
+ export { createLifetime, disposeLifetime, addDisposer } from './lifetime.js';
21
21
  //# sourceMappingURL=internal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAE5F,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA","sourcesContent":["/**\n * Internal primitives surface — exported for framework-adapter packages\n * (`@llui/vike`, `@llui/router`, `@llui/transitions`) that need to build\n * their own structural primitives on top of LLui's scope + render-context\n * machinery.\n *\n * **Not part of the public API.** App authors should not import from\n * `@llui/dom/internal`. The shapes here are free to change without a\n * major version bump — the stability contract applies only to the public\n * barrel at `@llui/dom`. Reach for this subpath when you're writing a\n * primitive like `pageSlot()` (from `@llui/vike`) that has to participate\n * in the scope tree, not when you're writing application views.\n *\n * Added in 0.0.16 to support `@llui/vike`'s persistent-layout feature.\n * Any future adapter-level primitive that needs render-context / scope\n * access should re-export from this file rather than duplicating the\n * low-level glue.\n */\n\nexport { getRenderContext, setRenderContext, clearRenderContext } from './render-context.js'\nexport type { RenderContext } from './render-context.js'\nexport { createScope, disposeScope, addDisposer } from './scope.js'\n"]}
1
+ {"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAE5F,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA","sourcesContent":["/**\n * Internal primitives surface — exported for framework-adapter packages\n * (`@llui/vike`, `@llui/router`, `@llui/transitions`) that need to build\n * their own structural primitives on top of LLui's scope + render-context\n * machinery.\n *\n * **Not part of the public API.** App authors should not import from\n * `@llui/dom/internal`. The shapes here are free to change without a\n * major version bump — the stability contract applies only to the public\n * barrel at `@llui/dom`. Reach for this subpath when you're writing a\n * primitive like `pageSlot()` (from `@llui/vike`) that has to participate\n * in the scope tree, not when you're writing application views.\n *\n * Added in 0.0.16 to support `@llui/vike`'s persistent-layout feature.\n * Any future adapter-level primitive that needs render-context / scope\n * access should re-export from this file rather than duplicating the\n * low-level glue.\n */\n\nexport { getRenderContext, setRenderContext, clearRenderContext } from './render-context.js'\nexport type { RenderContext } from './render-context.js'\nexport { createLifetime, disposeLifetime, addDisposer } from './lifetime.js'\n"]}
@@ -0,0 +1,39 @@
1
+ import type { Lifetime, Binding } from './types.js';
2
+ export declare function createLifetime(parent: Lifetime | null): Lifetime;
3
+ /**
4
+ * Dispose a scope and all its children. By default, detaches the scope
5
+ * from its parent's `children` array via `indexOf + splice` — O(N) per
6
+ * call, which becomes O(N²) when disposing many sibling scopes in bulk
7
+ * (e.g. `each` clearing 1000 rows).
8
+ *
9
+ * Pass `skipParentRemoval = true` when the caller will batch-remove
10
+ * children afterwards (see `removeOrphanedFromParent`). The scope's
11
+ * `parent` pointer is still set to `null` so the caller can identify
12
+ * orphaned entries.
13
+ */
14
+ export declare function disposeLifetime(scope: Lifetime, skipParentRemoval?: boolean): void;
15
+ /**
16
+ * Batch-remove children with `parent === null` from `parent.children`.
17
+ * Called after a bulk `disposeLifetime(child, true)` pass to collapse the
18
+ * individual O(N) splice operations into one O(N) scan.
19
+ */
20
+ export declare function removeOrphanedChildren(parent: Lifetime): void;
21
+ /**
22
+ * Bulk dispose an array of sibling scopes — avoids per-scope function call
23
+ * overhead. Used by each() clear path where 1000+ scopes are disposed at once.
24
+ * Caller must call removeOrphanedChildren(parent) afterwards.
25
+ */
26
+ export declare function disposeLifetimesBulk(scopes: Lifetime[]): void;
27
+ export declare function addBinding(scope: Lifetime, binding: Binding): void;
28
+ export declare function addItemUpdater(scope: Lifetime, updater: () => void): void;
29
+ /**
30
+ * Register a per-item updater that compares the new value against the last
31
+ * value before applying. Shared by `text()`, `elSplit()`, and `elTemplate()`
32
+ * so the equality-check logic lives in one place.
33
+ *
34
+ * @param apply - DOM write: receives the new value when it differs
35
+ * @returns the initial value (caller should apply it to the DOM)
36
+ */
37
+ export declare function addCheckedItemUpdater<V>(scope: Lifetime, get: () => V, apply: (value: V) => void): V;
38
+ export declare function addDisposer(scope: Lifetime, disposer: () => void): void;
39
+ //# sourceMappingURL=lifetime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifetime.d.ts","sourceRoot":"","sources":["../src/lifetime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AA8CnD,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,GAAG,QAAQ,CA8BhE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,iBAAiB,UAAQ,GAAG,IAAI,CAqEhF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,CAO7D;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAuC7D;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAIlE;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAGzE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,KAAK,EAAE,QAAQ,EACf,GAAG,EAAE,MAAM,CAAC,EACZ,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GACxB,CAAC,CASH;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAGvE"}
@@ -0,0 +1,250 @@
1
+ let nextId = 1;
2
+ /**
3
+ * Walk up the scope chain to find the owning ComponentInstance. The
4
+ * instance is stamped onto the rootLifetime by `installDevTools`, so this
5
+ * returns null in production (no devtools) or for scopes that haven't
6
+ * yet been parented to a tracked root (e.g., during initial creation).
7
+ */
8
+ function findInstance(scope) {
9
+ let s = scope;
10
+ while (s) {
11
+ if (s.instance)
12
+ return s.instance;
13
+ s = s.parent;
14
+ }
15
+ return null;
16
+ }
17
+ // Shared empty arrays — avoid allocating per scope when unused
18
+ const EMPTY_LIFETIMES = [];
19
+ const EMPTY_DISPOSERS = [];
20
+ const EMPTY_BINDINGS = [];
21
+ const EMPTY_UPDATERS = [];
22
+ // Lifetime pool — reuse disposed scope objects to reduce GC pressure.
23
+ // Capped to avoid memory leaks in apps that create/destroy thousands of rows.
24
+ const SCOPE_POOL = [];
25
+ const SCOPE_POOL_MAX = 2048;
26
+ // Dev-mode flag. Flipped to true by installDevTools() once any component
27
+ // instance has a disposer log. In production this stays false forever,
28
+ // and disposeLifetime skips findInstance entirely — zero cost.
29
+ let anyDisposerLogInstalled = false;
30
+ /** @internal — called by devtools.ts::installDevTools */
31
+ export function _markDisposerLogInstalled() {
32
+ anyDisposerLogInstalled = true;
33
+ }
34
+ /** @internal Drain the scope pool — for testing only */
35
+ export function _drainScopePool() {
36
+ SCOPE_POOL.length = 0;
37
+ }
38
+ export function createLifetime(parent) {
39
+ let scope;
40
+ if (SCOPE_POOL.length > 0) {
41
+ scope = SCOPE_POOL.pop();
42
+ scope.id = nextId++;
43
+ scope.parent = parent;
44
+ // Arrays already reset to empties by dispose. Reset dev-only hints
45
+ // so recycled scopes don't carry stale tagging/back-refs. Cheap
46
+ // (two undefined writes) and keeps production-identical behavior
47
+ // when these fields are never set.
48
+ scope.disposalCause = undefined;
49
+ scope.instance = undefined;
50
+ scope._kind = undefined;
51
+ }
52
+ else {
53
+ scope = {
54
+ id: nextId++,
55
+ parent,
56
+ children: EMPTY_LIFETIMES,
57
+ disposers: EMPTY_DISPOSERS,
58
+ bindings: EMPTY_BINDINGS,
59
+ itemUpdaters: EMPTY_UPDATERS,
60
+ };
61
+ }
62
+ if (parent) {
63
+ if (parent.children === EMPTY_LIFETIMES)
64
+ parent.children = [];
65
+ parent.children.push(scope);
66
+ }
67
+ return scope;
68
+ }
69
+ /**
70
+ * Dispose a scope and all its children. By default, detaches the scope
71
+ * from its parent's `children` array via `indexOf + splice` — O(N) per
72
+ * call, which becomes O(N²) when disposing many sibling scopes in bulk
73
+ * (e.g. `each` clearing 1000 rows).
74
+ *
75
+ * Pass `skipParentRemoval = true` when the caller will batch-remove
76
+ * children afterwards (see `removeOrphanedFromParent`). The scope's
77
+ * `parent` pointer is still set to `null` so the caller can identify
78
+ * orphaned entries.
79
+ */
80
+ export function disposeLifetime(scope, skipParentRemoval = false) {
81
+ if (scope.disposers.length === 0 && scope.children.length === 0 && scope.bindings.length === 0) {
82
+ // Dev-only: still emit a DisposerEvent for empty scopes — the log
83
+ // is meant to capture every scope the app destroys, not only ones
84
+ // that had attached work. Outer flag check keeps production (no
85
+ // devtools ever installed) at true zero cost — no parent-chain walk.
86
+ if (anyDisposerLogInstalled) {
87
+ const inst = findInstance(scope);
88
+ if (inst?._disposerLog !== undefined) {
89
+ inst._disposerLog.push({
90
+ scopeId: String(scope.id),
91
+ cause: scope.disposalCause ?? 'component-unmount',
92
+ timestamp: Date.now(),
93
+ });
94
+ }
95
+ }
96
+ if (!skipParentRemoval)
97
+ removeFromParent(scope);
98
+ scope.parent = null;
99
+ // Don't pool empty scopes from the early-return path — they may be
100
+ // disposed idempotently (twice), which would create pool duplicates
101
+ return;
102
+ }
103
+ // When skipParentRemoval is true, children don't mutate during disposal —
104
+ // iterate directly without allocating a copy. Otherwise, clone to avoid
105
+ // mutation during iteration.
106
+ const children = skipParentRemoval ? scope.children : scope.children.slice();
107
+ for (const child of children) {
108
+ disposeLifetime(child, skipParentRemoval);
109
+ }
110
+ for (const disposer of scope.disposers) {
111
+ disposer();
112
+ }
113
+ // Dev-only: emit disposer events into the owning instance's log.
114
+ // Outer flag check keeps production (no devtools ever installed) at
115
+ // true zero cost — skips the O(depth) parent-chain walk entirely.
116
+ if (anyDisposerLogInstalled) {
117
+ const inst = findInstance(scope);
118
+ if (inst?._disposerLog !== undefined) {
119
+ inst._disposerLog.push({
120
+ scopeId: String(scope.id),
121
+ cause: scope.disposalCause ?? 'component-unmount',
122
+ timestamp: Date.now(),
123
+ });
124
+ }
125
+ }
126
+ // Mark bindings as dead and break closure/DOM retention
127
+ for (const binding of scope.bindings) {
128
+ binding.dead = true;
129
+ binding.accessor = null;
130
+ binding.node = null;
131
+ binding.lastValue = undefined;
132
+ }
133
+ // Reset to shared empties — don't just truncate, so pooled scopes
134
+ // don't hold allocated-but-empty arrays
135
+ scope.disposers = EMPTY_DISPOSERS;
136
+ scope.bindings = EMPTY_BINDINGS;
137
+ scope.children = EMPTY_LIFETIMES;
138
+ scope.itemUpdaters = EMPTY_UPDATERS;
139
+ if (!skipParentRemoval)
140
+ removeFromParent(scope);
141
+ scope.parent = null;
142
+ // Return to pool for reuse
143
+ if (SCOPE_POOL.length < SCOPE_POOL_MAX)
144
+ SCOPE_POOL.push(scope);
145
+ }
146
+ /**
147
+ * Batch-remove children with `parent === null` from `parent.children`.
148
+ * Called after a bulk `disposeLifetime(child, true)` pass to collapse the
149
+ * individual O(N) splice operations into one O(N) scan.
150
+ */
151
+ export function removeOrphanedChildren(parent) {
152
+ const children = parent.children;
153
+ let w = 0;
154
+ for (let r = 0; r < children.length; r++) {
155
+ if (children[r].parent !== null)
156
+ children[w++] = children[r];
157
+ }
158
+ children.length = w;
159
+ }
160
+ /**
161
+ * Bulk dispose an array of sibling scopes — avoids per-scope function call
162
+ * overhead. Used by each() clear path where 1000+ scopes are disposed at once.
163
+ * Caller must call removeOrphanedChildren(parent) afterwards.
164
+ */
165
+ export function disposeLifetimesBulk(scopes) {
166
+ for (let i = 0; i < scopes.length; i++) {
167
+ const scope = scopes[i];
168
+ // Recursively dispose children
169
+ const children = scope.children;
170
+ if (children.length > 0) {
171
+ disposeLifetimesBulk(children);
172
+ }
173
+ // Run disposers
174
+ const disposers = scope.disposers;
175
+ for (let d = 0; d < disposers.length; d++)
176
+ disposers[d]();
177
+ // Dev-only: emit disposer events — same guard as disposeLifetime.
178
+ if (anyDisposerLogInstalled) {
179
+ const inst = findInstance(scope);
180
+ if (inst?._disposerLog !== undefined) {
181
+ inst._disposerLog.push({
182
+ scopeId: String(scope.id),
183
+ cause: scope.disposalCause ?? 'component-unmount',
184
+ timestamp: Date.now(),
185
+ });
186
+ }
187
+ }
188
+ // Mark bindings dead
189
+ const bindings = scope.bindings;
190
+ for (let b = 0; b < bindings.length; b++) {
191
+ const binding = bindings[b];
192
+ binding.dead = true;
193
+ binding.accessor = null;
194
+ binding.node = null;
195
+ binding.lastValue = undefined;
196
+ }
197
+ // Reset to shared empties + detach from parent + return to pool
198
+ scope.disposers = EMPTY_DISPOSERS;
199
+ scope.bindings = EMPTY_BINDINGS;
200
+ scope.children = EMPTY_LIFETIMES;
201
+ scope.itemUpdaters = EMPTY_UPDATERS;
202
+ scope.parent = null;
203
+ if (SCOPE_POOL.length < SCOPE_POOL_MAX)
204
+ SCOPE_POOL.push(scope);
205
+ }
206
+ }
207
+ export function addBinding(scope, binding) {
208
+ binding.ownerLifetime = scope;
209
+ if (scope.bindings === EMPTY_BINDINGS)
210
+ scope.bindings = [];
211
+ scope.bindings.push(binding);
212
+ }
213
+ export function addItemUpdater(scope, updater) {
214
+ if (scope.itemUpdaters === EMPTY_UPDATERS)
215
+ scope.itemUpdaters = [];
216
+ scope.itemUpdaters.push(updater);
217
+ }
218
+ /**
219
+ * Register a per-item updater that compares the new value against the last
220
+ * value before applying. Shared by `text()`, `elSplit()`, and `elTemplate()`
221
+ * so the equality-check logic lives in one place.
222
+ *
223
+ * @param apply - DOM write: receives the new value when it differs
224
+ * @returns the initial value (caller should apply it to the DOM)
225
+ */
226
+ export function addCheckedItemUpdater(scope, get, apply) {
227
+ let last = get();
228
+ addItemUpdater(scope, () => {
229
+ const v = get();
230
+ if (v === last || (v !== v && last !== last))
231
+ return;
232
+ last = v;
233
+ apply(v);
234
+ });
235
+ return last;
236
+ }
237
+ export function addDisposer(scope, disposer) {
238
+ if (scope.disposers === EMPTY_DISPOSERS)
239
+ scope.disposers = [];
240
+ scope.disposers.push(disposer);
241
+ }
242
+ function removeFromParent(scope) {
243
+ if (scope.parent) {
244
+ const idx = scope.parent.children.indexOf(scope);
245
+ if (idx !== -1) {
246
+ scope.parent.children.splice(idx, 1);
247
+ }
248
+ }
249
+ }
250
+ //# sourceMappingURL=lifetime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifetime.js","sourceRoot":"","sources":["../src/lifetime.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Lifetime, Binding } from './types.js'\nimport type { ComponentInstance } from './update-loop.js'\n\nlet nextId = 1\n\n/**\n * Walk up the scope chain to find the owning ComponentInstance. The\n * instance is stamped onto the rootLifetime by `installDevTools`, so this\n * returns null in production (no devtools) or for scopes that haven't\n * yet been parented to a tracked root (e.g., during initial creation).\n */\nfunction findInstance(scope: Lifetime): ComponentInstance | null {\n let s: Lifetime | null = scope\n while (s) {\n if (s.instance) return s.instance\n s = s.parent\n }\n return null\n}\n\n// Shared empty arrays — avoid allocating per scope when unused\nconst EMPTY_LIFETIMES: Lifetime[] = []\nconst EMPTY_DISPOSERS: Array<() => void> = []\nconst EMPTY_BINDINGS: Binding[] = []\nconst EMPTY_UPDATERS: Array<() => void> = []\n\n// Lifetime pool — reuse disposed scope objects to reduce GC pressure.\n// Capped to avoid memory leaks in apps that create/destroy thousands of rows.\nconst SCOPE_POOL: Lifetime[] = []\nconst SCOPE_POOL_MAX = 2048\n\n// Dev-mode flag. Flipped to true by installDevTools() once any component\n// instance has a disposer log. In production this stays false forever,\n// and disposeLifetime skips findInstance entirely — zero cost.\nlet anyDisposerLogInstalled = false\n\n/** @internal — called by devtools.ts::installDevTools */\nexport function _markDisposerLogInstalled(): void {\n anyDisposerLogInstalled = true\n}\n\n/** @internal Drain the scope pool — for testing only */\nexport function _drainScopePool(): void {\n SCOPE_POOL.length = 0\n}\n\nexport function createLifetime(parent: Lifetime | null): Lifetime {\n let scope: Lifetime\n if (SCOPE_POOL.length > 0) {\n scope = SCOPE_POOL.pop()!\n scope.id = nextId++\n scope.parent = parent\n // Arrays already reset to empties by dispose. Reset dev-only hints\n // so recycled scopes don't carry stale tagging/back-refs. Cheap\n // (two undefined writes) and keeps production-identical behavior\n // when these fields are never set.\n scope.disposalCause = undefined\n scope.instance = undefined\n scope._kind = undefined\n } else {\n scope = {\n id: nextId++,\n parent,\n children: EMPTY_LIFETIMES,\n disposers: EMPTY_DISPOSERS,\n bindings: EMPTY_BINDINGS,\n itemUpdaters: EMPTY_UPDATERS,\n }\n }\n\n if (parent) {\n if (parent.children === EMPTY_LIFETIMES) parent.children = []\n parent.children.push(scope)\n }\n\n return scope\n}\n\n/**\n * Dispose a scope and all its children. By default, detaches the scope\n * from its parent's `children` array via `indexOf + splice` — O(N) per\n * call, which becomes O(N²) when disposing many sibling scopes in bulk\n * (e.g. `each` clearing 1000 rows).\n *\n * Pass `skipParentRemoval = true` when the caller will batch-remove\n * children afterwards (see `removeOrphanedFromParent`). The scope's\n * `parent` pointer is still set to `null` so the caller can identify\n * orphaned entries.\n */\nexport function disposeLifetime(scope: Lifetime, skipParentRemoval = false): void {\n if (scope.disposers.length === 0 && scope.children.length === 0 && scope.bindings.length === 0) {\n // Dev-only: still emit a DisposerEvent for empty scopes — the log\n // is meant to capture every scope the app destroys, not only ones\n // that had attached work. Outer flag check keeps production (no\n // devtools ever installed) at true zero cost — no parent-chain walk.\n if (anyDisposerLogInstalled) {\n const inst = findInstance(scope)\n if (inst?._disposerLog !== undefined) {\n inst._disposerLog.push({\n scopeId: String(scope.id),\n cause: scope.disposalCause ?? 'component-unmount',\n timestamp: Date.now(),\n })\n }\n }\n if (!skipParentRemoval) removeFromParent(scope)\n scope.parent = null\n // Don't pool empty scopes from the early-return path — they may be\n // disposed idempotently (twice), which would create pool duplicates\n return\n }\n\n // When skipParentRemoval is true, children don't mutate during disposal —\n // iterate directly without allocating a copy. Otherwise, clone to avoid\n // mutation during iteration.\n const children = skipParentRemoval ? scope.children : scope.children.slice()\n for (const child of children) {\n disposeLifetime(child, skipParentRemoval)\n }\n\n for (const disposer of scope.disposers) {\n disposer()\n }\n\n // Dev-only: emit disposer events into the owning instance's log.\n // Outer flag check keeps production (no devtools ever installed) at\n // true zero cost — skips the O(depth) parent-chain walk entirely.\n if (anyDisposerLogInstalled) {\n const inst = findInstance(scope)\n if (inst?._disposerLog !== undefined) {\n inst._disposerLog.push({\n scopeId: String(scope.id),\n cause: scope.disposalCause ?? 'component-unmount',\n timestamp: Date.now(),\n })\n }\n }\n\n // Mark bindings as dead and break closure/DOM retention\n for (const binding of scope.bindings) {\n binding.dead = true\n binding.accessor = null!\n binding.node = null!\n binding.lastValue = undefined\n }\n\n // Reset to shared empties — don't just truncate, so pooled scopes\n // don't hold allocated-but-empty arrays\n scope.disposers = EMPTY_DISPOSERS\n scope.bindings = EMPTY_BINDINGS\n scope.children = EMPTY_LIFETIMES\n scope.itemUpdaters = EMPTY_UPDATERS\n\n if (!skipParentRemoval) removeFromParent(scope)\n scope.parent = null\n\n // Return to pool for reuse\n if (SCOPE_POOL.length < SCOPE_POOL_MAX) SCOPE_POOL.push(scope)\n}\n\n/**\n * Batch-remove children with `parent === null` from `parent.children`.\n * Called after a bulk `disposeLifetime(child, true)` pass to collapse the\n * individual O(N) splice operations into one O(N) scan.\n */\nexport function removeOrphanedChildren(parent: Lifetime): void {\n const children = parent.children\n let w = 0\n for (let r = 0; r < children.length; r++) {\n if (children[r]!.parent !== null) children[w++] = children[r]!\n }\n children.length = w\n}\n\n/**\n * Bulk dispose an array of sibling scopes — avoids per-scope function call\n * overhead. Used by each() clear path where 1000+ scopes are disposed at once.\n * Caller must call removeOrphanedChildren(parent) afterwards.\n */\nexport function disposeLifetimesBulk(scopes: Lifetime[]): void {\n for (let i = 0; i < scopes.length; i++) {\n const scope = scopes[i]!\n // Recursively dispose children\n const children = scope.children\n if (children.length > 0) {\n disposeLifetimesBulk(children)\n }\n // Run disposers\n const disposers = scope.disposers\n for (let d = 0; d < disposers.length; d++) disposers[d]!()\n // Dev-only: emit disposer events — same guard as disposeLifetime.\n if (anyDisposerLogInstalled) {\n const inst = findInstance(scope)\n if (inst?._disposerLog !== undefined) {\n inst._disposerLog.push({\n scopeId: String(scope.id),\n cause: scope.disposalCause ?? 'component-unmount',\n timestamp: Date.now(),\n })\n }\n }\n // Mark bindings dead\n const bindings = scope.bindings\n for (let b = 0; b < bindings.length; b++) {\n const binding = bindings[b]!\n binding.dead = true\n binding.accessor = null!\n binding.node = null!\n binding.lastValue = undefined\n }\n // Reset to shared empties + detach from parent + return to pool\n scope.disposers = EMPTY_DISPOSERS\n scope.bindings = EMPTY_BINDINGS\n scope.children = EMPTY_LIFETIMES\n scope.itemUpdaters = EMPTY_UPDATERS\n scope.parent = null\n if (SCOPE_POOL.length < SCOPE_POOL_MAX) SCOPE_POOL.push(scope)\n }\n}\n\nexport function addBinding(scope: Lifetime, binding: Binding): void {\n binding.ownerLifetime = scope\n if (scope.bindings === EMPTY_BINDINGS) scope.bindings = []\n scope.bindings.push(binding)\n}\n\nexport function addItemUpdater(scope: Lifetime, updater: () => void): void {\n if (scope.itemUpdaters === EMPTY_UPDATERS) scope.itemUpdaters = []\n scope.itemUpdaters.push(updater)\n}\n\n/**\n * Register a per-item updater that compares the new value against the last\n * value before applying. Shared by `text()`, `elSplit()`, and `elTemplate()`\n * so the equality-check logic lives in one place.\n *\n * @param apply - DOM write: receives the new value when it differs\n * @returns the initial value (caller should apply it to the DOM)\n */\nexport function addCheckedItemUpdater<V>(\n scope: Lifetime,\n get: () => V,\n apply: (value: V) => void,\n): V {\n let last: V = get()\n addItemUpdater(scope, () => {\n const v = get()\n if (v === last || (v !== v && last !== last)) return\n last = v\n apply(v)\n })\n return last\n}\n\nexport function addDisposer(scope: Lifetime, disposer: () => void): void {\n if (scope.disposers === EMPTY_DISPOSERS) scope.disposers = []\n scope.disposers.push(disposer)\n}\n\nfunction removeFromParent(scope: Lifetime): void {\n if (scope.parent) {\n const idx = scope.parent.children.indexOf(scope)\n if (idx !== -1) {\n scope.parent.children.splice(idx, 1)\n }\n }\n}\n"]}
@@ -25,7 +25,7 @@ function createMathmlElement(tag, propsOrChildren, maybeChildren) {
25
25
  const key = kind === 'class' ? undefined : rawKey;
26
26
  const accessor = value;
27
27
  const perItem = value.length === 0;
28
- const binding = createBinding(ctx.rootScope, {
28
+ const binding = createBinding(ctx.rootLifetime, {
29
29
  mask: FULL_MASK,
30
30
  accessor,
31
31
  kind,