@elurjs/core 3.6.1 → 3.7.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/async.cjs +1 -1
- package/dist/lib/async.js +1 -1
- package/dist/lib/component.cjs +1 -2
- package/dist/lib/component.js +2 -66
- package/dist/lib/context.cjs +1 -1
- package/dist/lib/context.js +35 -23
- package/dist/lib/devtools.cjs +1 -1
- package/dist/lib/devtools.js +1 -1
- package/dist/lib/elur/async.cjs +1 -1
- package/dist/lib/elur/async.cjs.map +1 -1
- package/dist/lib/elur/async.js +1 -1
- package/dist/lib/elur/component.cjs +1 -2
- package/dist/lib/elur/component.d.cts +1 -17
- package/dist/lib/elur/component.d.ts +1 -17
- package/dist/lib/elur/component.js +2 -66
- package/dist/lib/elur/context.cjs +1 -1
- package/dist/lib/elur/context.cjs.map +1 -1
- package/dist/lib/elur/context.d.cts +5 -0
- package/dist/lib/elur/context.d.ts +5 -0
- package/dist/lib/elur/context.js +35 -23
- package/dist/lib/elur/context.js.map +1 -1
- package/dist/lib/elur/devtools.cjs +1 -1
- package/dist/lib/elur/devtools.cjs.map +1 -1
- package/dist/lib/elur/devtools.js +1 -1
- package/dist/lib/elur/form.cjs +1 -1
- package/dist/lib/elur/form.cjs.map +1 -1
- package/dist/lib/elur/form.js +1 -1
- package/dist/lib/elur/hydrate/index.cjs +1 -2
- package/dist/lib/elur/hydrate/index.d.cts +1 -13
- package/dist/lib/elur/hydrate/index.d.ts +1 -13
- package/dist/lib/elur/hydrate/index.js +2 -410
- package/dist/lib/elur/lifecycle.cjs +1 -1
- package/dist/lib/elur/lifecycle.cjs.map +1 -1
- package/dist/lib/elur/lifecycle.d.cts +27 -0
- package/dist/lib/elur/lifecycle.d.ts +27 -0
- package/dist/lib/elur/lifecycle.js +4 -0
- package/dist/lib/elur/lifecycle.js.map +1 -1
- package/dist/lib/elur/next/component.d.cts +281 -0
- package/dist/lib/elur/next/component.d.ts +281 -0
- package/dist/lib/elur/next/dom-write.d.cts +18 -0
- package/dist/lib/elur/next/dom-write.d.ts +18 -0
- package/dist/lib/elur/next/hydrate.d.cts +14 -0
- package/dist/lib/elur/next/hydrate.d.ts +14 -0
- package/dist/lib/elur/next/keyed-diff.d.cts +46 -0
- package/dist/lib/elur/next/keyed-diff.d.ts +46 -0
- package/dist/lib/elur/next/mount-helpers.d.cts +25 -0
- package/dist/lib/elur/next/mount-helpers.d.ts +25 -0
- package/dist/lib/elur/next/mount.d.cts +29 -0
- package/dist/lib/elur/next/mount.d.ts +29 -0
- package/dist/lib/elur/next/node-binding.d.cts +6 -0
- package/dist/lib/elur/next/node-binding.d.ts +6 -0
- package/dist/lib/elur/next/reactivity.d.cts +193 -0
- package/dist/lib/elur/next/reactivity.d.ts +193 -0
- package/dist/lib/elur/next-2/component.cjs +2 -0
- package/dist/lib/elur/next-2/component.cjs.map +1 -0
- package/dist/lib/elur/next-2/component.d.cts +283 -0
- package/dist/lib/elur/next-2/component.d.ts +283 -0
- package/dist/lib/elur/next-2/component.js +340 -0
- package/dist/lib/elur/next-2/component.js.map +1 -0
- package/dist/lib/elur/next-2/dom-write.cjs +2 -0
- package/dist/lib/elur/next-2/dom-write.cjs.map +1 -0
- package/dist/lib/elur/next-2/dom-write.d.cts +18 -0
- package/dist/lib/elur/next-2/dom-write.d.ts +18 -0
- package/dist/lib/elur/next-2/dom-write.js +31 -0
- package/dist/lib/elur/next-2/dom-write.js.map +1 -0
- package/dist/lib/elur/next-2/hydrate.cjs +2 -0
- package/dist/lib/elur/next-2/hydrate.cjs.map +1 -0
- package/dist/lib/elur/next-2/hydrate.d.cts +30 -0
- package/dist/lib/elur/next-2/hydrate.d.ts +30 -0
- package/dist/lib/elur/next-2/hydrate.js +449 -0
- package/dist/lib/elur/next-2/hydrate.js.map +1 -0
- package/dist/lib/elur/next-2/keyed-diff.cjs +2 -0
- package/dist/lib/elur/next-2/keyed-diff.cjs.map +1 -0
- package/dist/lib/elur/next-2/keyed-diff.d.cts +79 -0
- package/dist/lib/elur/next-2/keyed-diff.d.ts +79 -0
- package/dist/lib/elur/next-2/keyed-diff.js +208 -0
- package/dist/lib/elur/next-2/keyed-diff.js.map +1 -0
- package/dist/lib/elur/next-2/mount-helpers.cjs +2 -0
- package/dist/lib/elur/next-2/mount-helpers.cjs.map +1 -0
- package/dist/lib/elur/next-2/mount-helpers.d.cts +25 -0
- package/dist/lib/elur/next-2/mount-helpers.d.ts +25 -0
- package/dist/lib/elur/next-2/mount-helpers.js +87 -0
- package/dist/lib/elur/next-2/mount-helpers.js.map +1 -0
- package/dist/lib/elur/next-2/mount.cjs +2 -0
- package/dist/lib/elur/next-2/mount.cjs.map +1 -0
- package/dist/lib/elur/next-2/mount.d.cts +29 -0
- package/dist/lib/elur/next-2/mount.d.ts +29 -0
- package/dist/lib/elur/next-2/mount.js +34 -0
- package/dist/lib/elur/next-2/mount.js.map +1 -0
- package/dist/lib/elur/next-2/node-binding.cjs +2 -0
- package/dist/lib/elur/next-2/node-binding.cjs.map +1 -0
- package/dist/lib/elur/next-2/node-binding.d.cts +6 -0
- package/dist/lib/elur/next-2/node-binding.d.ts +6 -0
- package/dist/lib/elur/next-2/node-binding.js +130 -0
- package/dist/lib/elur/next-2/node-binding.js.map +1 -0
- package/dist/lib/elur/next-2/reactivity.cjs +2 -0
- package/dist/lib/elur/next-2/reactivity.cjs.map +1 -0
- package/dist/lib/elur/next-2/reactivity.d.cts +220 -0
- package/dist/lib/elur/next-2/reactivity.d.ts +220 -0
- package/dist/lib/elur/next-2/reactivity.js +614 -0
- package/dist/lib/elur/next-2/reactivity.js.map +1 -0
- package/dist/lib/elur/next-2/scheduler.cjs +2 -0
- package/dist/lib/elur/next-2/scheduler.cjs.map +1 -0
- package/dist/lib/elur/next-2/scheduler.d.cts +23 -0
- package/dist/lib/elur/next-2/scheduler.d.ts +23 -0
- package/dist/lib/elur/next-2/scheduler.js +26 -0
- package/dist/lib/elur/next-2/scheduler.js.map +1 -0
- package/dist/lib/elur/plugins.cjs +1 -1
- package/dist/lib/elur/plugins.cjs.map +1 -1
- package/dist/lib/elur/plugins.js +1 -1
- package/dist/lib/elur/reactivity.cjs +1 -2
- package/dist/lib/elur/reactivity.d.cts +1 -67
- package/dist/lib/elur/reactivity.d.ts +1 -67
- package/dist/lib/elur/reactivity.js +2 -218
- package/dist/lib/elur/router.cjs +2 -2
- package/dist/lib/elur/router.cjs.map +1 -1
- package/dist/lib/elur/router.js +2 -2
- package/dist/lib/elur/router.js.map +1 -1
- package/dist/lib/elur/server/index.cjs +1 -1
- package/dist/lib/elur/server/index.cjs.map +1 -1
- package/dist/lib/elur/server/index.js +180 -108
- package/dist/lib/elur/server/index.js.map +1 -1
- package/dist/lib/elur/store.cjs +1 -1
- package/dist/lib/elur/store.cjs.map +1 -1
- package/dist/lib/elur/store.js +10 -4
- package/dist/lib/elur/store.js.map +1 -1
- package/dist/lib/elur/template/bindings.cjs +1 -1
- package/dist/lib/elur/template/bindings.cjs.map +1 -1
- package/dist/lib/elur/template/bindings.js +98 -84
- package/dist/lib/elur/template/bindings.js.map +1 -1
- package/dist/lib/elur/template/dom-write.d.cts +1 -5
- package/dist/lib/elur/template/dom-write.d.ts +1 -5
- package/dist/lib/elur/template/error-boundary.cjs +1 -1
- package/dist/lib/elur/template/error-boundary.cjs.map +1 -1
- package/dist/lib/elur/template/error-boundary.js +56 -50
- package/dist/lib/elur/template/error-boundary.js.map +1 -1
- package/dist/lib/elur/template/html.cjs +1 -1
- package/dist/lib/elur/template/html.cjs.map +1 -1
- package/dist/lib/elur/template/html.js +40 -37
- package/dist/lib/elur/template/html.js.map +1 -1
- package/dist/lib/elur/template/index.cjs +1 -1
- package/dist/lib/elur/template/index.d.cts +2 -1
- package/dist/lib/elur/template/index.d.ts +2 -1
- package/dist/lib/elur/template/index.js +13 -12
- package/dist/lib/elur/template/keyed-diff.d.cts +1 -32
- package/dist/lib/elur/template/keyed-diff.d.ts +1 -32
- package/dist/lib/elur/template/keyed.cjs +1 -1
- package/dist/lib/elur/template/keyed.cjs.map +1 -1
- package/dist/lib/elur/template/keyed.d.cts +10 -2
- package/dist/lib/elur/template/keyed.d.ts +10 -2
- package/dist/lib/elur/template/keyed.js +12 -1
- package/dist/lib/elur/template/keyed.js.map +1 -1
- package/dist/lib/elur/template/mount-helpers.d.cts +1 -29
- package/dist/lib/elur/template/mount-helpers.d.ts +1 -29
- package/dist/lib/elur/template/node-binding.d.cts +1 -6
- package/dist/lib/elur/template/node-binding.d.ts +1 -6
- package/dist/lib/elur/template/portal.cjs +1 -1
- package/dist/lib/elur/template/portal.cjs.map +1 -1
- package/dist/lib/elur/template/portal.js +1 -1
- package/dist/lib/elur/template/transitions.cjs +1 -1
- package/dist/lib/elur/template/transitions.cjs.map +1 -1
- package/dist/lib/elur/template/transitions.js +2 -2
- package/dist/lib/elur/template/types.cjs +1 -1
- package/dist/lib/elur/template/types.cjs.map +1 -1
- package/dist/lib/elur/template/types.d.cts +55 -0
- package/dist/lib/elur/template/types.d.ts +55 -0
- package/dist/lib/elur/template/types.js +5 -1
- package/dist/lib/elur/template/types.js.map +1 -1
- package/dist/lib/elur.cjs +1 -1
- package/dist/lib/elur.js +2 -2
- package/dist/lib/form.cjs +1 -1
- package/dist/lib/form.js +1 -1
- package/dist/lib/hydrate.cjs +1 -2
- package/dist/lib/hydrate.js +2 -410
- package/dist/lib/index.cjs +1 -1
- package/dist/lib/index.js +2 -2
- package/dist/lib/lifecycle.cjs +1 -1
- package/dist/lib/lifecycle.js +4 -0
- package/dist/lib/plugins.cjs +1 -1
- package/dist/lib/plugins.js +1 -1
- package/dist/lib/router.cjs +2 -2
- package/dist/lib/router.js +2 -2
- package/dist/lib/server.cjs +1 -1
- package/dist/lib/server.js +180 -108
- package/dist/lib/signals.cjs +1 -2
- package/dist/lib/signals.js +2 -218
- package/dist/lib/store.cjs +1 -1
- package/dist/lib/store.js +10 -4
- package/dist/lib/template.cjs +1 -1
- package/dist/lib/template.js +13 -12
- package/package.json +7 -9
- package/dist/lib/elur/component.cjs.map +0 -1
- package/dist/lib/elur/component.js.map +0 -1
- package/dist/lib/elur/hydrate/index.cjs.map +0 -1
- package/dist/lib/elur/hydrate/index.js.map +0 -1
- package/dist/lib/elur/reactivity.cjs.map +0 -1
- package/dist/lib/elur/reactivity.js.map +0 -1
- package/dist/lib/elur/template/dom-write.cjs +0 -2
- package/dist/lib/elur/template/dom-write.cjs.map +0 -1
- package/dist/lib/elur/template/dom-write.js +0 -16
- package/dist/lib/elur/template/dom-write.js.map +0 -1
- package/dist/lib/elur/template/keyed-diff.cjs +0 -2
- package/dist/lib/elur/template/keyed-diff.cjs.map +0 -1
- package/dist/lib/elur/template/keyed-diff.js +0 -100
- package/dist/lib/elur/template/keyed-diff.js.map +0 -1
- package/dist/lib/elur/template/mount-helpers.cjs +0 -2
- package/dist/lib/elur/template/mount-helpers.cjs.map +0 -1
- package/dist/lib/elur/template/mount-helpers.js +0 -132
- package/dist/lib/elur/template/mount-helpers.js.map +0 -1
- package/dist/lib/elur/template/node-binding.cjs +0 -2
- package/dist/lib/elur/template/node-binding.cjs.map +0 -1
- package/dist/lib/elur/template/node-binding.js +0 -95
- package/dist/lib/elur/template/node-binding.js.map +0 -1
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type KEntry, type KeyedList } from "../template/types.js";
|
|
2
|
+
import { type RepeatKey } from "../template/keyed.js";
|
|
3
|
+
/**
|
|
4
|
+
* C.16.1: lista keyed "live" — renderItem recibe accessors (`getItem`,
|
|
5
|
+
* `getIndex`) en vez del item capturado. Misma key + objeto nuevo → las
|
|
6
|
+
* señales del item se actualizan y los bindings re-corren sin remount,
|
|
7
|
+
* preservando identidad de DOM y estado del item.
|
|
8
|
+
*/
|
|
9
|
+
export interface LiveKeyedList<T = unknown> {
|
|
10
|
+
readonly __isKeyedList: true;
|
|
11
|
+
readonly live: true;
|
|
12
|
+
readonly items: T[];
|
|
13
|
+
readonly keyFn: (item: T, index: number) => string | number;
|
|
14
|
+
readonly renderItem: (getItem: () => T, getIndex: () => number) => unknown;
|
|
15
|
+
}
|
|
16
|
+
export declare function repeatLive<T>(items: T[], keyFn: (item: T, index: number) => string | number, renderItem: (getItem: () => T, getIndex: () => number) => unknown): LiveKeyedList<T>;
|
|
17
|
+
/**
|
|
18
|
+
* Mounts a single keyed item's rendered value before `endMarker` inside `parent`.
|
|
19
|
+
* Used by the DOM renderer and the hydration renderer so both engines share the
|
|
20
|
+
* exact same reconciliation semantics.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createKeyedMount(ctxSnapshot: Map<unknown, unknown>[]): (rendered: unknown, parent: Node, endMarker: Node) => () => void;
|
|
23
|
+
export interface KeyedDiffOptions {
|
|
24
|
+
/** Node marking the start of the keyed zone. */
|
|
25
|
+
zoneStart: Node;
|
|
26
|
+
/** End boundary; new content is inserted before this node. */
|
|
27
|
+
anchor: Node;
|
|
28
|
+
/** Live map of key → entry (start/end markers + cleanup). */
|
|
29
|
+
state: Map<RepeatKey, KEntry>;
|
|
30
|
+
/** Key order from the previous reconciliation pass. */
|
|
31
|
+
prevOrder: RepeatKey[];
|
|
32
|
+
/** The current keyed list value (clásica o live). */
|
|
33
|
+
list: KeyedList | LiveKeyedList;
|
|
34
|
+
/** Mounts a freshly rendered item into the DOM. */
|
|
35
|
+
mount: (rendered: unknown, parent: Node, endMarker: Node) => () => void;
|
|
36
|
+
/** Context snapshot for component mounts inside the effect. */
|
|
37
|
+
ctxSnapshot?: Map<unknown, unknown>[];
|
|
38
|
+
/** Called when a duplicate key is encountered. */
|
|
39
|
+
onDuplicateKey?: (key: RepeatKey) => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Reconciles a keyed list between `zoneStart` and `anchor` using the same LIS
|
|
43
|
+
* algorithm used by the DOM renderer. Total replacement (O(1)) when no key
|
|
44
|
+
* survives; otherwise remove/insert/move with minimal DOM operations.
|
|
45
|
+
*/
|
|
46
|
+
export declare function reconcileKeyedList(opts: KeyedDiffOptions): void;
|
|
47
|
+
/**
|
|
48
|
+
* B.12.7: lista keyed mutable — los mutadores aplican deltas directos al DOM
|
|
49
|
+
* (insert/remove/set/move) sin re-correr la reconciliación. La renderFn recibe
|
|
50
|
+
* accessors como `repeatLive` — set() actualiza la señal del item sin remount.
|
|
51
|
+
*
|
|
52
|
+
* ```ts
|
|
53
|
+
* const list = liveList({ key: u => u.id, render: (getItem) => html`<li>${() => getItem().name}</li>` });
|
|
54
|
+
* html`<ul>${list}</ul>` // monta la zona vacía
|
|
55
|
+
* list.push({id:1,name:"a"}); // inserta sin diff
|
|
56
|
+
* list.set(1, {id:1,name:"b"}); // actualiza in-place
|
|
57
|
+
* list.remove(1);
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export interface DeltaList<T, K = string | number> {
|
|
61
|
+
readonly __isKeyedList: true;
|
|
62
|
+
readonly delta: true;
|
|
63
|
+
readonly items: readonly T[];
|
|
64
|
+
readonly length: number;
|
|
65
|
+
/** @internal — monta la zona (markers + entries) antes de `anchor`. */
|
|
66
|
+
_mount(parent: Node, anchor: Node): void;
|
|
67
|
+
push(item: T): number;
|
|
68
|
+
insert(index: number, item: T): void;
|
|
69
|
+
remove(key: K): boolean;
|
|
70
|
+
set(key: K, item: T): boolean;
|
|
71
|
+
move(key: K, toIndex: number): void;
|
|
72
|
+
clear(): void;
|
|
73
|
+
/** @internal — dispone todo el subárbol. */
|
|
74
|
+
_dispose(): void;
|
|
75
|
+
}
|
|
76
|
+
export declare function liveList<T, K extends string | number>(opts: {
|
|
77
|
+
key: (item: T) => K;
|
|
78
|
+
render: (getItem: () => T, getIndex: () => number) => unknown;
|
|
79
|
+
}): DeltaList<T, K>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type KEntry, type KeyedList } from "../template/types.js";
|
|
2
|
+
import { type RepeatKey } from "../template/keyed.js";
|
|
3
|
+
/**
|
|
4
|
+
* C.16.1: lista keyed "live" — renderItem recibe accessors (`getItem`,
|
|
5
|
+
* `getIndex`) en vez del item capturado. Misma key + objeto nuevo → las
|
|
6
|
+
* señales del item se actualizan y los bindings re-corren sin remount,
|
|
7
|
+
* preservando identidad de DOM y estado del item.
|
|
8
|
+
*/
|
|
9
|
+
export interface LiveKeyedList<T = unknown> {
|
|
10
|
+
readonly __isKeyedList: true;
|
|
11
|
+
readonly live: true;
|
|
12
|
+
readonly items: T[];
|
|
13
|
+
readonly keyFn: (item: T, index: number) => string | number;
|
|
14
|
+
readonly renderItem: (getItem: () => T, getIndex: () => number) => unknown;
|
|
15
|
+
}
|
|
16
|
+
export declare function repeatLive<T>(items: T[], keyFn: (item: T, index: number) => string | number, renderItem: (getItem: () => T, getIndex: () => number) => unknown): LiveKeyedList<T>;
|
|
17
|
+
/**
|
|
18
|
+
* Mounts a single keyed item's rendered value before `endMarker` inside `parent`.
|
|
19
|
+
* Used by the DOM renderer and the hydration renderer so both engines share the
|
|
20
|
+
* exact same reconciliation semantics.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createKeyedMount(ctxSnapshot: Map<unknown, unknown>[]): (rendered: unknown, parent: Node, endMarker: Node) => () => void;
|
|
23
|
+
export interface KeyedDiffOptions {
|
|
24
|
+
/** Node marking the start of the keyed zone. */
|
|
25
|
+
zoneStart: Node;
|
|
26
|
+
/** End boundary; new content is inserted before this node. */
|
|
27
|
+
anchor: Node;
|
|
28
|
+
/** Live map of key → entry (start/end markers + cleanup). */
|
|
29
|
+
state: Map<RepeatKey, KEntry>;
|
|
30
|
+
/** Key order from the previous reconciliation pass. */
|
|
31
|
+
prevOrder: RepeatKey[];
|
|
32
|
+
/** The current keyed list value (clásica o live). */
|
|
33
|
+
list: KeyedList | LiveKeyedList;
|
|
34
|
+
/** Mounts a freshly rendered item into the DOM. */
|
|
35
|
+
mount: (rendered: unknown, parent: Node, endMarker: Node) => () => void;
|
|
36
|
+
/** Context snapshot for component mounts inside the effect. */
|
|
37
|
+
ctxSnapshot?: Map<unknown, unknown>[];
|
|
38
|
+
/** Called when a duplicate key is encountered. */
|
|
39
|
+
onDuplicateKey?: (key: RepeatKey) => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Reconciles a keyed list between `zoneStart` and `anchor` using the same LIS
|
|
43
|
+
* algorithm used by the DOM renderer. Total replacement (O(1)) when no key
|
|
44
|
+
* survives; otherwise remove/insert/move with minimal DOM operations.
|
|
45
|
+
*/
|
|
46
|
+
export declare function reconcileKeyedList(opts: KeyedDiffOptions): void;
|
|
47
|
+
/**
|
|
48
|
+
* B.12.7: lista keyed mutable — los mutadores aplican deltas directos al DOM
|
|
49
|
+
* (insert/remove/set/move) sin re-correr la reconciliación. La renderFn recibe
|
|
50
|
+
* accessors como `repeatLive` — set() actualiza la señal del item sin remount.
|
|
51
|
+
*
|
|
52
|
+
* ```ts
|
|
53
|
+
* const list = liveList({ key: u => u.id, render: (getItem) => html`<li>${() => getItem().name}</li>` });
|
|
54
|
+
* html`<ul>${list}</ul>` // monta la zona vacía
|
|
55
|
+
* list.push({id:1,name:"a"}); // inserta sin diff
|
|
56
|
+
* list.set(1, {id:1,name:"b"}); // actualiza in-place
|
|
57
|
+
* list.remove(1);
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export interface DeltaList<T, K = string | number> {
|
|
61
|
+
readonly __isKeyedList: true;
|
|
62
|
+
readonly delta: true;
|
|
63
|
+
readonly items: readonly T[];
|
|
64
|
+
readonly length: number;
|
|
65
|
+
/** @internal — monta la zona (markers + entries) antes de `anchor`. */
|
|
66
|
+
_mount(parent: Node, anchor: Node): void;
|
|
67
|
+
push(item: T): number;
|
|
68
|
+
insert(index: number, item: T): void;
|
|
69
|
+
remove(key: K): boolean;
|
|
70
|
+
set(key: K, item: T): boolean;
|
|
71
|
+
move(key: K, toIndex: number): void;
|
|
72
|
+
clear(): void;
|
|
73
|
+
/** @internal — dispone todo el subárbol. */
|
|
74
|
+
_dispose(): void;
|
|
75
|
+
}
|
|
76
|
+
export declare function liveList<T, K extends string | number>(opts: {
|
|
77
|
+
key: (item: T) => K;
|
|
78
|
+
render: (getItem: () => T, getIndex: () => number) => unknown;
|
|
79
|
+
}): DeltaList<T, K>;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { batch as e, createRoot as t, signal as n } from "./reactivity.js";
|
|
2
|
+
import { isElurTemplate as r } from "../template/types.js";
|
|
3
|
+
import { isElurComponent as i } from "../../lifecycle.js";
|
|
4
|
+
import { ComponentInstance as a, isComponentInvocation as o } from "./component.js";
|
|
5
|
+
import { _mountComponentWithCtx as s } from "./mount-helpers.js";
|
|
6
|
+
import { _keyedItemsEqual as c, getSequence as l } from "../template/keyed.js";
|
|
7
|
+
//#region src/elur/next-2/keyed-diff.ts
|
|
8
|
+
function u(e) {
|
|
9
|
+
return (n, c, l) => {
|
|
10
|
+
let u, d = t((t) => {
|
|
11
|
+
if (i(n)) u = s(n, c, l, e);
|
|
12
|
+
else if (o(n)) {
|
|
13
|
+
let t = new a(n);
|
|
14
|
+
t.mount(c, l, { ctxSnapshot: e }), u = () => t.unmount();
|
|
15
|
+
} else if (r(n)) u = n._render(c, l);
|
|
16
|
+
else if (n != null && n !== !1) {
|
|
17
|
+
let e = document.createTextNode(String(n));
|
|
18
|
+
c.insertBefore(e, l), u = () => e.parentNode?.removeChild(e);
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
});
|
|
22
|
+
return () => {
|
|
23
|
+
u?.(), d();
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function d(e, t, n) {
|
|
28
|
+
let r = document.createTextNode(""), i = document.createTextNode("");
|
|
29
|
+
t.appendChild(r), t.appendChild(i);
|
|
30
|
+
let a = n(e, t, i), o = r.nextSibling;
|
|
31
|
+
return o !== null && o !== i && o === i.previousSibling ? (t.removeChild(r), t.removeChild(i), {
|
|
32
|
+
start: o,
|
|
33
|
+
end: o,
|
|
34
|
+
cleanup: a
|
|
35
|
+
}) : {
|
|
36
|
+
start: r,
|
|
37
|
+
end: i,
|
|
38
|
+
cleanup: a
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
var f = typeof Element < "u" && "moveBefore" in Element.prototype ? (e, t, n) => e.moveBefore(t, n) : (e, t, n) => e.insertBefore(t, n);
|
|
42
|
+
function p(t) {
|
|
43
|
+
let { zoneStart: r, anchor: i, prevOrder: a, list: o, mount: s } = t, u = t.state, p = o.live === !0, m = (e) => {
|
|
44
|
+
let t = o.items[e];
|
|
45
|
+
if (!p) return { rendered: o.renderFn(t, e) };
|
|
46
|
+
let r = n(t), i = n(e);
|
|
47
|
+
return {
|
|
48
|
+
rendered: o.renderItem(() => r.value, () => i.value),
|
|
49
|
+
itemSig: r,
|
|
50
|
+
indexSig: i
|
|
51
|
+
};
|
|
52
|
+
}, h = i.parentNode;
|
|
53
|
+
if (!h) return;
|
|
54
|
+
let g = (e, t, n) => {
|
|
55
|
+
let r = u.get(e);
|
|
56
|
+
r.cleanup();
|
|
57
|
+
let i = r.start;
|
|
58
|
+
for (; i;) {
|
|
59
|
+
let e = i === r.end ? null : i.nextSibling;
|
|
60
|
+
if (i.parentNode?.removeChild(i), !e) break;
|
|
61
|
+
i = e;
|
|
62
|
+
}
|
|
63
|
+
let a = document.createDocumentFragment(), { rendered: c } = m(t), l = d(c, a, s);
|
|
64
|
+
u.set(e, {
|
|
65
|
+
...l,
|
|
66
|
+
item: o.items[t]
|
|
67
|
+
}), h.insertBefore(a, n);
|
|
68
|
+
}, _ = (e, t) => {
|
|
69
|
+
let n = u.get(e);
|
|
70
|
+
n && !n.itemSig && !c(n.item, o.items[t]) && g(e, t, n.end.nextSibling);
|
|
71
|
+
}, v = o.items.map((e, t) => o.keyFn(e, t)), y = new Set(v), b = !1;
|
|
72
|
+
if (u.size > 0) {
|
|
73
|
+
for (let e of u.keys()) if (y.has(e)) {
|
|
74
|
+
b = !0;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (!b) {
|
|
79
|
+
if (u.size > 0) {
|
|
80
|
+
let e = r.nextSibling;
|
|
81
|
+
for (; e && e !== i;) {
|
|
82
|
+
let t = e.nextSibling;
|
|
83
|
+
e.parentNode?.removeChild(e), e = t;
|
|
84
|
+
}
|
|
85
|
+
for (let e of u.values()) e.cleanup();
|
|
86
|
+
u.clear();
|
|
87
|
+
}
|
|
88
|
+
if (v.length > 0) {
|
|
89
|
+
let n = document.createDocumentFragment();
|
|
90
|
+
e(() => {
|
|
91
|
+
for (let e = 0; e < v.length; e++) {
|
|
92
|
+
let r = v[e], i = o.items[e], { rendered: a, itemSig: c, indexSig: l } = m(e), f = d(a, n, s);
|
|
93
|
+
u.has(r) && t.onDuplicateKey?.(r), u.set(r, {
|
|
94
|
+
...f,
|
|
95
|
+
item: i,
|
|
96
|
+
itemSig: c,
|
|
97
|
+
indexSig: l
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}), h.insertBefore(n, i);
|
|
101
|
+
}
|
|
102
|
+
a.length = 0, a.push(...v);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
let x = (t, n) => {
|
|
106
|
+
let r = u.get(t);
|
|
107
|
+
if (r?.itemSig) {
|
|
108
|
+
let t = o.items[n], i = c(r.item, t);
|
|
109
|
+
r.item = t, (!i || r.indexSig.peek() !== n) && e(() => {
|
|
110
|
+
r.itemSig.value = t, r.indexSig.value = n;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
{
|
|
115
|
+
let n = 0, r = Math.min(a.length, v.length);
|
|
116
|
+
for (; n < r && a[n] === v[n];) n++;
|
|
117
|
+
let c = a.length - 1, l = v.length - 1;
|
|
118
|
+
for (; c >= n && l >= n && a[c] === v[l];) c--, l--;
|
|
119
|
+
if (n > c || n > l) {
|
|
120
|
+
for (let e = 0; e < n; e++) x(v[e], e);
|
|
121
|
+
for (let e = l + 1; e < v.length; e++) x(v[e], e);
|
|
122
|
+
for (let e = 0; e < n; e++) _(v[e], e);
|
|
123
|
+
for (let e = l + 1; e < v.length; e++) _(v[e], e);
|
|
124
|
+
if (n <= c) for (let e = n; e <= c; e++) {
|
|
125
|
+
let t = a[e], n = u.get(t);
|
|
126
|
+
n.cleanup();
|
|
127
|
+
let r = n.start;
|
|
128
|
+
for (; r;) {
|
|
129
|
+
let e = r === n.end ? null : r.nextSibling;
|
|
130
|
+
if (r.parentNode?.removeChild(r), !e) break;
|
|
131
|
+
r = e;
|
|
132
|
+
}
|
|
133
|
+
u.delete(t);
|
|
134
|
+
}
|
|
135
|
+
if (n <= l) {
|
|
136
|
+
let r = n < a.length ? u.get(a[n]).start : i, c = document.createDocumentFragment();
|
|
137
|
+
e(() => {
|
|
138
|
+
for (let e = n; e <= l; e++) {
|
|
139
|
+
let n = v[e], { rendered: r, itemSig: i, indexSig: a } = m(e), l = d(r, c, s);
|
|
140
|
+
u.has(n) && t.onDuplicateKey?.(n), u.set(n, {
|
|
141
|
+
...l,
|
|
142
|
+
item: o.items[e],
|
|
143
|
+
itemSig: i,
|
|
144
|
+
indexSig: a
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}), h.insertBefore(c, r);
|
|
148
|
+
}
|
|
149
|
+
a.length = 0, a.push(...v);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
let S = /* @__PURE__ */ new Map();
|
|
154
|
+
for (let e = 0; e < v.length; e++) S.set(v[e], e);
|
|
155
|
+
let C = new Int32Array(v.length), w = !1, T = 0;
|
|
156
|
+
for (let e = 0; e < a.length; e++) {
|
|
157
|
+
let t = a[e], n = S.get(t);
|
|
158
|
+
if (n === void 0) {
|
|
159
|
+
let e = u.get(t);
|
|
160
|
+
e.cleanup();
|
|
161
|
+
let n = e.start;
|
|
162
|
+
for (; n;) {
|
|
163
|
+
let t = n === e.end ? null : n.nextSibling;
|
|
164
|
+
if (n.parentNode?.removeChild(n), !t) break;
|
|
165
|
+
n = t;
|
|
166
|
+
}
|
|
167
|
+
u.delete(t);
|
|
168
|
+
} else C[n] = e + 1, n >= T ? T = n : w = !0;
|
|
169
|
+
}
|
|
170
|
+
let E = w ? l(C) : [], D = E.length - 1, O = i;
|
|
171
|
+
for (let n = v.length - 1; n >= 0; n--) {
|
|
172
|
+
let r = v[n];
|
|
173
|
+
if (C[n] === 0) {
|
|
174
|
+
let e = o.items[n], i = document.createDocumentFragment(), { rendered: a, itemSig: c, indexSig: l } = m(n), f = d(a, i, s);
|
|
175
|
+
u.has(r) && t.onDuplicateKey?.(r), u.set(r, {
|
|
176
|
+
...f,
|
|
177
|
+
item: e,
|
|
178
|
+
itemSig: c,
|
|
179
|
+
indexSig: l
|
|
180
|
+
}), h.insertBefore(i, O), O = f.start;
|
|
181
|
+
} else {
|
|
182
|
+
let t = u.get(r);
|
|
183
|
+
if (t.itemSig) {
|
|
184
|
+
let r = o.items[n], i = c(t.item, r);
|
|
185
|
+
t.item = r, (!i || t.indexSig.peek() !== n) && e(() => {
|
|
186
|
+
t.itemSig.value = r, t.indexSig.value = n;
|
|
187
|
+
});
|
|
188
|
+
} else if (!c(t.item, o.items[n])) {
|
|
189
|
+
g(r, n, O), t = u.get(r), w && D >= 0 && n === E[D] && D--, O = t.start;
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
if (w) if (D < 0 || n !== E[D]) {
|
|
193
|
+
let e = t.start;
|
|
194
|
+
for (; e;) {
|
|
195
|
+
let n = e === t.end ? null : e.nextSibling;
|
|
196
|
+
if (f(h, e, O), !n) break;
|
|
197
|
+
e = n;
|
|
198
|
+
}
|
|
199
|
+
} else D--;
|
|
200
|
+
O = t.start;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
a.length = 0, a.push(...v);
|
|
204
|
+
}
|
|
205
|
+
//#endregion
|
|
206
|
+
export { u as createKeyedMount, p as reconcileKeyedList };
|
|
207
|
+
|
|
208
|
+
//# sourceMappingURL=keyed-diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyed-diff.js","names":[],"sources":["../../../../src/elur/next-2/keyed-diff.ts"],"sourcesContent":["import { batch, createRoot, signal, type Signal } from \"./reactivity.js\";\nimport { isElurComponent } from \"../lifecycle.js\";\nimport { ComponentInstance, isComponentInvocation } from \"./component.js\";\nimport { _mountComponentWithCtx } from \"../template/mount-helpers.js\";\nimport { isElurTemplate, type KEntry, type KeyedList } from \"../template/types.js\";\nimport { getSequence, _keyedItemsEqual, type RepeatKey } from \"../template/keyed.js\";\nimport { _captureContextSnapshot } from \"../context.js\";\n\n// =============================================================================\n// --- next/ — keyed list reconciliation con ownership por item ---\n// Fork de ../template/keyed-diff.ts: igual que el actual, pero cada item monta\n// bajo su propio root owner (createRoot del grafo next). Sus effects internos\n// pertenecen al item y no al effect del repeat — así sobreviven a re-orders\n// y se destruyen con entry.cleanup() al removerse (A.11/B.10 del plan).\n// =============================================================================\n\n/**\n * C.16.1: lista keyed \"live\" — renderItem recibe accessors (`getItem`,\n * `getIndex`) en vez del item capturado. Misma key + objeto nuevo → las\n * señales del item se actualizan y los bindings re-corren sin remount,\n * preservando identidad de DOM y estado del item.\n */\nexport interface LiveKeyedList<T = unknown> {\n readonly __isKeyedList: true;\n readonly live: true;\n readonly items: T[];\n readonly keyFn: (item: T, index: number) => string | number;\n readonly renderItem: (getItem: () => T, getIndex: () => number) => unknown;\n}\n\nexport function repeatLive<T>(\n items: T[],\n keyFn: (item: T, index: number) => string | number,\n renderItem: (getItem: () => T, getIndex: () => number) => unknown,\n): LiveKeyedList<T> {\n return { __isKeyedList: true as const, live: true as const, items, keyFn, renderItem };\n}\n\n/**\n * Mounts a single keyed item's rendered value before `endMarker` inside `parent`.\n * Used by the DOM renderer and the hydration renderer so both engines share the\n * exact same reconciliation semantics.\n */\nexport function createKeyedMount(\n ctxSnapshot: Map<unknown, unknown>[],\n): (rendered: unknown, parent: Node, endMarker: Node) => () => void {\n return (rendered: unknown, parent: Node, endMarker: Node): (() => void) => {\n let inner: (() => void) | void;\n const disposeOwner = createRoot((dispose) => {\n if (isElurComponent(rendered)) {\n inner = _mountComponentWithCtx(rendered, parent, endMarker, ctxSnapshot);\n } else if (isComponentInvocation(rendered)) {\n // Invocación funcional: montar por el kernel — setup una vez,\n // owner propio dentro del root del item.\n const inst = new ComponentInstance(rendered);\n inst.mount(parent, endMarker, { ctxSnapshot });\n inner = () => inst.unmount();\n } else if (isElurTemplate(rendered)) {\n inner = rendered._render(parent, endMarker);\n } else if (rendered != null && rendered !== false) {\n const node = document.createTextNode(String(rendered));\n parent.insertBefore(node, endMarker);\n inner = () => node.parentNode?.removeChild(node);\n }\n return dispose;\n });\n return () => {\n inner?.();\n disposeOwner();\n };\n };\n}\n\n/**\n * Entry con contenido single-node: los markers start/end se eliminan y el\n * nodo mismo actúa como ambos bounds — 2 nodos menos por entry y menos\n * trabajo en remove/move/clear. Multi-nodo/vacío conserva los markers.\n */\nfunction createKeyedEntry(\n rendered: unknown,\n frag: DocumentFragment,\n mount: (rendered: unknown, parent: Node, endMarker: Node) => () => void,\n): { start: Comment; end: Comment; cleanup: () => void } {\n const start = document.createTextNode(\"\") as unknown as Comment;\n const end = document.createTextNode(\"\") as unknown as Comment;\n frag.appendChild(start);\n frag.appendChild(end);\n const cleanup = mount(rendered, frag, end);\n const first = start.nextSibling;\n if (first !== null && first !== end && first === end.previousSibling) {\n frag.removeChild(start);\n frag.removeChild(end);\n return { start: first as unknown as Comment, end: first as unknown as Comment, cleanup };\n }\n return { start, end, cleanup };\n}\n\n/**\n * `moveBefore` (Chrome 133+) mueve un nodo sin desconectarlo — preserva\n * iframes, focus y animaciones en reorders. Fallback a insertBefore.\n */\nconst moveNode: (parent: Node, node: Node, before: Node | null) => void =\n typeof Element !== \"undefined\" && \"moveBefore\" in Element.prototype\n ? (parent, node, before) => (parent as Element).moveBefore(node, before)\n : (parent, node, before) => parent.insertBefore(node, before);\n\n/**\n * C.16.1: entry con el item que la originó — detecta el caso\n * \"misma key, objeto nuevo\" (el renderFn capturó el item viejo).\n */\ninterface KeyedItemEntry extends KEntry {\n item: unknown;\n /** C.16.1 live: señal por item (sólo en repeatLive). */\n itemSig?: import(\"./reactivity.js\").Signal<unknown>;\n indexSig?: import(\"./reactivity.js\").Signal<number>;\n}\n\nexport interface KeyedDiffOptions {\n /** Node marking the start of the keyed zone. */\n zoneStart: Node;\n /** End boundary; new content is inserted before this node. */\n anchor: Node;\n /** Live map of key → entry (start/end markers + cleanup). */\n state: Map<RepeatKey, KEntry>;\n /** Key order from the previous reconciliation pass. */\n prevOrder: RepeatKey[];\n /** The current keyed list value (clásica o live). */\n list: KeyedList | LiveKeyedList;\n /** Mounts a freshly rendered item into the DOM. */\n mount: (rendered: unknown, parent: Node, endMarker: Node) => () => void;\n /** Context snapshot for component mounts inside the effect. */\n ctxSnapshot?: Map<unknown, unknown>[];\n /** Called when a duplicate key is encountered. */\n onDuplicateKey?: (key: RepeatKey) => void;\n}\n\n/**\n * Reconciles a keyed list between `zoneStart` and `anchor` using the same LIS\n * algorithm used by the DOM renderer. Total replacement (O(1)) when no key\n * survives; otherwise remove/insert/move with minimal DOM operations.\n */\nexport function reconcileKeyedList(opts: KeyedDiffOptions): void {\n const { zoneStart, anchor, prevOrder, list, mount } = opts;\n const state = opts.state as Map<RepeatKey, KeyedItemEntry>;\n const live = (list as LiveKeyedList).live === true;\n // Render del item i-ésimo: live → accessors + señales; clásico → valor.\n const renderItem = (i: number): { rendered: unknown; itemSig?: Signal<unknown>; indexSig?: Signal<number> } => {\n const item = list.items[i];\n if (!live) return { rendered: (list as KeyedList).renderFn(item as never, i) };\n const itemSig = signal<unknown>(item);\n const indexSig = signal<number>(i);\n const rendered = (list as LiveKeyedList).renderItem(\n () => itemSig.value as never,\n () => indexSig.value,\n );\n return { rendered, itemSig, indexSig };\n };\n const parent = anchor.parentNode;\n if (!parent) return;\n\n /**\n * C.16.4 (clásico): entry cuya key sobrevivió pero cuyo item fue\n * reemplazado por otro objeto → remount in-place (los bindings\n * capturaron el item viejo). Las live no pasan por aquí: sus\n * bindings leen itemSig y se actualizan por señal.\n */\n const remountItem = (key: RepeatKey, i: number, ref: Node | null): void => {\n const entry = state.get(key)!;\n entry.cleanup();\n let node: Node | null = entry.start;\n while (node) {\n const next: ChildNode | null = node === entry.end ? null : node.nextSibling;\n node.parentNode?.removeChild(node);\n if (!next) break;\n node = next;\n }\n const frag = document.createDocumentFragment();\n const { rendered } = renderItem(i);\n const ne = createKeyedEntry(rendered, frag, mount);\n state.set(key, { ...ne, item: list.items[i] });\n parent.insertBefore(frag, ref);\n };\n const remountIfReplaced = (key: RepeatKey, i: number): void => {\n const entry = state.get(key);\n if (entry && !entry.itemSig && !_keyedItemsEqual(entry.item, list.items[i])) {\n remountItem(key, i, entry.end.nextSibling);\n }\n };\n\n const newKeyOrder: RepeatKey[] = list.items.map((item, idx) => list.keyFn(item as never, idx));\n const newKeySet = new Set(newKeyOrder);\n\n let anyKeysSurvive = false;\n if (state.size > 0) {\n for (const k of state.keys()) {\n if (newKeySet.has(k)) {\n anyKeysSurvive = true;\n break;\n }\n }\n }\n\n // 1. Initial render or total replacement (O(1) path)\n if (!anyKeysSurvive) {\n if (state.size > 0) {\n // Sibling walk — Range.deleteContents es patológico en\n // happy-dom sobre zonas de miles de nodos.\n let node: Node | null = zoneStart.nextSibling;\n while (node && node !== anchor) {\n const next = node.nextSibling;\n node.parentNode?.removeChild(node);\n node = next;\n }\n for (const entry of state.values()) entry.cleanup();\n state.clear();\n }\n\n if (newKeyOrder.length > 0) {\n const frag = document.createDocumentFragment();\n batch(() => {\n for (let i = 0; i < newKeyOrder.length; i++) {\n const key = newKeyOrder[i];\n const item = list.items[i];\n const { rendered, itemSig, indexSig } = renderItem(i);\n const entry = createKeyedEntry(rendered, frag, mount);\n if (state.has(key)) opts.onDuplicateKey?.(key);\n state.set(key, { ...entry, item, itemSig, indexSig });\n }\n });\n parent.insertBefore(frag, anchor);\n }\n prevOrder.length = 0;\n prevOrder.push(...newKeyOrder);\n return;\n }\n\n // C.16.2: fast paths — prefix/suffix comunes sin Map/LIS. Si cubren el\n // diff completo (append, prepend, truncate, insert/remove en el medio)\n // terminamos aquí; si el medio tiene moves, cae al camino LIS completo.\n const updateLiveEntry = (key: RepeatKey, i: number) => {\n const e = state.get(key);\n if (e?.itemSig) {\n const it = list.items[i];\n const sameItem = _keyedItemsEqual(e.item, it);\n e.item = it;\n if (!sameItem || e.indexSig!.peek() !== i) {\n batch(() => {\n e.itemSig!.value = it;\n e.indexSig!.value = i;\n });\n }\n }\n };\n {\n let pi = 0;\n const minLen = Math.min(prevOrder.length, newKeyOrder.length);\n while (pi < minLen && prevOrder[pi] === newKeyOrder[pi]) pi++;\n let pj = prevOrder.length - 1;\n let nk = newKeyOrder.length - 1;\n while (pj >= pi && nk >= pi && prevOrder[pj] === newKeyOrder[nk]) {\n pj--;\n nk--;\n }\n if (pi > pj || pi > nk) {\n // Cubierto por prefix+suffix: el medio es sólo insertar o borrar.\n for (let m = 0; m < pi; m++) updateLiveEntry(newKeyOrder[m], m);\n for (let m = nk + 1; m < newKeyOrder.length; m++) {\n updateLiveEntry(newKeyOrder[m], m);\n }\n // C.16.4: mismos checks para listas clásicas (remount in-place).\n for (let m = 0; m < pi; m++) remountIfReplaced(newKeyOrder[m], m);\n for (let m = nk + 1; m < newKeyOrder.length; m++) {\n remountIfReplaced(newKeyOrder[m], m);\n }\n if (pi <= pj) {\n // Borrar prev[pi..pj]\n for (let m = pi; m <= pj; m++) {\n const key = prevOrder[m];\n const entry = state.get(key)!;\n entry.cleanup();\n let node: Node | null = entry.start;\n while (node) {\n const next: ChildNode | null = node === entry.end ? null : node.nextSibling;\n node.parentNode?.removeChild(node);\n if (!next) break;\n node = next;\n }\n state.delete(key);\n }\n }\n if (pi <= nk) {\n // Insertar new[pi..nk] antes del primer item del suffix\n // (prevOrder[pi] sobrevivió — si no hay suffix, anchor).\n const refNode = pi < prevOrder.length\n ? state.get(prevOrder[pi])!.start\n : anchor;\n const frag = document.createDocumentFragment();\n batch(() => {\n for (let m = pi; m <= nk; m++) {\n const key = newKeyOrder[m];\n const { rendered, itemSig, indexSig } = renderItem(m);\n const entry = createKeyedEntry(rendered, frag, mount);\n if (state.has(key)) opts.onDuplicateKey?.(key);\n state.set(key, { ...entry, item: list.items[m], itemSig, indexSig });\n }\n });\n parent.insertBefore(frag, refNode);\n }\n prevOrder.length = 0;\n prevOrder.push(...newKeyOrder);\n return;\n }\n }\n\n // 2. Reconciliation with LIS\n const keyToNewIndex = new Map<RepeatKey, number>();\n for (let i = 0; i < newKeyOrder.length; i++) {\n keyToNewIndex.set(newKeyOrder[i], i);\n }\n\n const newIndexToOldIndexMap = new Int32Array(newKeyOrder.length);\n let moved = false;\n let maxNewIndexSoFar = 0;\n\n for (let i = 0; i < prevOrder.length; i++) {\n const key = prevOrder[i];\n const newIndex = keyToNewIndex.get(key);\n\n if (newIndex === undefined) {\n const entry = state.get(key)!;\n entry.cleanup();\n let node: Node | null = entry.start;\n while (node) {\n const next: ChildNode | null = node === entry.end ? null : node.nextSibling;\n node.parentNode?.removeChild(node);\n if (!next) break;\n node = next;\n }\n state.delete(key);\n } else {\n newIndexToOldIndexMap[newIndex] = i + 1;\n if (newIndex >= maxNewIndexSoFar) {\n maxNewIndexSoFar = newIndex;\n } else {\n moved = true;\n }\n }\n }\n\n const increasingNewIndexSequence = moved ? getSequence(newIndexToOldIndexMap) : [];\n let j = increasingNewIndexSequence.length - 1;\n let insertionPoint: Node = anchor;\n\n for (let i = newKeyOrder.length - 1; i >= 0; i--) {\n const key = newKeyOrder[i];\n const isNew = newIndexToOldIndexMap[i] === 0;\n\n if (isNew) {\n const it = list.items[i];\n const frag = document.createDocumentFragment();\n const { rendered, itemSig, indexSig } = renderItem(i);\n const entry = createKeyedEntry(rendered, frag, mount);\n if (state.has(key)) opts.onDuplicateKey?.(key);\n state.set(key, { ...entry, item: it, itemSig, indexSig });\n parent.insertBefore(frag, insertionPoint);\n insertionPoint = entry.start;\n } else {\n let entry = state.get(key)!;\n // C.16.1 (live): misma key + objeto nuevo → actualizar las\n // señales del item — bindings re-corren, DOM preservado.\n if (entry.itemSig) {\n const newItem = list.items[i];\n const sameItem = _keyedItemsEqual(entry.item, newItem);\n entry.item = newItem;\n if (!sameItem || entry.indexSig!.peek() !== i) {\n batch(() => {\n entry.itemSig!.value = newItem;\n entry.indexSig!.value = i;\n });\n }\n } else if (!_keyedItemsEqual(entry.item, list.items[i])) {\n // C.16.4 (clásico): mismo caso sin accessors → remount.\n // Insertar antes de insertionPoint equivale a su posición\n // final en el walk reverso; se conserva el bookkeeping LIS.\n remountItem(key, i, insertionPoint);\n entry = state.get(key)!;\n if (moved && j >= 0 && i === increasingNewIndexSequence[j]) j--;\n insertionPoint = entry.start;\n continue;\n }\n if (moved) {\n if (j < 0 || i !== increasingNewIndexSequence[j]) {\n let node: Node | null = entry.start;\n while (node) {\n const next: ChildNode | null = node === entry.end ? null : node.nextSibling;\n moveNode(parent, node, insertionPoint);\n if (!next) break;\n node = next;\n }\n } else {\n j--;\n }\n }\n insertionPoint = entry.start;\n }\n }\n\n prevOrder.length = 0;\n prevOrder.push(...newKeyOrder);\n}\n\n// =============================================================================\n// B.12.7 — liveList(): lista con mutación incremental (deltas, estilo DBSP)\n// =============================================================================\n\ninterface DeltaEntry<T> {\n key: RepeatKey;\n item: T;\n itemSig: Signal<T>;\n indexSig: Signal<number>;\n start: Node;\n end: Node;\n cleanup: () => void;\n}\n\n/**\n * B.12.7: lista keyed mutable — los mutadores aplican deltas directos al DOM\n * (insert/remove/set/move) sin re-correr la reconciliación. La renderFn recibe\n * accessors como `repeatLive` — set() actualiza la señal del item sin remount.\n *\n * ```ts\n * const list = liveList({ key: u => u.id, render: (getItem) => html`<li>${() => getItem().name}</li>` });\n * html`<ul>${list}</ul>` // monta la zona vacía\n * list.push({id:1,name:\"a\"}); // inserta sin diff\n * list.set(1, {id:1,name:\"b\"}); // actualiza in-place\n * list.remove(1);\n * ```\n */\nexport interface DeltaList<T, K = string | number> {\n readonly __isKeyedList: true;\n readonly delta: true;\n readonly items: readonly T[];\n readonly length: number;\n /** @internal — monta la zona (markers + entries) antes de `anchor`. */\n _mount(parent: Node, anchor: Node): void;\n push(item: T): number;\n insert(index: number, item: T): void;\n remove(key: K): boolean;\n set(key: K, item: T): boolean;\n move(key: K, toIndex: number): void;\n clear(): void;\n /** @internal — dispone todo el subárbol. */\n _dispose(): void;\n}\n\nexport function liveList<T, K extends string | number>(opts: {\n key: (item: T) => K;\n render: (getItem: () => T, getIndex: () => number) => unknown;\n}): DeltaList<T, K> {\n const entries: DeltaEntry<T>[] = [];\n const byKey = new Map<K, DeltaEntry<T>>();\n let parent: Node | null = null;\n let zoneEnd: Node | null = null;\n let mountFn: ((r: unknown, p: Node, e: Node) => () => void) | null = null;\n\n const api: DeltaList<T, K> = {\n __isKeyedList: true as const,\n delta: true as const,\n get items() { return entries.map((e) => e.item); },\n get length() { return entries.length; },\n\n _mount(p: Node, anchor: Node): void {\n if (parent) return; // ya montada — idempotente\n parent = p;\n zoneEnd = anchor;\n mountFn = createKeyedMount(_captureContextSnapshot());\n },\n\n push(item: T): number {\n api.insert(entries.length, item);\n return entries.length - 1;\n },\n\n insert(index: number, item: T): void {\n if (!parent || !zoneEnd || !mountFn) {\n throw new Error(\"[elur-next2] liveList: la lista no está montada (úsala en un binding primero).\");\n }\n const key = opts.key(item);\n if (byKey.has(key)) {\n console.warn(`[elur] liveList: duplicate key \"${key}\".`);\n return;\n }\n index = Math.max(0, Math.min(index, entries.length));\n const sMarker = document.createTextNode(\"\");\n const eMarker = document.createTextNode(\"\");\n const ref = index < entries.length ? entries[index].start : zoneEnd;\n parent.insertBefore(sMarker, ref);\n parent.insertBefore(eMarker, ref);\n const itemSig = signal(item);\n const indexSig = signal(index);\n const rendered = opts.render(() => itemSig.value, () => indexSig.value);\n const cleanup = mountFn(rendered, parent, eMarker);\n const entry: DeltaEntry<T> = { key, item, itemSig, indexSig, start: sMarker, end: eMarker, cleanup };\n entries.splice(index, 0, entry);\n byKey.set(key, entry);\n // Deltas de índice para los desplazados.\n for (let i = index + 1; i < entries.length; i++) entries[i].indexSig.value = i;\n },\n\n remove(key: K): boolean {\n const entry = byKey.get(key);\n if (!entry || !parent) return false;\n const i = entries.indexOf(entry);\n entry.cleanup();\n let node: Node | null = entry.start;\n while (node) {\n const next: ChildNode | null = node === entry.end ? null : node.nextSibling;\n parent.removeChild(node);\n if (!next) break;\n node = next;\n }\n entries.splice(i, 1);\n byKey.delete(key);\n for (let j = i; j < entries.length; j++) entries[j].indexSig.value = j;\n return true;\n },\n\n set(key: K, item: T): boolean {\n const entry = byKey.get(key);\n if (!entry) return false;\n entry.item = item;\n entry.itemSig.value = item;\n return true;\n },\n\n move(key: K, toIndex: number): void {\n const entry = byKey.get(key);\n if (!entry || !parent) return;\n const from = entries.indexOf(entry);\n toIndex = Math.max(0, Math.min(toIndex, entries.length - 1));\n if (from === toIndex) return;\n const ref = toIndex > from ? entries[toIndex].end.nextSibling : entries[toIndex].start;\n let node: Node | null = entry.start;\n while (node) {\n const next: ChildNode | null = node === entry.end ? null : node.nextSibling;\n moveNode(parent, node, ref);\n if (!next) break;\n node = next;\n }\n entries.splice(from, 1);\n entries.splice(toIndex, 0, entry);\n const lo = Math.min(from, toIndex), hi = Math.max(from, toIndex);\n for (let i = lo; i <= hi; i++) entries[i].indexSig.value = i;\n },\n\n clear(): void {\n // Bulk: las entries son contiguas en el DOM entre\n // entries[0].start y zoneEnd — sibling walk por nodos (O(n);\n // Range.deleteContents es patológico en happy-dom y el walk\n // evita indexOf+splice+deltas por fila = O(n²)).\n if (parent && zoneEnd && entries.length > 0) {\n let node: Node | null = entries[0].start;\n while (node && node !== zoneEnd) {\n const nextNode: Node | null = node.nextSibling;\n node.parentNode?.removeChild(node);\n node = nextNode;\n }\n }\n for (const e of entries) e.cleanup();\n entries.length = 0;\n byKey.clear();\n },\n\n _dispose(): void {\n api.clear();\n parent = null;\n zoneEnd = null;\n },\n };\n return api;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`../../lifecycle.cjs`),t=require(`./component.cjs`);var n=null;function r(e){if(n!==null)return e();n=[];let t=!1;try{let n=e();return t=!0,n}finally{let e=n;if(n=null,t)for(let t of e)t()}}function i(e){let t=n;n=[];let r=!1;try{let t=e();return r=!0,t}finally{let e=n;if(n=t,r)if(t)t.push(...e);else for(let t of e)t()}}function a(e){n?n.push(e):e()}function o(n,r,i){e._debugComponentMountStart(n);let o=t.adaptClassComponent(n);try{o.mount(r,i,{deferOnMount:e=>a(e)})}finally{e._debugComponentMountEnd(n)}return()=>{o.unmount(),e._debugComponentUnmount(n)}}function s(n,r,i){e._debugComponentMountStart(n);let o=t.adaptClassComponent(n);try{o.mount(r,i,{deferOnMount:e=>a(e)})}catch{}finally{e._debugComponentMountEnd(n)}return()=>{o.unmount(),e._debugComponentUnmount(n)}}function c(n,r,i,o){e._debugComponentMountStart(n);let s=t.adaptClassComponent(n);try{s.mount(r,i,{ctxSnapshot:o,deferOnMount:e=>a(e)})}finally{e._debugComponentMountEnd(n)}return()=>{s.unmount(),e._debugComponentUnmount(n)}}function l(n,r,i,a,o){e._debugComponentMountStart(n);let s=t.adaptClassComponent(n);try{s.mount(r,i,{deferOnMount:e=>a.push(e)})}finally{e._debugComponentMountEnd(n)}o.push(()=>{s.unmount(),e._debugComponentUnmount(n)})}exports._deferOnMount=a,exports._mountComponent=o,exports._mountComponentDeferred=l,exports._mountComponentSilent=s,exports._mountComponentWithCtx=c,exports._postMountScope=r,exports._postMountScopeSub=i;
|
|
2
|
+
//# sourceMappingURL=mount-helpers.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount-helpers.cjs","names":[],"sources":["../../../../src/elur/next-2/mount-helpers.ts"],"sourcesContent":["import {\n _debugComponentMountStart,\n _debugComponentMountEnd,\n _debugComponentUnmount,\n type ElurComponent,\n} from \"../lifecycle.js\";\nimport { type _captureContextSnapshot } from \"../context.js\";\nimport { adaptClassComponent } from \"./component.js\";\n\n// =============================================================================\n// --- next/ — component mounting sobre el kernel unificado (A.6–A.9) ---\n// Fork de ../template/mount-helpers.ts: misma superficie, pero cada mount pasa\n// por ComponentInstance — owner propio, máquina de estados, mount transaccional\n// con rollback, onMount post-commit, unmount idempotente.\n// =============================================================================\n\n// --- Post-commit onMount queue (misma superficie que el estable) -------------\n// El kernel ya difiere onMount por instancia via `deferOnMount`; esta cola\n// cubre los callers que NO pasan por el kernel (p.ej. error-boundary llama\n// `content.onMount` directamente sobre ElurComponent).\nlet pendingOnMount: Array<() => void> | null = null;\n\nexport function _postMountScope<T>(fn: () => T): T {\n if (pendingOnMount !== null) return fn();\n pendingOnMount = [];\n let ok = false;\n try {\n const r = fn();\n ok = true;\n return r;\n } finally {\n const q = pendingOnMount;\n pendingOnMount = null;\n if (ok) for (const h of q) h();\n }\n}\n\nexport function _postMountScopeSub<T>(fn: () => T): T {\n const outer = pendingOnMount;\n pendingOnMount = [];\n let ok = false;\n try {\n const r = fn();\n ok = true;\n return r;\n } finally {\n const q = pendingOnMount!;\n pendingOnMount = outer;\n if (ok) {\n if (outer) outer.push(...q);\n else for (const h of q) h();\n }\n }\n}\n\nexport function _deferOnMount(fn: () => void): void {\n if (pendingOnMount) pendingOnMount.push(fn);\n else fn();\n}\n\n/**\n * Monta un ElurComponent via kernel: onInit → render → _render → onMount\n * (post-commit). Errores van por onError o re-lanzan. Cleanup = unmount().\n */\nexport function _mountComponent(\n inst: ElurComponent,\n parent: Node,\n before: Node | null,\n): () => void {\n _debugComponentMountStart(inst);\n const ci = adaptClassComponent(inst);\n try {\n ci.mount(parent, before, {\n deferOnMount: (fire) => _deferOnMount(fire),\n });\n } finally {\n _debugComponentMountEnd(inst);\n }\n return () => {\n ci.unmount();\n _debugComponentUnmount(inst);\n };\n}\n\n/**\n * Igual que `_mountComponent` pero traga todos los errores de lifecycle —\n * para contenido de transitions y fallbacks de error boundaries.\n */\nexport function _mountComponentSilent(\n inst: ElurComponent,\n parent: Node,\n before: Node | null,\n): () => void {\n _debugComponentMountStart(inst);\n const ci = adaptClassComponent(inst);\n // Errores silenciados: onError ausente → el kernel re-lanza → se traga aquí.\n try {\n ci.mount(parent, before, {\n deferOnMount: (fire) => _deferOnMount(fire),\n });\n } catch {\n /* silent */\n } finally {\n _debugComponentMountEnd(inst);\n }\n return () => {\n ci.unmount();\n _debugComponentUnmount(inst);\n };\n}\n\n/**\n * Monta con contexto capturado — para render dinámico/keyed dentro de\n * effects, donde provide/inject hereda del punto de declaración.\n */\nexport function _mountComponentWithCtx(\n inst: ElurComponent,\n parent: Node,\n before: Node | null,\n ctxSnapshot: ReturnType<typeof _captureContextSnapshot>,\n): () => void {\n _debugComponentMountStart(inst);\n const ci = adaptClassComponent(inst);\n try {\n ci.mount(parent, before, {\n ctxSnapshot,\n deferOnMount: (fire) => _deferOnMount(fire),\n });\n } finally {\n _debugComponentMountEnd(inst);\n }\n return () => {\n ci.unmount();\n _debugComponentUnmount(inst);\n };\n}\n\n/**\n * Mount con onMount diferido — dentro de fragments de `html` donde el DOM\n * aún no está insertado: el hook corre cuando el fragment hace commit.\n */\nexport function _mountComponentDeferred(\n inst: ElurComponent,\n parent: Node,\n before: Node | null,\n postMountHooks: Array<() => void>,\n disposes: Array<() => void>,\n): void {\n _debugComponentMountStart(inst);\n const ci = adaptClassComponent(inst);\n try {\n ci.mount(parent, before, {\n deferOnMount: (fire) => postMountHooks.push(fire),\n });\n } finally {\n _debugComponentMountEnd(inst);\n }\n disposes.push(() => {\n ci.unmount();\n _debugComponentUnmount(inst);\n });\n}\n"],"mappings":"oEAoBA,IAAI,EAA2C,KAE/C,SAAgB,EAAmB,EAAgB,CAC/C,GAAI,IAAmB,KAAM,OAAO,GAAI,CACxC,EAAiB,EAAE,CACnB,IAAI,EAAK,GACT,GAAI,CACA,IAAM,EAAI,GAAI,CAEd,MADA,GAAK,GACE,SACD,CACN,IAAM,EAAI,EAEV,GADA,EAAiB,KACb,EAAI,IAAK,IAAM,KAAK,EAAG,GAAG,EAItC,SAAgB,EAAsB,EAAgB,CAClD,IAAM,EAAQ,EACd,EAAiB,EAAE,CACnB,IAAI,EAAK,GACT,GAAI,CACA,IAAM,EAAI,GAAI,CAEd,MADA,GAAK,GACE,SACD,CACN,IAAM,EAAI,EAEV,GADA,EAAiB,EACb,EACA,GAAI,EAAO,EAAM,KAAK,GAAG,EAAE,MACtB,IAAK,IAAM,KAAK,EAAG,GAAG,EAKvC,SAAgB,EAAc,EAAsB,CAC5C,EAAgB,EAAe,KAAK,EAAG,CACtC,GAAI,CAOb,SAAgB,EACZ,EACA,EACA,EACU,CACV,EAAA,0BAA0B,EAAK,CAC/B,IAAM,EAAK,EAAA,oBAAoB,EAAK,CACpC,GAAI,CACA,EAAG,MAAM,EAAQ,EAAQ,CACrB,aAAe,GAAS,EAAc,EAAK,CAC9C,CAAC,QACI,CACN,EAAA,wBAAwB,EAAK,CAEjC,UAAa,CACT,EAAG,SAAS,CACZ,EAAA,uBAAuB,EAAK,EAQpC,SAAgB,EACZ,EACA,EACA,EACU,CACV,EAAA,0BAA0B,EAAK,CAC/B,IAAM,EAAK,EAAA,oBAAoB,EAAK,CAEpC,GAAI,CACA,EAAG,MAAM,EAAQ,EAAQ,CACrB,aAAe,GAAS,EAAc,EAAK,CAC9C,CAAC,MACE,SAEE,CACN,EAAA,wBAAwB,EAAK,CAEjC,UAAa,CACT,EAAG,SAAS,CACZ,EAAA,uBAAuB,EAAK,EAQpC,SAAgB,EACZ,EACA,EACA,EACA,EACU,CACV,EAAA,0BAA0B,EAAK,CAC/B,IAAM,EAAK,EAAA,oBAAoB,EAAK,CACpC,GAAI,CACA,EAAG,MAAM,EAAQ,EAAQ,CACrB,cACA,aAAe,GAAS,EAAc,EAAK,CAC9C,CAAC,QACI,CACN,EAAA,wBAAwB,EAAK,CAEjC,UAAa,CACT,EAAG,SAAS,CACZ,EAAA,uBAAuB,EAAK,EAQpC,SAAgB,EACZ,EACA,EACA,EACA,EACA,EACI,CACJ,EAAA,0BAA0B,EAAK,CAC/B,IAAM,EAAK,EAAA,oBAAoB,EAAK,CACpC,GAAI,CACA,EAAG,MAAM,EAAQ,EAAQ,CACrB,aAAe,GAAS,EAAe,KAAK,EAAK,CACpD,CAAC,QACI,CACN,EAAA,wBAAwB,EAAK,CAEjC,EAAS,SAAW,CAChB,EAAG,SAAS,CACZ,EAAA,uBAAuB,EAAK,EAC9B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ElurComponent } from "../lifecycle.js";
|
|
2
|
+
import { type _captureContextSnapshot } from "../context.js";
|
|
3
|
+
export declare function _postMountScope<T>(fn: () => T): T;
|
|
4
|
+
export declare function _postMountScopeSub<T>(fn: () => T): T;
|
|
5
|
+
export declare function _deferOnMount(fn: () => void): void;
|
|
6
|
+
/**
|
|
7
|
+
* Monta un ElurComponent via kernel: onInit → render → _render → onMount
|
|
8
|
+
* (post-commit). Errores van por onError o re-lanzan. Cleanup = unmount().
|
|
9
|
+
*/
|
|
10
|
+
export declare function _mountComponent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Igual que `_mountComponent` pero traga todos los errores de lifecycle —
|
|
13
|
+
* para contenido de transitions y fallbacks de error boundaries.
|
|
14
|
+
*/
|
|
15
|
+
export declare function _mountComponentSilent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Monta con contexto capturado — para render dinámico/keyed dentro de
|
|
18
|
+
* effects, donde provide/inject hereda del punto de declaración.
|
|
19
|
+
*/
|
|
20
|
+
export declare function _mountComponentWithCtx(inst: ElurComponent, parent: Node, before: Node | null, ctxSnapshot: ReturnType<typeof _captureContextSnapshot>): () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Mount con onMount diferido — dentro de fragments de `html` donde el DOM
|
|
23
|
+
* aún no está insertado: el hook corre cuando el fragment hace commit.
|
|
24
|
+
*/
|
|
25
|
+
export declare function _mountComponentDeferred(inst: ElurComponent, parent: Node, before: Node | null, postMountHooks: Array<() => void>, disposes: Array<() => void>): void;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type ElurComponent } from "../lifecycle.js";
|
|
2
|
+
import { type _captureContextSnapshot } from "../context.js";
|
|
3
|
+
export declare function _postMountScope<T>(fn: () => T): T;
|
|
4
|
+
export declare function _postMountScopeSub<T>(fn: () => T): T;
|
|
5
|
+
export declare function _deferOnMount(fn: () => void): void;
|
|
6
|
+
/**
|
|
7
|
+
* Monta un ElurComponent via kernel: onInit → render → _render → onMount
|
|
8
|
+
* (post-commit). Errores van por onError o re-lanzan. Cleanup = unmount().
|
|
9
|
+
*/
|
|
10
|
+
export declare function _mountComponent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Igual que `_mountComponent` pero traga todos los errores de lifecycle —
|
|
13
|
+
* para contenido de transitions y fallbacks de error boundaries.
|
|
14
|
+
*/
|
|
15
|
+
export declare function _mountComponentSilent(inst: ElurComponent, parent: Node, before: Node | null): () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Monta con contexto capturado — para render dinámico/keyed dentro de
|
|
18
|
+
* effects, donde provide/inject hereda del punto de declaración.
|
|
19
|
+
*/
|
|
20
|
+
export declare function _mountComponentWithCtx(inst: ElurComponent, parent: Node, before: Node | null, ctxSnapshot: ReturnType<typeof _captureContextSnapshot>): () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Mount con onMount diferido — dentro de fragments de `html` donde el DOM
|
|
23
|
+
* aún no está insertado: el hook corre cuando el fragment hace commit.
|
|
24
|
+
*/
|
|
25
|
+
export declare function _mountComponentDeferred(inst: ElurComponent, parent: Node, before: Node | null, postMountHooks: Array<() => void>, disposes: Array<() => void>): void;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { _debugComponentMountEnd as e, _debugComponentMountStart as t, _debugComponentUnmount as n } from "../../lifecycle.js";
|
|
2
|
+
import { adaptClassComponent as r } from "./component.js";
|
|
3
|
+
//#region src/elur/next-2/mount-helpers.ts
|
|
4
|
+
var i = null;
|
|
5
|
+
function a(e) {
|
|
6
|
+
if (i !== null) return e();
|
|
7
|
+
i = [];
|
|
8
|
+
let t = !1;
|
|
9
|
+
try {
|
|
10
|
+
let n = e();
|
|
11
|
+
return t = !0, n;
|
|
12
|
+
} finally {
|
|
13
|
+
let e = i;
|
|
14
|
+
if (i = null, t) for (let t of e) t();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function o(e) {
|
|
18
|
+
let t = i;
|
|
19
|
+
i = [];
|
|
20
|
+
let n = !1;
|
|
21
|
+
try {
|
|
22
|
+
let t = e();
|
|
23
|
+
return n = !0, t;
|
|
24
|
+
} finally {
|
|
25
|
+
let e = i;
|
|
26
|
+
if (i = t, n) if (t) t.push(...e);
|
|
27
|
+
else for (let t of e) t();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function s(e) {
|
|
31
|
+
i ? i.push(e) : e();
|
|
32
|
+
}
|
|
33
|
+
function c(i, a, o) {
|
|
34
|
+
t(i);
|
|
35
|
+
let c = r(i);
|
|
36
|
+
try {
|
|
37
|
+
c.mount(a, o, { deferOnMount: (e) => s(e) });
|
|
38
|
+
} finally {
|
|
39
|
+
e(i);
|
|
40
|
+
}
|
|
41
|
+
return () => {
|
|
42
|
+
c.unmount(), n(i);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function l(i, a, o) {
|
|
46
|
+
t(i);
|
|
47
|
+
let c = r(i);
|
|
48
|
+
try {
|
|
49
|
+
c.mount(a, o, { deferOnMount: (e) => s(e) });
|
|
50
|
+
} catch {} finally {
|
|
51
|
+
e(i);
|
|
52
|
+
}
|
|
53
|
+
return () => {
|
|
54
|
+
c.unmount(), n(i);
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function u(i, a, o, c) {
|
|
58
|
+
t(i);
|
|
59
|
+
let l = r(i);
|
|
60
|
+
try {
|
|
61
|
+
l.mount(a, o, {
|
|
62
|
+
ctxSnapshot: c,
|
|
63
|
+
deferOnMount: (e) => s(e)
|
|
64
|
+
});
|
|
65
|
+
} finally {
|
|
66
|
+
e(i);
|
|
67
|
+
}
|
|
68
|
+
return () => {
|
|
69
|
+
l.unmount(), n(i);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function d(i, a, o, s, c) {
|
|
73
|
+
t(i);
|
|
74
|
+
let l = r(i);
|
|
75
|
+
try {
|
|
76
|
+
l.mount(a, o, { deferOnMount: (e) => s.push(e) });
|
|
77
|
+
} finally {
|
|
78
|
+
e(i);
|
|
79
|
+
}
|
|
80
|
+
c.push(() => {
|
|
81
|
+
l.unmount(), n(i);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//#endregion
|
|
85
|
+
export { s as _deferOnMount, c as _mountComponent, d as _mountComponentDeferred, l as _mountComponentSilent, u as _mountComponentWithCtx, a as _postMountScope, o as _postMountScopeSub };
|
|
86
|
+
|
|
87
|
+
//# sourceMappingURL=mount-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount-helpers.js","names":[],"sources":["../../../../src/elur/next-2/mount-helpers.ts"],"sourcesContent":["import {\n _debugComponentMountStart,\n _debugComponentMountEnd,\n _debugComponentUnmount,\n type ElurComponent,\n} from \"../lifecycle.js\";\nimport { type _captureContextSnapshot } from \"../context.js\";\nimport { adaptClassComponent } from \"./component.js\";\n\n// =============================================================================\n// --- next/ — component mounting sobre el kernel unificado (A.6–A.9) ---\n// Fork de ../template/mount-helpers.ts: misma superficie, pero cada mount pasa\n// por ComponentInstance — owner propio, máquina de estados, mount transaccional\n// con rollback, onMount post-commit, unmount idempotente.\n// =============================================================================\n\n// --- Post-commit onMount queue (misma superficie que el estable) -------------\n// El kernel ya difiere onMount por instancia via `deferOnMount`; esta cola\n// cubre los callers que NO pasan por el kernel (p.ej. error-boundary llama\n// `content.onMount` directamente sobre ElurComponent).\nlet pendingOnMount: Array<() => void> | null = null;\n\nexport function _postMountScope<T>(fn: () => T): T {\n if (pendingOnMount !== null) return fn();\n pendingOnMount = [];\n let ok = false;\n try {\n const r = fn();\n ok = true;\n return r;\n } finally {\n const q = pendingOnMount;\n pendingOnMount = null;\n if (ok) for (const h of q) h();\n }\n}\n\nexport function _postMountScopeSub<T>(fn: () => T): T {\n const outer = pendingOnMount;\n pendingOnMount = [];\n let ok = false;\n try {\n const r = fn();\n ok = true;\n return r;\n } finally {\n const q = pendingOnMount!;\n pendingOnMount = outer;\n if (ok) {\n if (outer) outer.push(...q);\n else for (const h of q) h();\n }\n }\n}\n\nexport function _deferOnMount(fn: () => void): void {\n if (pendingOnMount) pendingOnMount.push(fn);\n else fn();\n}\n\n/**\n * Monta un ElurComponent via kernel: onInit → render → _render → onMount\n * (post-commit). Errores van por onError o re-lanzan. Cleanup = unmount().\n */\nexport function _mountComponent(\n inst: ElurComponent,\n parent: Node,\n before: Node | null,\n): () => void {\n _debugComponentMountStart(inst);\n const ci = adaptClassComponent(inst);\n try {\n ci.mount(parent, before, {\n deferOnMount: (fire) => _deferOnMount(fire),\n });\n } finally {\n _debugComponentMountEnd(inst);\n }\n return () => {\n ci.unmount();\n _debugComponentUnmount(inst);\n };\n}\n\n/**\n * Igual que `_mountComponent` pero traga todos los errores de lifecycle —\n * para contenido de transitions y fallbacks de error boundaries.\n */\nexport function _mountComponentSilent(\n inst: ElurComponent,\n parent: Node,\n before: Node | null,\n): () => void {\n _debugComponentMountStart(inst);\n const ci = adaptClassComponent(inst);\n // Errores silenciados: onError ausente → el kernel re-lanza → se traga aquí.\n try {\n ci.mount(parent, before, {\n deferOnMount: (fire) => _deferOnMount(fire),\n });\n } catch {\n /* silent */\n } finally {\n _debugComponentMountEnd(inst);\n }\n return () => {\n ci.unmount();\n _debugComponentUnmount(inst);\n };\n}\n\n/**\n * Monta con contexto capturado — para render dinámico/keyed dentro de\n * effects, donde provide/inject hereda del punto de declaración.\n */\nexport function _mountComponentWithCtx(\n inst: ElurComponent,\n parent: Node,\n before: Node | null,\n ctxSnapshot: ReturnType<typeof _captureContextSnapshot>,\n): () => void {\n _debugComponentMountStart(inst);\n const ci = adaptClassComponent(inst);\n try {\n ci.mount(parent, before, {\n ctxSnapshot,\n deferOnMount: (fire) => _deferOnMount(fire),\n });\n } finally {\n _debugComponentMountEnd(inst);\n }\n return () => {\n ci.unmount();\n _debugComponentUnmount(inst);\n };\n}\n\n/**\n * Mount con onMount diferido — dentro de fragments de `html` donde el DOM\n * aún no está insertado: el hook corre cuando el fragment hace commit.\n */\nexport function _mountComponentDeferred(\n inst: ElurComponent,\n parent: Node,\n before: Node | null,\n postMountHooks: Array<() => void>,\n disposes: Array<() => void>,\n): void {\n _debugComponentMountStart(inst);\n const ci = adaptClassComponent(inst);\n try {\n ci.mount(parent, before, {\n deferOnMount: (fire) => postMountHooks.push(fire),\n });\n } finally {\n _debugComponentMountEnd(inst);\n }\n disposes.push(() => {\n ci.unmount();\n _debugComponentUnmount(inst);\n });\n}\n"],"mappings":";;;AAoBA,IAAI,IAA2C;AAE/C,SAAgB,EAAmB,GAAgB;AAC/C,KAAI,MAAmB,KAAM,QAAO,GAAI;AACxC,KAAiB,EAAE;CACnB,IAAI,IAAK;AACT,KAAI;EACA,IAAM,IAAI,GAAI;AAEd,SADA,IAAK,IACE;WACD;EACN,IAAM,IAAI;AAEV,MADA,IAAiB,MACb,EAAI,MAAK,IAAM,KAAK,EAAG,IAAG;;;AAItC,SAAgB,EAAsB,GAAgB;CAClD,IAAM,IAAQ;AACd,KAAiB,EAAE;CACnB,IAAI,IAAK;AACT,KAAI;EACA,IAAM,IAAI,GAAI;AAEd,SADA,IAAK,IACE;WACD;EACN,IAAM,IAAI;AAEV,MADA,IAAiB,GACb,EACA,KAAI,EAAO,GAAM,KAAK,GAAG,EAAE;MACtB,MAAK,IAAM,KAAK,EAAG,IAAG;;;AAKvC,SAAgB,EAAc,GAAsB;AAChD,CAAI,IAAgB,EAAe,KAAK,EAAG,GACtC,GAAI;;AAOb,SAAgB,EACZ,GACA,GACA,GACU;AACV,GAA0B,EAAK;CAC/B,IAAM,IAAK,EAAoB,EAAK;AACpC,KAAI;AACA,IAAG,MAAM,GAAQ,GAAQ,EACrB,eAAe,MAAS,EAAc,EAAK,EAC9C,CAAC;WACI;AACN,IAAwB,EAAK;;AAEjC,cAAa;AAET,EADA,EAAG,SAAS,EACZ,EAAuB,EAAK;;;AAQpC,SAAgB,EACZ,GACA,GACA,GACU;AACV,GAA0B,EAAK;CAC/B,IAAM,IAAK,EAAoB,EAAK;AAEpC,KAAI;AACA,IAAG,MAAM,GAAQ,GAAQ,EACrB,eAAe,MAAS,EAAc,EAAK,EAC9C,CAAC;SACE,WAEE;AACN,IAAwB,EAAK;;AAEjC,cAAa;AAET,EADA,EAAG,SAAS,EACZ,EAAuB,EAAK;;;AAQpC,SAAgB,EACZ,GACA,GACA,GACA,GACU;AACV,GAA0B,EAAK;CAC/B,IAAM,IAAK,EAAoB,EAAK;AACpC,KAAI;AACA,IAAG,MAAM,GAAQ,GAAQ;GACrB;GACA,eAAe,MAAS,EAAc,EAAK;GAC9C,CAAC;WACI;AACN,IAAwB,EAAK;;AAEjC,cAAa;AAET,EADA,EAAG,SAAS,EACZ,EAAuB,EAAK;;;AAQpC,SAAgB,EACZ,GACA,GACA,GACA,GACA,GACI;AACJ,GAA0B,EAAK;CAC/B,IAAM,IAAK,EAAoB,EAAK;AACpC,KAAI;AACA,IAAG,MAAM,GAAQ,GAAQ,EACrB,eAAe,MAAS,EAAe,KAAK,EAAK,EACpD,CAAC;WACI;AACN,IAAwB,EAAK;;AAEjC,GAAS,WAAW;AAEhB,EADA,EAAG,SAAS,EACZ,EAAuB,EAAK;GAC9B"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`./reactivity.cjs`),t=require(`../../lifecycle.cjs`),n=require(`./component.cjs`),r=require(`../router-registry.cjs`);function i(e){let t=typeof e==`string`?document.querySelector(e):e;if(!t)throw Error(`[elur] mount: container not found: ${e}`);return t}function a(a,o,s){if(t.isElurComponent(a)||n.isComponentInvocation(a)){let e=i(o),c=new n.ComponentInstance(a);t._debugComponentMountStart(a);try{c.mount(e,null,{provides:s?.router?[[r.RouterKey,s.router]]:void 0})}finally{t._debugComponentMountEnd(a)}return s?.router&&r._debugRegisterRouter(s.router),{unmount(){c.unmount(),s?.router&&r._debugUnregisterRouter(s.router),t._debugComponentUnmount(a)}}}let c=i(o),l=new e.Owner;l.parent=e.getOwner(),s?.router&&(n._registerContextOwner(l,new Map([[r.RouterKey,s.router]])),r._debugRegisterRouter(s.router));let u=e.runWithOwner(l,()=>a._render(c,null));return{unmount(){l.dispose(),u(),s?.router&&r._debugUnregisterRouter(s.router)}}}exports.mount=a;
|
|
2
|
+
//# sourceMappingURL=mount.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mount.cjs","names":[],"sources":["../../../../src/elur/next-2/mount.ts"],"sourcesContent":["/**\n * next/ — fork del mount() público (../component.ts) sobre el kernel.\n *\n * Diferencias vs el estable:\n * - Componentes (clase o invocación funcional) montan via ComponentInstance:\n * máquina de estados, owner propio, mount transaccional, onMount\n * post-commit, unmount idempotente.\n * - `options.router` se inyecta via `provides` en el frame de contexto de la\n * instancia (A.12) en vez de un stack global.\n * - Templates raíz montan bajo un Owner raíz — así los componentes internos\n * tienen cadena de owners y provide/inject resuelve por instancias.\n */\nimport type { ElurTemplate, ElurMountHandle } from \"../template/index.js\";\nimport {\n isElurComponent,\n _debugComponentMountStart,\n _debugComponentMountEnd,\n _debugComponentUnmount,\n type ElurComponent,\n} from \"../lifecycle.js\";\nimport { RouterKey, _debugRegisterRouter, _debugUnregisterRouter } from \"../router-registry.js\";\nimport type { Router } from \"../router.js\";\nimport { Owner, getOwner, runWithOwner } from \"./reactivity.js\";\nimport {\n ComponentInstance,\n isComponentInvocation,\n _registerContextOwner,\n type ComponentInvocation,\n} from \"./component.js\";\n\nexport interface MountOptions {\n router?: Router;\n}\n\nfunction _resolveContainer(container: Element | string): Element {\n const el =\n typeof container === \"string\"\n ? (document.querySelector(container) as Element)\n : container;\n if (!el) {\n throw new Error(`[elur] mount: container not found: ${container}`);\n }\n return el;\n}\n\n/**\n * Mounts a ElurTemplate, ElurComponent o ComponentInvocation en el DOM.\n *\n * mount(Counter({ initial: 10 }), \"#app\"); // componente funcional\n * mount(new Timer(), \"#app\"); // clase con lifecycle\n * mount(html`…`, \"#app\"); // template\n *\n * @returns { unmount() } — mata el árbol reactivo completo y remueve el DOM.\n */\nexport function mount(\n component: ElurTemplate | ElurComponent | ComponentInvocation<any>,\n container: Element | string,\n options?: MountOptions,\n): ElurMountHandle {\n if (isElurComponent(component) || isComponentInvocation(component)) {\n const el = _resolveContainer(container);\n const inst = new ComponentInstance(component);\n\n _debugComponentMountStart(component as ElurComponent);\n try {\n inst.mount(el, null, {\n provides: options?.router\n ? [[RouterKey, options.router] as const]\n : undefined,\n });\n } finally {\n _debugComponentMountEnd(component as ElurComponent);\n }\n if (options?.router) _debugRegisterRouter(options.router);\n\n return {\n unmount() {\n inst.unmount();\n if (options?.router) _debugUnregisterRouter(options.router);\n _debugComponentUnmount(component as ElurComponent);\n },\n };\n }\n\n const el = _resolveContainer(container);\n // Owner raíz para el template: ancla la cadena de owners (los componentes\n // internos resuelven parent/contexto por ella) y puede portar el frame\n // de contexto del router.\n const root = new Owner();\n root.parent = getOwner();\n if (options?.router) {\n _registerContextOwner(root, new Map([[RouterKey, options.router]]));\n _debugRegisterRouter(options.router);\n }\n const cleanup = runWithOwner(root, () =>\n (component as ElurTemplate)._render(el, null),\n );\n return {\n unmount() {\n root.dispose();\n cleanup();\n if (options?.router) _debugUnregisterRouter(options.router);\n },\n };\n}\n"],"mappings":"sIAkCA,SAAS,EAAkB,EAAsC,CAC7D,IAAM,EACF,OAAO,GAAc,SACd,SAAS,cAAc,EAAU,CAClC,EACV,GAAI,CAAC,EACD,MAAU,MAAM,sCAAsC,IAAY,CAEtE,OAAO,EAYX,SAAgB,EACZ,EACA,EACA,EACe,CACf,GAAI,EAAA,gBAAgB,EAAU,EAAI,EAAA,sBAAsB,EAAU,CAAE,CAChE,IAAM,EAAK,EAAkB,EAAU,CACjC,EAAO,IAAI,EAAA,kBAAkB,EAAU,CAE7C,EAAA,0BAA0B,EAA2B,CACrD,GAAI,CACA,EAAK,MAAM,EAAI,KAAM,CACjB,SAAU,GAAS,OACb,CAAC,CAAC,EAAA,UAAW,EAAQ,OAAO,CAAU,CACtC,IAAA,GACT,CAAC,QACI,CACN,EAAA,wBAAwB,EAA2B,CAIvD,OAFI,GAAS,QAAQ,EAAA,qBAAqB,EAAQ,OAAO,CAElD,CACH,SAAU,CACN,EAAK,SAAS,CACV,GAAS,QAAQ,EAAA,uBAAuB,EAAQ,OAAO,CAC3D,EAAA,uBAAuB,EAA2B,EAEzD,CAGL,IAAM,EAAK,EAAkB,EAAU,CAIjC,EAAO,IAAI,EAAA,MACjB,EAAK,OAAS,EAAA,UAAU,CACpB,GAAS,SACT,EAAA,sBAAsB,EAAM,IAAI,IAAI,CAAC,CAAC,EAAA,UAAW,EAAQ,OAAO,CAAC,CAAC,CAAC,CACnE,EAAA,qBAAqB,EAAQ,OAAO,EAExC,IAAM,EAAU,EAAA,aAAa,MACxB,EAA2B,QAAQ,EAAI,KAAK,CAChD,CACD,MAAO,CACH,SAAU,CACN,EAAK,SAAS,CACd,GAAS,CACL,GAAS,QAAQ,EAAA,uBAAuB,EAAQ,OAAO,EAElE"}
|