@meekojs/meeko 0.0.3 → 0.1.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/README.md +35 -16
- package/dist/autoimports-ts.d.ts +26 -0
- package/dist/autoimports-ts.js +183 -0
- package/dist/autoimports-ts.js.map +1 -0
- package/dist/autoimports.d.ts +21 -0
- package/dist/autoimports.js +301 -0
- package/dist/autoimports.js.map +1 -0
- package/dist/check.js +74 -33
- package/dist/check.js.map +1 -0
- package/dist/cli.js +67 -5
- package/dist/cli.js.map +1 -0
- package/dist/compiler/events.d.ts +2 -0
- package/dist/compiler/events.js +6 -0
- package/dist/compiler/events.js.map +1 -0
- package/dist/compiler/import-graph.d.ts +8 -0
- package/dist/compiler/import-graph.js +33 -0
- package/dist/compiler/import-graph.js.map +1 -0
- package/dist/compiler/mapping.js +1 -0
- package/dist/compiler/mapping.js.map +1 -0
- package/dist/compiler/project-root.d.ts +2 -0
- package/dist/compiler/project-root.js +18 -0
- package/dist/compiler/project-root.js.map +1 -0
- package/dist/compiler/props.d.ts +12 -0
- package/dist/compiler/props.js +32 -0
- package/dist/compiler/props.js.map +1 -0
- package/dist/compiler/sfc.js +1 -0
- package/dist/compiler/sfc.js.map +1 -0
- package/dist/compiler/sourcemap.d.ts +3 -0
- package/dist/compiler/sourcemap.js +75 -0
- package/dist/compiler/sourcemap.js.map +1 -0
- package/dist/compiler/template.js +1 -0
- package/dist/compiler/template.js.map +1 -0
- package/dist/compiler.js +66 -17
- package/dist/compiler.js.map +1 -0
- package/dist/component-errors.d.ts +18 -0
- package/dist/component-errors.js +65 -0
- package/dist/component-errors.js.map +1 -0
- package/dist/devtools-ui/index.js +1 -0
- package/dist/devtools-ui/index.js.map +1 -0
- package/dist/devtools.js +3 -4
- package/dist/devtools.js.map +1 -0
- package/dist/dom.d.ts +18 -5
- package/dist/dom.js +295 -90
- package/dist/dom.js.map +1 -0
- package/dist/error-observer.d.ts +6 -0
- package/dist/error-observer.js +41 -0
- package/dist/error-observer.js.map +1 -0
- package/dist/framework/check-app.d.ts +5 -0
- package/dist/framework/check-app.js +214 -0
- package/dist/framework/check-app.js.map +1 -0
- package/dist/framework/check-project.d.ts +4 -0
- package/dist/framework/check-project.js +42 -0
- package/dist/framework/check-project.js.map +1 -0
- package/dist/framework/client.d.ts +48 -0
- package/dist/framework/client.js +249 -0
- package/dist/framework/client.js.map +1 -0
- package/dist/framework/clients.d.ts +82 -0
- package/dist/framework/clients.js +190 -0
- package/dist/framework/clients.js.map +1 -0
- package/dist/framework/config-type.d.ts +10 -0
- package/dist/framework/config-type.js +4 -0
- package/dist/framework/config-type.js.map +1 -0
- package/dist/framework/config.d.ts +15 -0
- package/dist/framework/config.js +138 -0
- package/dist/framework/config.js.map +1 -0
- package/dist/framework/contracts-generate.d.ts +8 -0
- package/dist/framework/contracts-generate.js +290 -0
- package/dist/framework/contracts-generate.js.map +1 -0
- package/dist/framework/generate.d.ts +7 -0
- package/dist/framework/generate.js +67 -0
- package/dist/framework/generate.js.map +1 -0
- package/dist/framework/init.d.ts +2 -0
- package/dist/framework/init.js +183 -0
- package/dist/framework/init.js.map +1 -0
- package/dist/framework/middleware.d.ts +14 -0
- package/dist/framework/middleware.js +16 -0
- package/dist/framework/middleware.js.map +1 -0
- package/dist/framework/modules.d.ts +22 -0
- package/dist/framework/modules.js +29 -0
- package/dist/framework/modules.js.map +1 -0
- package/dist/framework/page-contracts-check.d.ts +8 -0
- package/dist/framework/page-contracts-check.js +110 -0
- package/dist/framework/page-contracts-check.js.map +1 -0
- package/dist/framework/page-contracts-generate.d.ts +2 -0
- package/dist/framework/page-contracts-generate.js +94 -0
- package/dist/framework/page-contracts-generate.js.map +1 -0
- package/dist/framework/page.d.ts +64 -0
- package/dist/framework/page.js +44 -0
- package/dist/framework/page.js.map +1 -0
- package/dist/framework/prerender.d.ts +14 -0
- package/dist/framework/prerender.js +110 -0
- package/dist/framework/prerender.js.map +1 -0
- package/dist/framework/project-templates.d.ts +3 -0
- package/dist/framework/project-templates.js +119 -0
- package/dist/framework/project-templates.js.map +1 -0
- package/dist/framework/project.d.ts +9 -0
- package/dist/framework/project.js +272 -0
- package/dist/framework/project.js.map +1 -0
- package/dist/framework/router.d.ts +41 -0
- package/dist/framework/router.js +259 -0
- package/dist/framework/router.js.map +1 -0
- package/dist/framework/server.d.ts +65 -0
- package/dist/framework/server.js +239 -0
- package/dist/framework/server.js.map +1 -0
- package/dist/framework/socket-contracts-generate.d.ts +5 -0
- package/dist/framework/socket-contracts-generate.js +162 -0
- package/dist/framework/socket-contracts-generate.js.map +1 -0
- package/dist/framework/socket.d.ts +72 -0
- package/dist/framework/socket.js +252 -0
- package/dist/framework/socket.js.map +1 -0
- package/dist/framework/standard-schema-types.d.ts +7 -0
- package/dist/framework/standard-schema-types.js +69 -0
- package/dist/framework/standard-schema-types.js.map +1 -0
- package/dist/framework/state.d.ts +22 -0
- package/dist/framework/state.js +136 -0
- package/dist/framework/state.js.map +1 -0
- package/dist/framework/styles.d.ts +2 -0
- package/dist/framework/styles.js +6 -0
- package/dist/framework/styles.js.map +1 -0
- package/dist/framework/type-declarations.d.ts +5 -0
- package/dist/framework/type-declarations.js +84 -0
- package/dist/framework/type-declarations.js.map +1 -0
- package/dist/framework-server/auto-clients.d.ts +3 -0
- package/dist/framework-server/auto-clients.js +27 -0
- package/dist/framework-server/auto-clients.js.map +1 -0
- package/dist/framework-server/context.d.ts +21 -0
- package/dist/framework-server/context.js +22 -0
- package/dist/framework-server/context.js.map +1 -0
- package/dist/framework-server/contracts.d.ts +73 -0
- package/dist/framework-server/contracts.js +184 -0
- package/dist/framework-server/contracts.js.map +1 -0
- package/dist/framework-server/discovery.d.ts +43 -0
- package/dist/framework-server/discovery.js +257 -0
- package/dist/framework-server/discovery.js.map +1 -0
- package/dist/framework-server/local.d.ts +21 -0
- package/dist/framework-server/local.js +100 -0
- package/dist/framework-server/local.js.map +1 -0
- package/dist/framework-server/middleware.d.ts +4 -0
- package/dist/framework-server/middleware.js +56 -0
- package/dist/framework-server/middleware.js.map +1 -0
- package/dist/framework-server/node-upgrade.d.ts +23 -0
- package/dist/framework-server/node-upgrade.js +96 -0
- package/dist/framework-server/node-upgrade.js.map +1 -0
- package/dist/framework-server/node-websocket.d.ts +16 -0
- package/dist/framework-server/node-websocket.js +127 -0
- package/dist/framework-server/node-websocket.js.map +1 -0
- package/dist/framework-server/openapi.d.ts +17 -0
- package/dist/framework-server/openapi.js +118 -0
- package/dist/framework-server/openapi.js.map +1 -0
- package/dist/framework-server/session-stores.d.ts +73 -0
- package/dist/framework-server/session-stores.js +122 -0
- package/dist/framework-server/session-stores.js.map +1 -0
- package/dist/framework-server/sessions.d.ts +70 -0
- package/dist/framework-server/sessions.js +167 -0
- package/dist/framework-server/sessions.js.map +1 -0
- package/dist/framework-server/socket.d.ts +83 -0
- package/dist/framework-server/socket.js +196 -0
- package/dist/framework-server/socket.js.map +1 -0
- package/dist/framework-server.d.ts +23 -0
- package/dist/framework-server.js +13 -0
- package/dist/framework-server.js.map +1 -0
- package/dist/framework.d.ts +31 -0
- package/dist/framework.js +14 -0
- package/dist/framework.js.map +1 -0
- package/dist/hmr.js +75 -24
- package/dist/hmr.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -0
- package/dist/init.js +31 -3
- package/dist/init.js.map +1 -0
- package/dist/internal.d.ts +2 -2
- package/dist/internal.js +3 -2
- package/dist/internal.js.map +1 -0
- package/dist/node.d.ts +16 -0
- package/dist/node.js +122 -0
- package/dist/node.js.map +1 -0
- package/dist/reactivity.d.ts +22 -1
- package/dist/reactivity.js +132 -18
- package/dist/reactivity.js.map +1 -0
- package/dist/server.js +1 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +26 -9
- package/dist/types.js.map +1 -0
- package/dist/vite.js +112 -7
- package/dist/vite.js.map +1 -0
- package/package.json +15 -4
package/dist/dom.d.ts
CHANGED
|
@@ -7,24 +7,37 @@ export interface DomScope {
|
|
|
7
7
|
}
|
|
8
8
|
/** Contrato de un módulo de componente compilado para composición sin wrapper. */
|
|
9
9
|
export interface ComponentModule<Props extends object> {
|
|
10
|
-
renderToString(props: Props, state?: Record<string, unknown>)
|
|
11
|
-
renderWithState
|
|
10
|
+
readonly renderToString: (props: Props, state?: Record<string, unknown>) => string;
|
|
11
|
+
readonly renderWithState?: (props: Props) => {
|
|
12
12
|
html: string;
|
|
13
13
|
state: Record<string, unknown>;
|
|
14
14
|
};
|
|
15
|
-
hydrateScope(scope: DomScope, props: Props, state?: Record<string, unknown>)
|
|
15
|
+
readonly hydrateScope: (scope: DomScope, props: Props, state?: Record<string, unknown>) => ComponentRelease;
|
|
16
16
|
}
|
|
17
|
+
/** Componente compilado que puede transferir su estado durante SSR. */
|
|
18
|
+
export type Component<Props extends object> = ComponentModule<Props> & {
|
|
19
|
+
readonly renderWithState: (props: Props) => {
|
|
20
|
+
html: string;
|
|
21
|
+
state: Record<string, unknown>;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
17
24
|
/** Función de limpieza que puede exponer el estado editable de su instancia. */
|
|
18
25
|
export interface ComponentRelease {
|
|
19
26
|
(): void;
|
|
20
27
|
snapshot?: () => Record<string, unknown>;
|
|
21
28
|
}
|
|
29
|
+
/** Releases every compiled binding and preserves the failure that triggered cleanup. */
|
|
30
|
+
export declare function releaseAll(cleanups: Array<() => void>, cause: {
|
|
31
|
+
error: unknown;
|
|
32
|
+
}): never;
|
|
33
|
+
export declare function releaseAll(cleanups: Array<() => void>): void;
|
|
22
34
|
/** Añade una lectura de estado a la limpieza de un componente compilado. */
|
|
23
35
|
export declare function withStateSnapshot(release: () => void, snapshot: () => Record<string, unknown>): ComponentRelease;
|
|
24
36
|
/** Renderiza un hijo entre comentarios de ámbito sin añadir un elemento visual. */
|
|
25
|
-
export declare function renderComponent<Props extends object>(id: number, component:
|
|
37
|
+
export declare function renderComponent<Props extends object>(id: number, component: Component<Props>, props: Props, transferState: boolean): string;
|
|
38
|
+
export declare function renderComponent<Props extends object>(id: number, component: ComponentModule<Props>, props: Props, transferState?: false): string;
|
|
26
39
|
/** Hidrata un hijo dentro de su rango y actualiza props reactivas con limpieza previa. */
|
|
27
|
-
export declare function bindComponent<Props extends object>(scope: DomScope, id: number,
|
|
40
|
+
export declare function bindComponent<Props extends object>(scope: DomScope, id: number, input: ComponentModule<Props> | (() => ComponentModule<Props>), read: () => Props, location: string): () => void;
|
|
28
41
|
/** Conecta un texto reactivo al marcador SSR y comprueba su valor inicial. */
|
|
29
42
|
export declare function bindText(scope: DomScope, id: number, read: () => unknown, location: string, source?: EffectSource): () => void;
|
|
30
43
|
/** Conecta un atributo dinámico al elemento SSR y comprueba su valor inicial. */
|
package/dist/dom.js
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
|
-
import { createRoot, effect, signal } from "./reactivity.js";
|
|
1
|
+
import { batch, createRoot, effect, finishWithCleanup, signal } from "./reactivity.js";
|
|
2
|
+
import { observeCallback } from "./error-observer.js";
|
|
3
|
+
import { componentErrorReporter } from "./component-errors.js";
|
|
2
4
|
import { attributeValue, serializeJson } from "./server.js";
|
|
5
|
+
export function releaseAll(cleanups, cause) {
|
|
6
|
+
const failures = cause ? [cause.error] : [];
|
|
7
|
+
while (cleanups.length) {
|
|
8
|
+
try {
|
|
9
|
+
cleanups.pop()();
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
failures.push(error);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
if (failures.length > 1)
|
|
16
|
+
throw new AggregateError(failures, "Meeko hydration cleanup failed");
|
|
17
|
+
if (failures.length === 1)
|
|
18
|
+
throw failures[0];
|
|
19
|
+
}
|
|
3
20
|
/** Añade una lectura de estado a la limpieza de un componente compilado. */
|
|
4
21
|
export function withStateSnapshot(release, snapshot) {
|
|
5
22
|
return Object.assign(release, { snapshot });
|
|
@@ -67,6 +84,18 @@ function clearRegion(scope) {
|
|
|
67
84
|
node = next;
|
|
68
85
|
}
|
|
69
86
|
}
|
|
87
|
+
function cloneRegion(scope) {
|
|
88
|
+
if (!scope.start || !scope.end)
|
|
89
|
+
throw new Error("Expected a bounded Meeko region");
|
|
90
|
+
const range = scope.start.ownerDocument.createRange();
|
|
91
|
+
range.setStartAfter(scope.start);
|
|
92
|
+
range.setEndBefore(scope.end);
|
|
93
|
+
return range.cloneContents();
|
|
94
|
+
}
|
|
95
|
+
function restoreRegion(scope, content) {
|
|
96
|
+
clearRegion(scope);
|
|
97
|
+
scope.end.parentNode.insertBefore(content, scope.end);
|
|
98
|
+
}
|
|
70
99
|
function insertHtml(end, html) {
|
|
71
100
|
const parent = end.parentNode;
|
|
72
101
|
if (!parent)
|
|
@@ -80,7 +109,6 @@ function sameProps(first, second) {
|
|
|
80
109
|
const secondKeys = Object.keys(second);
|
|
81
110
|
return firstKeys.length === secondKeys.length && firstKeys.every((key) => Object.hasOwn(second, key) && Object.is(first[key], second[key]));
|
|
82
111
|
}
|
|
83
|
-
/** Renderiza un hijo entre comentarios de ámbito sin añadir un elemento visual. */
|
|
84
112
|
export function renderComponent(id, component, props, transferState = false) {
|
|
85
113
|
if (transferState) {
|
|
86
114
|
if (!component.renderWithState)
|
|
@@ -107,7 +135,7 @@ function componentRegion(scope, id) {
|
|
|
107
135
|
return { inner: { root: scope.root, start, end }, state: parsed };
|
|
108
136
|
}
|
|
109
137
|
/** Hidrata un hijo dentro de su rango y actualiza props reactivas con limpieza previa. */
|
|
110
|
-
export function bindComponent(scope, id,
|
|
138
|
+
export function bindComponent(scope, id, input, read, location) {
|
|
111
139
|
let inner;
|
|
112
140
|
let state;
|
|
113
141
|
try {
|
|
@@ -116,29 +144,57 @@ export function bindComponent(scope, id, component, read, location) {
|
|
|
116
144
|
catch (error) {
|
|
117
145
|
throw new Error(`Hydration mismatch in ${location}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
118
146
|
}
|
|
147
|
+
const resolveComponent = () => typeof input === "function" ? input() : input;
|
|
148
|
+
let component = resolveComponent();
|
|
119
149
|
let props = read();
|
|
120
150
|
let release = component.hydrateScope(inner, props, state);
|
|
121
|
-
|
|
151
|
+
let stop = () => { };
|
|
152
|
+
stop = effect(() => {
|
|
153
|
+
const nextComponent = resolveComponent();
|
|
122
154
|
const next = read();
|
|
123
|
-
if (sameProps(props, next))
|
|
155
|
+
if (nextComponent === component && sameProps(props, next))
|
|
124
156
|
return;
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
157
|
+
const previousState = release.snapshot?.();
|
|
158
|
+
const state = nextComponent === component ? previousState : undefined;
|
|
159
|
+
const html = nextComponent.renderToString(next, state);
|
|
160
|
+
const previous = cloneRegion(inner);
|
|
161
|
+
try {
|
|
162
|
+
release();
|
|
163
|
+
clearRegion(inner);
|
|
164
|
+
insertHtml(inner.end, html);
|
|
165
|
+
const nextRelease = nextComponent.hydrateScope(inner, next, state);
|
|
166
|
+
release = nextRelease;
|
|
167
|
+
component = nextComponent;
|
|
168
|
+
props = next;
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
try {
|
|
172
|
+
restoreRegion(inner, previous);
|
|
173
|
+
release = component.hydrateScope(inner, props, previousState);
|
|
174
|
+
}
|
|
175
|
+
catch (rollbackError) {
|
|
176
|
+
release = () => { };
|
|
177
|
+
stop();
|
|
178
|
+
throw new AggregateError([error, rollbackError], `Meeko component update and recovery failed in ${location}`);
|
|
179
|
+
}
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
132
182
|
});
|
|
133
183
|
return () => { stop(); release(); };
|
|
134
184
|
}
|
|
135
185
|
/** Conecta un texto reactivo al marcador SSR y comprueba su valor inicial. */
|
|
136
186
|
export function bindText(scope, id, read, location, source) {
|
|
137
187
|
const marker = findComment(scope, `meeko:text:${id}`);
|
|
138
|
-
const
|
|
188
|
+
const initial = String(read());
|
|
189
|
+
let text = marker.nextSibling;
|
|
190
|
+
// HTML parsing drops empty text nodes. Restore only that empty SSR case so
|
|
191
|
+
// adjacent static text stays untouched and the reactive expression can bind.
|
|
192
|
+
if (initial === "" && (!text || text.nodeType !== 3 || text.textContent !== "")) {
|
|
193
|
+
text = marker.ownerDocument.createTextNode("");
|
|
194
|
+
marker.parentNode.insertBefore(text, marker.nextSibling);
|
|
195
|
+
}
|
|
139
196
|
if (!text || text.nodeType !== 3)
|
|
140
197
|
throw new Error(`Missing text node in ${location}`);
|
|
141
|
-
const initial = String(read());
|
|
142
198
|
if (text.textContent !== initial)
|
|
143
199
|
throw new Error(`Hydration mismatch in ${location}`);
|
|
144
200
|
let first = true;
|
|
@@ -175,8 +231,10 @@ export function bindAttribute(scope, id, name, read, location, source) {
|
|
|
175
231
|
/** Conecta un evento al elemento SSR y entrega su función de limpieza. */
|
|
176
232
|
export function bindEvent(scope, id, name, handler) {
|
|
177
233
|
const target = findElement(scope, `data-meeko-e-${id}`);
|
|
178
|
-
|
|
179
|
-
|
|
234
|
+
const report = componentErrorReporter();
|
|
235
|
+
const listener = (event) => observeCallback(() => handler(event), report);
|
|
236
|
+
target.addEventListener(name, listener);
|
|
237
|
+
return () => target.removeEventListener(name, listener);
|
|
180
238
|
}
|
|
181
239
|
/** Genera los límites estables de una condición en SSR. */
|
|
182
240
|
export function renderIf(id, condition, render) {
|
|
@@ -189,18 +247,51 @@ export function bindIf(scope, id, read, render, hydrate) {
|
|
|
189
247
|
if (!active && inner.start?.nextSibling !== inner.end)
|
|
190
248
|
throw new Error(`Hydration mismatch in condition ${id}`);
|
|
191
249
|
let release = active ? hydrate(inner) : undefined;
|
|
192
|
-
|
|
250
|
+
let stop = () => { };
|
|
251
|
+
stop = effect(() => {
|
|
193
252
|
const next = Boolean(read());
|
|
194
253
|
if (next === active)
|
|
195
254
|
return;
|
|
196
|
-
release?.();
|
|
197
|
-
release = undefined;
|
|
198
|
-
clearRegion(inner);
|
|
199
255
|
if (next) {
|
|
200
|
-
|
|
201
|
-
|
|
256
|
+
const html = render();
|
|
257
|
+
try {
|
|
258
|
+
clearRegion(inner);
|
|
259
|
+
insertHtml(inner.end, html);
|
|
260
|
+
release = hydrate(inner);
|
|
261
|
+
active = true;
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
try {
|
|
265
|
+
clearRegion(inner);
|
|
266
|
+
}
|
|
267
|
+
catch (cleanupError) {
|
|
268
|
+
stop();
|
|
269
|
+
throw new AggregateError([error, cleanupError], `Meeko condition ${id} update and cleanup failed`);
|
|
270
|
+
}
|
|
271
|
+
throw error;
|
|
272
|
+
}
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const failures = [];
|
|
276
|
+
try {
|
|
277
|
+
release?.();
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
failures.push(error);
|
|
281
|
+
}
|
|
282
|
+
release = undefined;
|
|
283
|
+
try {
|
|
284
|
+
clearRegion(inner);
|
|
202
285
|
}
|
|
203
|
-
|
|
286
|
+
catch (error) {
|
|
287
|
+
failures.push(error);
|
|
288
|
+
stop();
|
|
289
|
+
}
|
|
290
|
+
active = false;
|
|
291
|
+
if (failures.length === 1)
|
|
292
|
+
throw failures[0];
|
|
293
|
+
if (failures.length > 1)
|
|
294
|
+
throw new AggregateError(failures, `Meeko condition ${id} update failed`);
|
|
204
295
|
});
|
|
205
296
|
return () => { stop(); release?.(); };
|
|
206
297
|
}
|
|
@@ -231,9 +322,12 @@ function moveRange(start, end, before) {
|
|
|
231
322
|
const parent = before.parentNode;
|
|
232
323
|
if (!parent)
|
|
233
324
|
throw new Error("Detached Meeko list");
|
|
325
|
+
if (start.parentNode !== parent || end.parentNode !== parent)
|
|
326
|
+
throw new Error("Detached Meeko list row");
|
|
234
327
|
const document = before.ownerDocument;
|
|
235
328
|
if (!document)
|
|
236
329
|
throw new Error("Missing document for Meeko list");
|
|
330
|
+
const originalNext = end.nextSibling;
|
|
237
331
|
const fragment = document.createDocumentFragment();
|
|
238
332
|
for (let node = start; node;) {
|
|
239
333
|
const next = node.nextSibling;
|
|
@@ -242,7 +336,30 @@ function moveRange(start, end, before) {
|
|
|
242
336
|
break;
|
|
243
337
|
node = next;
|
|
244
338
|
}
|
|
245
|
-
|
|
339
|
+
try {
|
|
340
|
+
parent.insertBefore(fragment, before);
|
|
341
|
+
}
|
|
342
|
+
catch (error) {
|
|
343
|
+
try {
|
|
344
|
+
parent.insertBefore(fragment, originalNext);
|
|
345
|
+
}
|
|
346
|
+
catch (restoreError) {
|
|
347
|
+
throw new AggregateError([error, restoreError], "Meeko list move and restoration failed");
|
|
348
|
+
}
|
|
349
|
+
throw error;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function removeRange(start, end) {
|
|
353
|
+
const parent = start.parentNode;
|
|
354
|
+
if (!parent || end.parentNode !== parent)
|
|
355
|
+
throw new Error("Detached Meeko list row");
|
|
356
|
+
for (let node = start; node;) {
|
|
357
|
+
const next = node.nextSibling;
|
|
358
|
+
parent.removeChild(node);
|
|
359
|
+
if (node === end)
|
|
360
|
+
break;
|
|
361
|
+
node = next;
|
|
362
|
+
}
|
|
246
363
|
}
|
|
247
364
|
/** Encuentra las posiciones que ya mantienen el orden relativo de la lista anterior. */
|
|
248
365
|
function stableListPositions(indices) {
|
|
@@ -281,35 +398,46 @@ export function bindFor(scope, id, read, keyOf, render, hydrate, trackIndex = tr
|
|
|
281
398
|
const initial = [...read()];
|
|
282
399
|
let currentKeys = [];
|
|
283
400
|
let cursor = outer.start.nextSibling;
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
401
|
+
try {
|
|
402
|
+
for (let index = 0; index < initial.length; index++) {
|
|
403
|
+
const item = initial[index];
|
|
404
|
+
const key = keyToken(keyOf(item, index));
|
|
405
|
+
if (entries.has(key))
|
|
406
|
+
throw new Error(`Duplicate Meeko list key ${key}`);
|
|
407
|
+
const startData = `meeko:item:${id}:${key}`;
|
|
408
|
+
const endData = `/meeko:item:${id}:${key}`;
|
|
409
|
+
if (!cursor || cursor.nodeType !== 8 || cursor.data !== startData)
|
|
410
|
+
throw new Error(`Hydration mismatch in list ${id} at key ${key}`);
|
|
411
|
+
const start = cursor;
|
|
412
|
+
let end = start.nextSibling;
|
|
413
|
+
while (end && (end.nodeType !== 8 || end.data !== endData))
|
|
414
|
+
end = end.nextSibling;
|
|
415
|
+
if (!end)
|
|
416
|
+
throw new Error(`Missing end marker for list key ${key}`);
|
|
417
|
+
const value = signal(item);
|
|
418
|
+
const position = trackIndex ? signal(index) : undefined;
|
|
419
|
+
const release = createRoot((dispose) => {
|
|
420
|
+
const cleanup = hydrate(value, position, { root: scope.root, start, end: end });
|
|
421
|
+
return () => finishWithCleanup(cleanup, dispose);
|
|
422
|
+
});
|
|
423
|
+
entries.set(key, { key, start, end: end, value, index: position, release });
|
|
424
|
+
currentKeys.push(key);
|
|
425
|
+
cursor = end.nextSibling;
|
|
426
|
+
}
|
|
427
|
+
if (cursor !== outer.end)
|
|
428
|
+
throw new Error(`Hydration mismatch in list ${id}: extra nodes`);
|
|
429
|
+
}
|
|
430
|
+
catch (error) {
|
|
431
|
+
try {
|
|
432
|
+
releaseAll([...entries.values()].map((entry) => entry.release), { error });
|
|
433
|
+
}
|
|
434
|
+
finally {
|
|
435
|
+
entries.clear();
|
|
436
|
+
}
|
|
308
437
|
}
|
|
309
|
-
if (cursor !== outer.end)
|
|
310
|
-
throw new Error(`Hydration mismatch in list ${id}: extra nodes`);
|
|
311
438
|
let initialItems = initial;
|
|
312
|
-
|
|
439
|
+
let stop = () => { };
|
|
440
|
+
stop = effect(() => {
|
|
313
441
|
const items = [...read()];
|
|
314
442
|
if (initialItems) {
|
|
315
443
|
const previous = initialItems;
|
|
@@ -324,54 +452,131 @@ export function bindFor(scope, id, read, keyOf, render, hydrate, trackIndex = tr
|
|
|
324
452
|
const oldPositions = new Map(currentKeys.map((key, index) => [key, index]));
|
|
325
453
|
const oldIndices = nextKeys.map((key) => oldPositions.get(key) ?? -1);
|
|
326
454
|
const stable = stableListPositions(oldIndices);
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
entries.delete(key);
|
|
340
|
-
}
|
|
341
|
-
let before = outer.end;
|
|
342
|
-
for (let index = items.length - 1; index >= 0; index--) {
|
|
343
|
-
const item = items[index];
|
|
344
|
-
const key = nextKeys[index];
|
|
345
|
-
let entry = entries.get(key);
|
|
346
|
-
if (!entry) {
|
|
347
|
-
const html = `<!--meeko:item:${id}:${key}-->${render(item, index)}<!--/meeko:item:${id}:${key}-->`;
|
|
348
|
-
insertHtml(before, html);
|
|
349
|
-
const end = before.previousSibling;
|
|
455
|
+
const newRows = items.flatMap((item, index) => entries.has(nextKeys[index]) ? [] : [{
|
|
456
|
+
key: nextKeys[index], index, item,
|
|
457
|
+
html: `<!--meeko:item:${id}:${nextKeys[index]}-->${render(item, index)}<!--/meeko:item:${id}:${nextKeys[index]}-->`,
|
|
458
|
+
}]);
|
|
459
|
+
const staged = new Map();
|
|
460
|
+
const inserted = [];
|
|
461
|
+
let moving = false;
|
|
462
|
+
try {
|
|
463
|
+
for (const row of newRows) {
|
|
464
|
+
const marker = outer.end;
|
|
465
|
+
insertHtml(marker, row.html);
|
|
466
|
+
const end = marker.previousSibling;
|
|
350
467
|
let start = end.previousSibling;
|
|
351
|
-
while (start && (start.nodeType !== 8 || start.data !== `meeko:item:${id}:${key}`))
|
|
468
|
+
while (start && (start.nodeType !== 8 || start.data !== `meeko:item:${id}:${row.key}`))
|
|
352
469
|
start = start.previousSibling;
|
|
353
470
|
if (!start)
|
|
354
|
-
throw new Error(`Missing new list marker for ${key}`);
|
|
355
|
-
|
|
356
|
-
const
|
|
471
|
+
throw new Error(`Missing new list marker for ${row.key}`);
|
|
472
|
+
inserted.push({ start: start, end });
|
|
473
|
+
const value = signal(row.item);
|
|
474
|
+
const position = trackIndex ? signal(row.index) : undefined;
|
|
357
475
|
const release = createRoot((dispose) => {
|
|
358
476
|
const cleanup = hydrate(value, position, { root: scope.root, start: start, end });
|
|
359
|
-
return () =>
|
|
477
|
+
return () => finishWithCleanup(cleanup, dispose);
|
|
360
478
|
});
|
|
361
|
-
|
|
362
|
-
|
|
479
|
+
staged.set(row.key, { key: row.key, start: start, end, value, index: position, release });
|
|
480
|
+
}
|
|
481
|
+
moving = true;
|
|
482
|
+
let before = outer.end;
|
|
483
|
+
for (let index = items.length - 1; index >= 0; index--) {
|
|
484
|
+
const key = nextKeys[index];
|
|
485
|
+
const entry = entries.get(key) ?? staged.get(key);
|
|
486
|
+
if ((oldIndices[index] === -1 || !stable.has(index)) && entry.end.nextSibling !== before) {
|
|
487
|
+
moveRange(entry.start, entry.end, before);
|
|
488
|
+
}
|
|
489
|
+
before = entry.start;
|
|
363
490
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
491
|
+
}
|
|
492
|
+
catch (error) {
|
|
493
|
+
const failures = [error];
|
|
494
|
+
for (const entry of [...staged.values()].reverse()) {
|
|
495
|
+
try {
|
|
496
|
+
entry.release();
|
|
497
|
+
}
|
|
498
|
+
catch (cleanupError) {
|
|
499
|
+
failures.push(cleanupError);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
for (const row of inserted.reverse()) {
|
|
503
|
+
try {
|
|
504
|
+
removeRange(row.start, row.end);
|
|
505
|
+
}
|
|
506
|
+
catch (cleanupError) {
|
|
507
|
+
failures.push(cleanupError);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
if (moving) {
|
|
511
|
+
let before = outer.end;
|
|
512
|
+
for (let index = currentKeys.length - 1; index >= 0; index--) {
|
|
513
|
+
const entry = entries.get(currentKeys[index]);
|
|
514
|
+
try {
|
|
515
|
+
if (entry.end.nextSibling !== before)
|
|
516
|
+
moveRange(entry.start, entry.end, before);
|
|
517
|
+
before = entry.start;
|
|
518
|
+
}
|
|
519
|
+
catch (restoreError) {
|
|
520
|
+
failures.push(restoreError);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
368
523
|
}
|
|
369
|
-
if (
|
|
370
|
-
|
|
371
|
-
|
|
524
|
+
if (failures.length > 1) {
|
|
525
|
+
stop();
|
|
526
|
+
throw new AggregateError(failures, `Meeko list ${id} update and cleanup failed`);
|
|
527
|
+
}
|
|
528
|
+
throw error;
|
|
372
529
|
}
|
|
530
|
+
const failures = [];
|
|
531
|
+
for (const [key, entry] of entries) {
|
|
532
|
+
if (nextKeySet.has(key))
|
|
533
|
+
continue;
|
|
534
|
+
try {
|
|
535
|
+
entry.release();
|
|
536
|
+
}
|
|
537
|
+
catch (error) {
|
|
538
|
+
failures.push(error);
|
|
539
|
+
}
|
|
540
|
+
try {
|
|
541
|
+
removeRange(entry.start, entry.end);
|
|
542
|
+
}
|
|
543
|
+
catch (error) {
|
|
544
|
+
failures.push(error);
|
|
545
|
+
stop();
|
|
546
|
+
}
|
|
547
|
+
entries.delete(key);
|
|
548
|
+
}
|
|
549
|
+
for (const [key, entry] of staged)
|
|
550
|
+
entries.set(key, entry);
|
|
373
551
|
currentKeys = nextKeys;
|
|
552
|
+
try {
|
|
553
|
+
batch(() => {
|
|
554
|
+
for (let index = 0; index < items.length; index++) {
|
|
555
|
+
const entry = entries.get(nextKeys[index]);
|
|
556
|
+
if (staged.has(entry.key))
|
|
557
|
+
continue;
|
|
558
|
+
entry.value.value = items[index];
|
|
559
|
+
if (entry.index)
|
|
560
|
+
entry.index.value = index;
|
|
561
|
+
}
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
catch (error) {
|
|
565
|
+
failures.push(error);
|
|
566
|
+
}
|
|
567
|
+
if (failures.length === 1)
|
|
568
|
+
throw failures[0];
|
|
569
|
+
if (failures.length > 1)
|
|
570
|
+
throw new AggregateError(failures, `Meeko list ${id} update failed`);
|
|
374
571
|
});
|
|
375
|
-
return () => {
|
|
376
|
-
|
|
572
|
+
return () => {
|
|
573
|
+
stop();
|
|
574
|
+
try {
|
|
575
|
+
releaseAll([...entries.values()].map((entry) => entry.release));
|
|
576
|
+
}
|
|
577
|
+
finally {
|
|
578
|
+
entries.clear();
|
|
579
|
+
}
|
|
580
|
+
};
|
|
377
581
|
}
|
|
582
|
+
//# sourceMappingURL=dom.js.map
|
package/dist/dom.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../src/dom.ts"],"names":[],"mappings":"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","sourcesContent":["import { batch, createRoot, effect, finishWithCleanup, signal } from \"./reactivity.js\";\nimport { observeCallback } from \"./error-observer.js\";\nimport { componentErrorReporter } from \"./component-errors.js\";\nimport type { EffectSource, Signal } from \"./reactivity.js\";\nimport { attributeValue, serializeJson } from \"./server.js\";\n\n/** Fragmento de DOM que pertenece a una instancia o a una región dinámica. */\nexport interface DomScope {\n root: Element;\n start?: Comment;\n end?: Comment;\n}\n\n/** Contrato de un módulo de componente compilado para composición sin wrapper. */\nexport interface ComponentModule<Props extends object> {\n readonly renderToString: (props: Props, state?: Record<string, unknown>) => string;\n readonly renderWithState?: (props: Props) => { html: string; state: Record<string, unknown> };\n readonly hydrateScope: (scope: DomScope, props: Props, state?: Record<string, unknown>) => ComponentRelease;\n}\n\n/** Componente compilado que puede transferir su estado durante SSR. */\nexport type Component<Props extends object> = ComponentModule<Props> & {\n readonly renderWithState: (props: Props) => { html: string; state: Record<string, unknown> };\n};\n\n/** Función de limpieza que puede exponer el estado editable de su instancia. */\nexport interface ComponentRelease {\n (): void;\n snapshot?: () => Record<string, unknown>;\n}\n\n/** Releases every compiled binding and preserves the failure that triggered cleanup. */\nexport function releaseAll(cleanups: Array<() => void>, cause: { error: unknown }): never;\nexport function releaseAll(cleanups: Array<() => void>): void;\nexport function releaseAll(cleanups: Array<() => void>, cause?: { error: unknown }): void {\n const failures: unknown[] = cause ? [cause.error] : [];\n while (cleanups.length) {\n try { cleanups.pop()!(); }\n catch (error) { failures.push(error); }\n }\n if (failures.length > 1) throw new AggregateError(failures, \"Meeko hydration cleanup failed\");\n if (failures.length === 1) throw failures[0];\n}\n\n/** Añade una lectura de estado a la limpieza de un componente compilado. */\nexport function withStateSnapshot(release: () => void, snapshot: () => Record<string, unknown>): ComponentRelease {\n return Object.assign(release, { snapshot });\n}\n\nconst componentStart = /^meeko:component:\\d+(?::.*)?$/;\n\nfunction componentEnd(start: Node): Node {\n let depth = 0;\n for (let node: Node | null = start; node; node = node.nextSibling) {\n if (node.nodeType !== 8) continue;\n const data = (node as Comment).data;\n if (componentStart.test(data)) depth++;\n else if (/^\\/meeko:component:\\d+$/.test(data) && --depth === 0) return node;\n }\n throw new Error(`Missing end marker for ${(start as Comment).data}`);\n}\n\nfunction visit(scope: DomScope, callback: (node: Node) => boolean): Node | undefined {\n function siblings(first: Node | null, stop: Node | null = null): Node | undefined {\n for (let node = first; node && node !== stop;) {\n if (callback(node)) return node;\n if (node.nodeType === 8 && componentStart.test((node as Comment).data)) {\n const end = componentEnd(node);\n if (callback(end)) return end;\n node = end.nextSibling;\n continue;\n }\n const found = siblings(node.firstChild);\n if (found) return found;\n node = node.nextSibling;\n }\n return undefined;\n }\n return siblings(scope.start?.nextSibling ?? scope.root.firstChild, scope.end ?? null);\n}\n\nfunction findComment(scope: DomScope, data: string): Comment {\n const node = visit(scope, (candidate) => candidate.nodeType === 8 && (candidate as Comment).data === data);\n if (!node) throw new Error(`Missing Meeko marker ${data}`);\n return node as Comment;\n}\n\nfunction findElement(scope: DomScope, name: string): Element {\n const node = visit(scope, (candidate) => candidate.nodeType === 1 && (candidate as Element).hasAttribute(name));\n if (!node) throw new Error(`Missing Meeko target ${name}`);\n return node as Element;\n}\n\nfunction region(scope: DomScope, kind: string, id: number): DomScope {\n const start = findComment(scope, `meeko:${kind}:${id}`);\n const end = findComment(scope, `/meeko:${kind}:${id}`);\n if (start.parentNode !== end.parentNode) throw new Error(`Invalid Meeko region ${kind}:${id}`);\n return { root: scope.root, start, end };\n}\n\nfunction clearRegion(scope: DomScope): void {\n if (!scope.start || !scope.end) throw new Error(\"Expected a bounded Meeko region\");\n for (let node = scope.start.nextSibling; node && node !== scope.end;) {\n const next = node.nextSibling;\n node.parentNode?.removeChild(node);\n node = next;\n }\n}\n\nfunction cloneRegion(scope: DomScope): DocumentFragment {\n if (!scope.start || !scope.end) throw new Error(\"Expected a bounded Meeko region\");\n const range = scope.start.ownerDocument.createRange();\n range.setStartAfter(scope.start);\n range.setEndBefore(scope.end);\n return range.cloneContents();\n}\n\nfunction restoreRegion(scope: DomScope, content: DocumentFragment): void {\n clearRegion(scope);\n scope.end!.parentNode!.insertBefore(content, scope.end!);\n}\n\nfunction insertHtml(end: Comment, html: string): void {\n const parent = end.parentNode;\n if (!parent) throw new Error(\"Detached Meeko region\");\n const range = end.ownerDocument.createRange();\n range.selectNodeContents(parent);\n parent.insertBefore(range.createContextualFragment(html), end);\n}\n\nfunction sameProps<Props extends object>(first: Props, second: Props): boolean {\n const firstKeys = Object.keys(first);\n const secondKeys = Object.keys(second);\n return firstKeys.length === secondKeys.length && firstKeys.every((key) => Object.hasOwn(second, key) && Object.is(first[key as keyof Props], second[key as keyof Props]));\n}\n\n/** Renderiza un hijo entre comentarios de ámbito sin añadir un elemento visual. */\nexport function renderComponent<Props extends object>(id: number, component: Component<Props>, props: Props, transferState: boolean): string;\nexport function renderComponent<Props extends object>(id: number, component: ComponentModule<Props>, props: Props, transferState?: false): string;\nexport function renderComponent<Props extends object>(id: number, component: ComponentModule<Props>, props: Props, transferState = false): string {\n if (transferState) {\n if (!component.renderWithState) throw new TypeError(`Component ${id} cannot transfer SSR state`);\n const rendered = component.renderWithState(props);\n return `<!--meeko:component:${id}:${encodeURIComponent(serializeJson(rendered.state))}-->${rendered.html}<!--/meeko:component:${id}-->`;\n }\n return `<!--meeko:component:${id}-->${component.renderToString(props)}<!--/meeko:component:${id}-->`;\n}\n\nfunction componentRegion(scope: DomScope, id: number): { inner: DomScope; state?: Record<string, unknown> } {\n const prefix = `meeko:component:${id}`;\n const start = visit(scope, (candidate) => candidate.nodeType === 8 && ((candidate as Comment).data === prefix || (candidate as Comment).data.startsWith(`${prefix}:`))) as Comment | undefined;\n if (!start) throw new Error(`Missing Meeko marker ${prefix}`);\n const end = findComment(scope, `/meeko:component:${id}`);\n if (start.parentNode !== end.parentNode) throw new Error(`Invalid Meeko region component:${id}`);\n const encoded = start.data.slice(prefix.length);\n if (!encoded) return { inner: { root: scope.root, start, end } };\n const parsed: unknown = JSON.parse(decodeURIComponent(encoded.slice(1)));\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) throw new TypeError(`Invalid Meeko state for component:${id}`);\n return { inner: { root: scope.root, start, end }, state: parsed as Record<string, unknown> };\n}\n\n/** Hidrata un hijo dentro de su rango y actualiza props reactivas con limpieza previa. */\nexport function bindComponent<Props extends object>(scope: DomScope, id: number, input: ComponentModule<Props> | (() => ComponentModule<Props>), read: () => Props, location: string): () => void {\n let inner: DomScope;\n let state: Record<string, unknown> | undefined;\n try {\n ({ inner, state } = componentRegion(scope, id));\n } catch (error) {\n throw new Error(`Hydration mismatch in ${location}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });\n }\n const resolveComponent = (): ComponentModule<Props> => typeof input === \"function\" ? input() : input;\n let component = resolveComponent();\n let props = read();\n let release = component.hydrateScope(inner, props, state);\n let stop = () => {};\n stop = effect(() => {\n const nextComponent = resolveComponent();\n const next = read();\n if (nextComponent === component && sameProps(props, next)) return;\n const previousState = release.snapshot?.();\n const state = nextComponent === component ? previousState : undefined;\n const html = nextComponent.renderToString(next, state);\n const previous = cloneRegion(inner);\n try {\n release();\n clearRegion(inner);\n insertHtml(inner.end!, html);\n const nextRelease = nextComponent.hydrateScope(inner, next, state);\n release = nextRelease;\n component = nextComponent;\n props = next;\n } catch (error) {\n try {\n restoreRegion(inner, previous);\n release = component.hydrateScope(inner, props, previousState);\n } catch (rollbackError) {\n release = () => {};\n stop();\n throw new AggregateError([error, rollbackError], `Meeko component update and recovery failed in ${location}`);\n }\n throw error;\n }\n });\n return () => { stop(); release(); };\n}\n\n/** Conecta un texto reactivo al marcador SSR y comprueba su valor inicial. */\nexport function bindText(scope: DomScope, id: number, read: () => unknown, location: string, source?: EffectSource): () => void {\n const marker = findComment(scope, `meeko:text:${id}`);\n const initial = String(read());\n let text = marker.nextSibling;\n // HTML parsing drops empty text nodes. Restore only that empty SSR case so\n // adjacent static text stays untouched and the reactive expression can bind.\n if (initial === \"\" && (!text || text.nodeType !== 3 || text.textContent !== \"\")) {\n text = marker.ownerDocument.createTextNode(\"\");\n marker.parentNode!.insertBefore(text, marker.nextSibling);\n }\n if (!text || text.nodeType !== 3) throw new Error(`Missing text node in ${location}`);\n if (text.textContent !== initial) throw new Error(`Hydration mismatch in ${location}`);\n let first = true;\n return effect(() => {\n const next = String(read());\n if (first) {\n first = false;\n if (text.textContent === next) return;\n }\n text.textContent = next;\n }, source);\n}\n\n/** Conecta un atributo dinámico al elemento SSR y comprueba su valor inicial. */\nexport function bindAttribute(scope: DomScope, id: number, name: string, read: () => unknown, location: string, source?: EffectSource): () => void {\n const target = findElement(scope, `data-meeko-a-${id}`);\n const initial = attributeValue(name, read());\n if (target.getAttribute(name) !== initial) throw new Error(`Hydration mismatch in ${location}`);\n let first = true;\n return effect(() => {\n const next = attributeValue(name, read());\n if (first) {\n first = false;\n if (target.getAttribute(name) === next) return;\n }\n if (next === null) target.removeAttribute(name);\n else target.setAttribute(name, next);\n }, source);\n}\n\n/** Conecta un evento al elemento SSR y entrega su función de limpieza. */\nexport function bindEvent(scope: DomScope, id: number, name: string, handler: (event: Event) => void): () => void {\n const target = findElement(scope, `data-meeko-e-${id}`);\n const report = componentErrorReporter();\n const listener = (event: Event) => observeCallback(\n () => handler(event),\n report,\n );\n target.addEventListener(name, listener);\n return () => target.removeEventListener(name, listener);\n}\n\n/** Genera los límites estables de una condición en SSR. */\nexport function renderIf(id: number, condition: unknown, render: () => string): string {\n return `<!--meeko:if:${id}-->${condition ? render() : \"\"}<!--/meeko:if:${id}-->`;\n}\n\n/** Hidrata una condición y conserva los nodos mientras sigue siendo verdadera. */\nexport function bindIf(scope: DomScope, id: number, read: () => unknown, render: () => string, hydrate: (inner: DomScope) => () => void): () => void {\n const inner = region(scope, \"if\", id);\n let active = Boolean(read());\n if (!active && inner.start?.nextSibling !== inner.end) throw new Error(`Hydration mismatch in condition ${id}`);\n let release = active ? hydrate(inner) : undefined;\n let stop = () => {};\n stop = effect(() => {\n const next = Boolean(read());\n if (next === active) return;\n if (next) {\n const html = render();\n try {\n clearRegion(inner);\n insertHtml(inner.end!, html);\n release = hydrate(inner);\n active = true;\n } catch (error) {\n try { clearRegion(inner); }\n catch (cleanupError) {\n stop();\n throw new AggregateError([error, cleanupError], `Meeko condition ${id} update and cleanup failed`);\n }\n throw error;\n }\n return;\n }\n const failures: unknown[] = [];\n try { release?.(); }\n catch (error) { failures.push(error); }\n release = undefined;\n try { clearRegion(inner); }\n catch (error) { failures.push(error); stop(); }\n active = false;\n if (failures.length === 1) throw failures[0];\n if (failures.length > 1) throw new AggregateError(failures, `Meeko condition ${id} update failed`);\n });\n return () => { stop(); release?.(); };\n}\n\n/** Convierte una clave de lista en un token seguro para comentarios HTML. */\nexport function keyToken(key: unknown): string {\n if (typeof key === \"number\" && Number.isFinite(key)) return `n${encodeURIComponent(String(key)).replaceAll(\"-\", \"%2D\")}`;\n if (typeof key === \"string\") return `s${encodeURIComponent(key).replaceAll(\"-\", \"%2D\")}`;\n throw new TypeError(\"Meeko list keys must be strings or finite numbers\");\n}\n\n/** Renderiza una lista con límites identificados por claves únicas. */\nexport function renderFor<T>(id: number, items: Iterable<T>, keyOf: (item: T, index: number) => string | number, render: (item: T, index: number) => string): string {\n const seen = new Set<string>();\n let html = `<!--meeko:for:${id}-->`;\n let index = 0;\n for (const item of items) {\n const key = keyToken(keyOf(item, index));\n if (seen.has(key)) throw new Error(`Duplicate Meeko list key ${key}`);\n seen.add(key);\n html += `<!--meeko:item:${id}:${key}-->${render(item, index)}<!--/meeko:item:${id}:${key}-->`;\n index++;\n }\n return `${html}<!--/meeko:for:${id}-->`;\n}\n\ninterface ListEntry<T> {\n key: string;\n start: Comment;\n end: Comment;\n value: Signal<T>;\n index: Signal<number> | undefined;\n release: () => void;\n}\n\nfunction moveRange(start: Comment, end: Comment, before: Node): void {\n const parent = before.parentNode;\n if (!parent) throw new Error(\"Detached Meeko list\");\n if (start.parentNode !== parent || end.parentNode !== parent) throw new Error(\"Detached Meeko list row\");\n const document = before.ownerDocument;\n if (!document) throw new Error(\"Missing document for Meeko list\");\n const originalNext = end.nextSibling;\n const fragment = document.createDocumentFragment();\n for (let node: Node | null = start; node;) {\n const next: Node | null = node.nextSibling;\n fragment.appendChild(node);\n if (node === end) break;\n node = next;\n }\n try { parent.insertBefore(fragment, before); }\n catch (error) {\n try { parent.insertBefore(fragment, originalNext); }\n catch (restoreError) {\n throw new AggregateError([error, restoreError], \"Meeko list move and restoration failed\");\n }\n throw error;\n }\n}\n\nfunction removeRange(start: Comment, end: Comment): void {\n const parent = start.parentNode;\n if (!parent || end.parentNode !== parent) throw new Error(\"Detached Meeko list row\");\n for (let node: Node | null = start; node;) {\n const next: Node | null = node.nextSibling;\n parent.removeChild(node);\n if (node === end) break;\n node = next;\n }\n}\n\n/** Encuentra las posiciones que ya mantienen el orden relativo de la lista anterior. */\nfunction stableListPositions(indices: readonly number[]): Set<number> {\n const tails: number[] = [];\n const previous = new Int32Array(indices.length).fill(-1);\n for (let index = 0; index < indices.length; index++) {\n const oldIndex = indices[index]!;\n if (oldIndex < 0) continue;\n let low = 0;\n let high = tails.length;\n while (low < high) {\n const middle = (low + high) >>> 1;\n if (indices[tails[middle]!]! < oldIndex) low = middle + 1;\n else high = middle;\n }\n if (low > 0) previous[index] = tails[low - 1]!;\n tails[low] = index;\n }\n const stable = new Set<number>();\n for (let index = tails.at(-1) ?? -1; index >= 0; index = previous[index]!) stable.add(index);\n return stable;\n}\n\n/**\n * Hidrata una lista y reordena regiones por clave sin reemplazar nodos conservados.\n * El compilador desactiva `trackIndex` sólo cuando el cuerpo de hidratación no lee\n * la señal de índice; las llamadas directas conservan la señal por defecto.\n */\nexport function bindFor<T>(scope: DomScope, id: number, read: () => Iterable<T>, keyOf: (item: T, index: number) => string | number, render: (item: T, index: number) => string, hydrate: (item: Signal<T>, index: Signal<number>, inner: DomScope) => () => void, trackIndex = true): () => void {\n const outer = region(scope, \"for\", id);\n const entries = new Map<string, ListEntry<T>>();\n const initial = [...read()];\n let currentKeys: string[] = [];\n let cursor = outer.start!.nextSibling;\n try {\n for (let index = 0; index < initial.length; index++) {\n const item = initial[index]!;\n const key = keyToken(keyOf(item, index));\n if (entries.has(key)) throw new Error(`Duplicate Meeko list key ${key}`);\n const startData = `meeko:item:${id}:${key}`;\n const endData = `/meeko:item:${id}:${key}`;\n if (!cursor || cursor.nodeType !== 8 || (cursor as Comment).data !== startData) throw new Error(`Hydration mismatch in list ${id} at key ${key}`);\n const start = cursor as Comment;\n let end = start.nextSibling;\n while (end && (end.nodeType !== 8 || (end as Comment).data !== endData)) end = end.nextSibling;\n if (!end) throw new Error(`Missing end marker for list key ${key}`);\n const value = signal(item);\n const position = trackIndex ? signal(index) : undefined;\n const release = createRoot((dispose) => {\n const cleanup = hydrate(value, position as Signal<number>, { root: scope.root, start, end: end as Comment });\n return () => finishWithCleanup(cleanup, dispose);\n });\n entries.set(key, { key, start, end: end as Comment, value, index: position, release });\n currentKeys.push(key);\n cursor = end.nextSibling;\n }\n if (cursor !== outer.end) throw new Error(`Hydration mismatch in list ${id}: extra nodes`);\n } catch (error) {\n try { releaseAll([...entries.values()].map((entry) => entry.release), { error }); }\n finally { entries.clear(); }\n }\n let initialItems: T[] | undefined = initial;\n let stop = () => {};\n stop = effect(() => {\n const items = [...read()];\n if (initialItems) {\n const previous = initialItems;\n initialItems = undefined;\n if (items.length === previous.length && items.every((item, index) =>\n Object.is(item, previous[index]) && keyToken(keyOf(item, index)) === currentKeys[index])) return;\n }\n const nextKeys = items.map((item, index) => keyToken(keyOf(item, index)));\n const nextKeySet = new Set(nextKeys);\n if (nextKeySet.size !== nextKeys.length) throw new Error(`Duplicate Meeko list key in region ${id}`);\n const oldPositions = new Map(currentKeys.map((key, index) => [key, index]));\n const oldIndices = nextKeys.map((key) => oldPositions.get(key) ?? -1);\n const stable = stableListPositions(oldIndices);\n const newRows = items.flatMap((item, index) => entries.has(nextKeys[index]!) ? [] : [{\n key: nextKeys[index]!, index, item,\n html: `<!--meeko:item:${id}:${nextKeys[index]}-->${render(item, index)}<!--/meeko:item:${id}:${nextKeys[index]}-->`,\n }]);\n const staged = new Map<string, ListEntry<T>>();\n const inserted: Array<{ start: Comment; end: Comment }> = [];\n let moving = false;\n try {\n for (const row of newRows) {\n const marker = outer.end!;\n insertHtml(marker, row.html);\n const end = marker.previousSibling as Comment;\n let start: Node | null = end.previousSibling;\n while (start && (start.nodeType !== 8 || (start as Comment).data !== `meeko:item:${id}:${row.key}`)) start = start.previousSibling;\n if (!start) throw new Error(`Missing new list marker for ${row.key}`);\n inserted.push({ start: start as Comment, end });\n const value = signal(row.item);\n const position = trackIndex ? signal(row.index) : undefined;\n const release = createRoot((dispose) => {\n const cleanup = hydrate(value, position as Signal<number>, { root: scope.root, start: start as Comment, end });\n return () => finishWithCleanup(cleanup, dispose);\n });\n staged.set(row.key, { key: row.key, start: start as Comment, end, value, index: position, release });\n }\n moving = true;\n let before: Node = outer.end!;\n for (let index = items.length - 1; index >= 0; index--) {\n const key = nextKeys[index]!;\n const entry = entries.get(key) ?? staged.get(key)!;\n if ((oldIndices[index] === -1 || !stable.has(index)) && entry.end.nextSibling !== before) {\n moveRange(entry.start, entry.end, before);\n }\n before = entry.start;\n }\n } catch (error) {\n const failures: unknown[] = [error];\n for (const entry of [...staged.values()].reverse()) {\n try { entry.release(); }\n catch (cleanupError) { failures.push(cleanupError); }\n }\n for (const row of inserted.reverse()) {\n try { removeRange(row.start, row.end); }\n catch (cleanupError) { failures.push(cleanupError); }\n }\n if (moving) {\n let before: Node = outer.end!;\n for (let index = currentKeys.length - 1; index >= 0; index--) {\n const entry = entries.get(currentKeys[index]!)!;\n try {\n if (entry.end.nextSibling !== before) moveRange(entry.start, entry.end, before);\n before = entry.start;\n } catch (restoreError) { failures.push(restoreError); }\n }\n }\n if (failures.length > 1) {\n stop();\n throw new AggregateError(failures, `Meeko list ${id} update and cleanup failed`);\n }\n throw error;\n }\n const failures: unknown[] = [];\n for (const [key, entry] of entries) {\n if (nextKeySet.has(key)) continue;\n try { entry.release(); }\n catch (error) { failures.push(error); }\n try { removeRange(entry.start, entry.end); }\n catch (error) { failures.push(error); stop(); }\n entries.delete(key);\n }\n for (const [key, entry] of staged) entries.set(key, entry);\n currentKeys = nextKeys;\n try {\n batch(() => {\n for (let index = 0; index < items.length; index++) {\n const entry = entries.get(nextKeys[index]!)!;\n if (staged.has(entry.key)) continue;\n entry.value.value = items[index]!;\n if (entry.index) entry.index.value = index;\n }\n });\n } catch (error) { failures.push(error); }\n if (failures.length === 1) throw failures[0];\n if (failures.length > 1) throw new AggregateError(failures, `Meeko list ${id} update failed`);\n });\n return () => {\n stop();\n try { releaseAll([...entries.values()].map((entry) => entry.release)); }\n finally { entries.clear(); }\n };\n}\n"]}
|