streetui 1.6.1 → 1.7.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/bin.cjs +1 -1
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/bin.js.map +1 -1
- package/dist/{compile-CEom4hkp.d.cts → compile-Cte0nf06.d.cts} +80 -3
- package/dist/{compile-CEom4hkp.d.ts → compile-Cte0nf06.d.ts} +80 -3
- package/dist/create-bin.cjs +1 -1
- package/dist/create-bin.cjs.map +1 -1
- package/dist/create-bin.js +1 -1
- package/dist/create-bin.js.map +1 -1
- package/dist/{hydration-diagnostics-YrG-OJJe.d.ts → hydration-diagnostics-Ddgs3Puu.d.ts} +1 -1
- package/dist/{hydration-diagnostics-D286jpZZ.d.cts → hydration-diagnostics-zK-fihvd.d.cts} +1 -1
- package/dist/index.cjs +301 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -7
- package/dist/index.d.ts +61 -7
- package/dist/index.js +293 -3
- package/dist/index.js.map +1 -1
- package/dist/{server-ZBh5DO-z.d.cts → server-D4A8eunr.d.cts} +17 -1
- package/dist/{server-jbB-7oN-.d.ts → server-cgmCiPsz.d.ts} +17 -1
- package/dist/server.cjs +1019 -866
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js +1019 -866
- package/dist/server.js.map +1 -1
- package/dist/testing.cjs +187 -3
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +3 -3
- package/dist/testing.d.ts +3 -3
- package/dist/testing.js +187 -3
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/server.cjs
CHANGED
|
@@ -185,978 +185,1130 @@ function wireEvents(dom, graph, node, element, instance) {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
// ../
|
|
189
|
-
var
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
"list-item": "li",
|
|
201
|
-
image: "img",
|
|
202
|
-
link: "a",
|
|
203
|
-
component: "div",
|
|
204
|
-
slot: "div",
|
|
205
|
-
fragment: "div",
|
|
206
|
-
"reactive-list": "ul"
|
|
188
|
+
// ../dom/src/server-node.ts
|
|
189
|
+
var ServerStyle = class {
|
|
190
|
+
declarations = /* @__PURE__ */ new Map();
|
|
191
|
+
setProperty(name, value) {
|
|
192
|
+
this.declarations.set(name, value);
|
|
193
|
+
}
|
|
194
|
+
get isEmpty() {
|
|
195
|
+
return this.declarations.size === 0;
|
|
196
|
+
}
|
|
197
|
+
toCss() {
|
|
198
|
+
return [...this.declarations.entries()].map(([k, v]) => `${k}: ${v}`).join("; ");
|
|
199
|
+
}
|
|
207
200
|
};
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const instance = ctx.instances.get(graphNode.id);
|
|
215
|
-
if (instance === void 0) return;
|
|
216
|
-
const domNode = instance.domNode;
|
|
217
|
-
if (!ctx.dom.isElement(domNode)) return;
|
|
218
|
-
const oldValue = graphNode.getProp(propKey);
|
|
219
|
-
switch (propKey) {
|
|
220
|
-
case "text":
|
|
221
|
-
if (!Object.is(oldValue, newValue)) {
|
|
222
|
-
ctx.dom.setTextContent(domNode, String(newValue ?? ""));
|
|
223
|
-
graphNode.setProp("text", String(newValue ?? ""));
|
|
224
|
-
}
|
|
225
|
-
break;
|
|
226
|
-
case "label":
|
|
227
|
-
if (!Object.is(oldValue, newValue)) {
|
|
228
|
-
ctx.dom.setTextContent(domNode, String(newValue ?? ""));
|
|
229
|
-
graphNode.setProp("label", String(newValue ?? ""));
|
|
230
|
-
}
|
|
231
|
-
break;
|
|
232
|
-
case "disabled":
|
|
233
|
-
if (newValue === true) {
|
|
234
|
-
ctx.dom.setAttribute(domNode, "disabled", "");
|
|
235
|
-
} else {
|
|
236
|
-
ctx.dom.removeAttribute(domNode, "disabled");
|
|
237
|
-
}
|
|
238
|
-
graphNode.setProp("disabled", Boolean(newValue));
|
|
239
|
-
break;
|
|
240
|
-
case "value":
|
|
241
|
-
if (!Object.is(oldValue, newValue)) {
|
|
242
|
-
ctx.dom.setProperty(domNode, "value", String(newValue ?? ""));
|
|
243
|
-
graphNode.setProp("value", String(newValue ?? ""));
|
|
244
|
-
}
|
|
245
|
-
break;
|
|
246
|
-
default:
|
|
247
|
-
patchProp(ctx.dom, domNode, propKey, oldValue, newValue);
|
|
248
|
-
graphNode.setProp(propKey, newValue);
|
|
249
|
-
break;
|
|
201
|
+
var ServerText = class {
|
|
202
|
+
kind = "text";
|
|
203
|
+
parent = null;
|
|
204
|
+
data;
|
|
205
|
+
constructor(data) {
|
|
206
|
+
this.data = data;
|
|
250
207
|
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
oldByKey.set(key, inst);
|
|
208
|
+
};
|
|
209
|
+
var ServerComment = class {
|
|
210
|
+
kind = "comment";
|
|
211
|
+
parent = null;
|
|
212
|
+
data;
|
|
213
|
+
constructor(data) {
|
|
214
|
+
this.data = data;
|
|
259
215
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
newInstances.push(existing);
|
|
274
|
-
} else {
|
|
275
|
-
const inst = mountFn(newNode, parentDom);
|
|
276
|
-
newInstances.push(inst);
|
|
277
|
-
}
|
|
216
|
+
};
|
|
217
|
+
var ServerFragment = class {
|
|
218
|
+
kind = "fragment";
|
|
219
|
+
parent = null;
|
|
220
|
+
children = [];
|
|
221
|
+
};
|
|
222
|
+
var ServerRawHTML = class {
|
|
223
|
+
kind = "raw";
|
|
224
|
+
parent = null;
|
|
225
|
+
html;
|
|
226
|
+
constructor(html) {
|
|
227
|
+
this.html = html;
|
|
278
228
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
229
|
+
};
|
|
230
|
+
var ServerElement = class {
|
|
231
|
+
kind = "element";
|
|
232
|
+
parent = null;
|
|
233
|
+
tagName;
|
|
234
|
+
attributes = /* @__PURE__ */ new Map();
|
|
235
|
+
children = [];
|
|
236
|
+
// Lazily-allocated stores. On the 10k-row SSR corpus ~0% of elements carry JS
|
|
237
|
+
// properties or inline styles (measured, §5: 1 of 80,029 elements uses
|
|
238
|
+
// `properties`, 0 use `style`), so eagerly allocating a `properties` Map plus
|
|
239
|
+
// a `ServerStyle` (which itself holds a Map) per element wasted ~240k
|
|
240
|
+
// allocations per /users render — all in the dominant mount phase. These are
|
|
241
|
+
// created on first WRITE via the `properties`/`style` getters; the serializer
|
|
242
|
+
// reads the raw `_properties`/`_style` fields so a READ never forces an
|
|
243
|
+
// allocation. Output is byte-identical: an unset store previously serialized
|
|
244
|
+
// to nothing (empty `properties.has(...)` / `style.isEmpty`), and a null store
|
|
245
|
+
// is skipped the same way.
|
|
246
|
+
_properties = null;
|
|
247
|
+
_style = null;
|
|
248
|
+
constructor(tagName) {
|
|
249
|
+
this.tagName = tagName.toLowerCase();
|
|
250
|
+
}
|
|
251
|
+
/** JS properties set via `setProperty` (e.g. input `value`, `checked`). Allocated on first access. */
|
|
252
|
+
get properties() {
|
|
253
|
+
return this._properties ??= /* @__PURE__ */ new Map();
|
|
254
|
+
}
|
|
255
|
+
/** Inline-style holder mirroring `element.style`. Allocated on first access. */
|
|
256
|
+
get style() {
|
|
257
|
+
return this._style ??= new ServerStyle();
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
261
|
+
"area",
|
|
262
|
+
"base",
|
|
263
|
+
"br",
|
|
264
|
+
"col",
|
|
265
|
+
"embed",
|
|
266
|
+
"hr",
|
|
267
|
+
"img",
|
|
268
|
+
"input",
|
|
269
|
+
"link",
|
|
270
|
+
"meta",
|
|
271
|
+
"param",
|
|
272
|
+
"source",
|
|
273
|
+
"track",
|
|
274
|
+
"wbr"
|
|
275
|
+
]);
|
|
276
|
+
var SERIALIZED_PROPERTIES = {
|
|
277
|
+
value: "attr",
|
|
278
|
+
checked: "boolean",
|
|
279
|
+
selected: "boolean"
|
|
280
|
+
};
|
|
281
|
+
var SERIALIZED_PROPERTY_ENTRIES = Object.entries(SERIALIZED_PROPERTIES);
|
|
282
|
+
var TEXT_SPECIAL = /[&<>]/;
|
|
283
|
+
var ATTR_SPECIAL = /[&<>"]/;
|
|
284
|
+
function escapeHtmlText(value) {
|
|
285
|
+
if (!TEXT_SPECIAL.test(value)) return value;
|
|
286
|
+
let out = "";
|
|
287
|
+
let last = 0;
|
|
288
|
+
for (let i = 0; i < value.length; i++) {
|
|
289
|
+
let esc;
|
|
290
|
+
switch (value.charCodeAt(i)) {
|
|
291
|
+
case 38:
|
|
292
|
+
esc = "&";
|
|
293
|
+
break;
|
|
294
|
+
// &
|
|
295
|
+
case 60:
|
|
296
|
+
esc = "<";
|
|
297
|
+
break;
|
|
298
|
+
// <
|
|
299
|
+
case 62:
|
|
300
|
+
esc = ">";
|
|
301
|
+
break;
|
|
302
|
+
// >
|
|
303
|
+
default:
|
|
304
|
+
continue;
|
|
284
305
|
}
|
|
306
|
+
out += value.slice(last, i) + esc;
|
|
307
|
+
last = i + 1;
|
|
285
308
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
309
|
+
return out + value.slice(last);
|
|
310
|
+
}
|
|
311
|
+
function escapeHtmlAttr(value) {
|
|
312
|
+
if (!ATTR_SPECIAL.test(value)) return value;
|
|
313
|
+
let out = "";
|
|
314
|
+
let last = 0;
|
|
315
|
+
for (let i = 0; i < value.length; i++) {
|
|
316
|
+
let esc;
|
|
317
|
+
switch (value.charCodeAt(i)) {
|
|
318
|
+
case 38:
|
|
319
|
+
esc = "&";
|
|
320
|
+
break;
|
|
321
|
+
// &
|
|
322
|
+
case 60:
|
|
323
|
+
esc = "<";
|
|
324
|
+
break;
|
|
325
|
+
// <
|
|
326
|
+
case 62:
|
|
327
|
+
esc = ">";
|
|
328
|
+
break;
|
|
329
|
+
// >
|
|
330
|
+
case 34:
|
|
331
|
+
esc = """;
|
|
332
|
+
break;
|
|
333
|
+
// "
|
|
334
|
+
default:
|
|
335
|
+
continue;
|
|
290
336
|
}
|
|
291
|
-
|
|
337
|
+
out += value.slice(last, i) + esc;
|
|
338
|
+
last = i + 1;
|
|
292
339
|
}
|
|
293
|
-
|
|
294
|
-
return { instances: newInstances, removed };
|
|
340
|
+
return out + value.slice(last);
|
|
295
341
|
}
|
|
296
|
-
function
|
|
297
|
-
const
|
|
298
|
-
for (const
|
|
299
|
-
|
|
342
|
+
function serializeAttributes(el) {
|
|
343
|
+
const parts = [];
|
|
344
|
+
for (const [name, value] of el.attributes) {
|
|
345
|
+
if (value === "") {
|
|
346
|
+
parts.push(` ${name}`);
|
|
347
|
+
} else {
|
|
348
|
+
parts.push(` ${name}="${escapeHtmlAttr(value)}"`);
|
|
349
|
+
}
|
|
300
350
|
}
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if (!Object.is(oldSig, newSig)) {
|
|
313
|
-
const freshNode = entry.build();
|
|
314
|
-
built.push(freshNode);
|
|
315
|
-
patchExistingInstance(ctx, existing, freshNode);
|
|
316
|
-
reconcileItemChildren(ctx, existing, freshNode, mountFn);
|
|
317
|
-
existing.graphNode.setProp("_sig", newSig);
|
|
351
|
+
const props = el._properties;
|
|
352
|
+
if (props !== null) {
|
|
353
|
+
for (const [name, kind] of SERIALIZED_PROPERTY_ENTRIES) {
|
|
354
|
+
if (!props.has(name)) continue;
|
|
355
|
+
if (el.attributes.has(name)) continue;
|
|
356
|
+
const raw = props.get(name);
|
|
357
|
+
if (kind === "boolean") {
|
|
358
|
+
if (raw === true) parts.push(` ${name}`);
|
|
359
|
+
} else {
|
|
360
|
+
if (raw !== void 0 && raw !== null) {
|
|
361
|
+
parts.push(` ${name}="${escapeHtmlAttr(String(raw))}"`);
|
|
318
362
|
}
|
|
319
|
-
existing.graphNode.setProp("_item", entry.item);
|
|
320
363
|
}
|
|
321
|
-
newInstances.push(existing);
|
|
322
|
-
} else {
|
|
323
|
-
const freshNode = entry.build();
|
|
324
|
-
built.push(freshNode);
|
|
325
|
-
const inst = mountFn(freshNode, parentDom);
|
|
326
|
-
newInstances.push(inst);
|
|
327
364
|
}
|
|
328
365
|
}
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
if (!usedKeys.has(key)) removed.push(inst);
|
|
333
|
-
}
|
|
334
|
-
for (const inst of removed) {
|
|
335
|
-
const parent = ctx.dom.parentNode(inst.domNode);
|
|
336
|
-
if (parent !== null) ctx.dom.removeChild(parent, inst.domNode);
|
|
337
|
-
inst.dispose();
|
|
366
|
+
const style = el._style;
|
|
367
|
+
if (style !== null && !style.isEmpty && !el.attributes.has("style")) {
|
|
368
|
+
parts.push(` style="${escapeHtmlAttr(style.toCss())}"`);
|
|
338
369
|
}
|
|
339
|
-
|
|
340
|
-
return { instances: newInstances, removed, built };
|
|
370
|
+
return parts.join("");
|
|
341
371
|
}
|
|
342
|
-
function
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
else lastSeen = oi;
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
if (!moved) return;
|
|
362
|
-
const keep = longestIncreasingSubsequence(source);
|
|
363
|
-
let refNode = null;
|
|
364
|
-
for (let i = n - 1; i >= 0; i--) {
|
|
365
|
-
const domNode = newInstances[i].domNode;
|
|
366
|
-
if (source[i] === -1 || !keep.has(i)) {
|
|
367
|
-
if (ctx.dom.nextSibling(domNode) !== refNode) {
|
|
368
|
-
ctx.dom.insertBefore(parentDom, domNode, refNode);
|
|
372
|
+
function serializeServerNode(node) {
|
|
373
|
+
switch (node.kind) {
|
|
374
|
+
case "text":
|
|
375
|
+
return escapeHtmlText(node.data);
|
|
376
|
+
case "comment":
|
|
377
|
+
return `<!--${node.data}-->`;
|
|
378
|
+
case "fragment":
|
|
379
|
+
return serializeChildren(node);
|
|
380
|
+
case "raw":
|
|
381
|
+
return node.html;
|
|
382
|
+
case "element": {
|
|
383
|
+
const el = node;
|
|
384
|
+
const tag = el.tagName;
|
|
385
|
+
const attrs = serializeAttributes(el);
|
|
386
|
+
if (VOID_ELEMENTS.has(tag)) {
|
|
387
|
+
return `<${tag}${attrs}>`;
|
|
369
388
|
}
|
|
389
|
+
return `<${tag}${attrs}>${serializeChildren(el)}</${tag}>`;
|
|
370
390
|
}
|
|
371
|
-
refNode = domNode;
|
|
372
391
|
}
|
|
373
392
|
}
|
|
374
|
-
function
|
|
375
|
-
|
|
376
|
-
const
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
393
|
+
function serializeChildren(node) {
|
|
394
|
+
let out = "";
|
|
395
|
+
for (const child of node.children) {
|
|
396
|
+
out += serializeServerNode(child);
|
|
397
|
+
}
|
|
398
|
+
return out;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// ../dom/src/server-adapter.ts
|
|
402
|
+
function asServer(node) {
|
|
403
|
+
return node;
|
|
404
|
+
}
|
|
405
|
+
function asParent(node) {
|
|
406
|
+
return node;
|
|
407
|
+
}
|
|
408
|
+
var ServerDOMAdapter = class {
|
|
409
|
+
createElement(tag, _ns) {
|
|
410
|
+
return new ServerElement(tag);
|
|
411
|
+
}
|
|
412
|
+
createTextNode(data) {
|
|
413
|
+
return new ServerText(data);
|
|
414
|
+
}
|
|
415
|
+
createComment(data) {
|
|
416
|
+
return new ServerComment(data);
|
|
417
|
+
}
|
|
418
|
+
createFragment() {
|
|
419
|
+
return new ServerFragment();
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Create a verbatim pre-serialized HTML node (v1.7 static SSR plan, §6).
|
|
423
|
+
* Server-only: the browser adapter does not implement this, and the renderer
|
|
424
|
+
* fast path only invokes it when a static SSR plan is present (SSR). The
|
|
425
|
+
* stored HTML was produced by this same serializer, so it is emitted as-is.
|
|
426
|
+
*/
|
|
427
|
+
createRawHTML(html) {
|
|
428
|
+
return new ServerRawHTML(html);
|
|
429
|
+
}
|
|
430
|
+
appendChild(parent, child) {
|
|
431
|
+
const p = asParent(parent);
|
|
432
|
+
const c = asServer(child);
|
|
433
|
+
this._detach(c);
|
|
434
|
+
c.parent = p;
|
|
435
|
+
p.children.push(c);
|
|
436
|
+
}
|
|
437
|
+
insertBefore(parent, child, reference) {
|
|
438
|
+
const p = asParent(parent);
|
|
439
|
+
const c = asServer(child);
|
|
440
|
+
this._detach(c);
|
|
441
|
+
c.parent = p;
|
|
442
|
+
if (reference === null) {
|
|
443
|
+
p.children.push(c);
|
|
444
|
+
return;
|
|
388
445
|
}
|
|
389
|
-
|
|
390
|
-
|
|
446
|
+
const ref = asServer(reference);
|
|
447
|
+
const idx = p.children.indexOf(ref);
|
|
448
|
+
if (idx === -1) p.children.push(c);
|
|
449
|
+
else p.children.splice(idx, 0, c);
|
|
391
450
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
idx =
|
|
451
|
+
removeChild(parent, child) {
|
|
452
|
+
const p = asParent(parent);
|
|
453
|
+
const c = asServer(child);
|
|
454
|
+
const idx = p.children.indexOf(c);
|
|
455
|
+
if (idx !== -1) {
|
|
456
|
+
p.children.splice(idx, 1);
|
|
457
|
+
c.parent = null;
|
|
458
|
+
}
|
|
396
459
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
if (
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
} else {
|
|
415
|
-
itemInstance.graphNode.appendChild(newChild);
|
|
416
|
-
const inst = mountFn(newChild, el);
|
|
417
|
-
nextChildren.push(inst);
|
|
460
|
+
replaceChild(parent, newChild, oldChild) {
|
|
461
|
+
const p = asParent(parent);
|
|
462
|
+
const nc = asServer(newChild);
|
|
463
|
+
const oc = asServer(oldChild);
|
|
464
|
+
const idx = p.children.indexOf(oc);
|
|
465
|
+
if (idx === -1) return;
|
|
466
|
+
this._detach(nc);
|
|
467
|
+
nc.parent = p;
|
|
468
|
+
p.children.splice(idx, 1, nc);
|
|
469
|
+
oc.parent = null;
|
|
470
|
+
}
|
|
471
|
+
_detach(node) {
|
|
472
|
+
if (node.parent !== null) {
|
|
473
|
+
const siblings = node.parent.children;
|
|
474
|
+
const idx = siblings.indexOf(node);
|
|
475
|
+
if (idx !== -1) siblings.splice(idx, 1);
|
|
476
|
+
node.parent = null;
|
|
418
477
|
}
|
|
419
478
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
479
|
+
setAttribute(element, name, value) {
|
|
480
|
+
element.attributes.set(name, value);
|
|
481
|
+
}
|
|
482
|
+
removeAttribute(element, name) {
|
|
483
|
+
element.attributes.delete(name);
|
|
484
|
+
}
|
|
485
|
+
getAttribute(element, name) {
|
|
486
|
+
return element.attributes.get(name) ?? null;
|
|
427
487
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
for (const c of nextChildren) itemInstance.children.push(c);
|
|
431
|
-
for (const c of [...itemInstance.graphNode.children]) {
|
|
432
|
-
itemInstance.graphNode.removeChild(c);
|
|
488
|
+
setProperty(element, name, value) {
|
|
489
|
+
element.properties.set(name, value);
|
|
433
490
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
ctx.dom.insertBefore(parentDom, domNode, referenceNode);
|
|
491
|
+
setTextContent(node, text) {
|
|
492
|
+
const n = asServer(node);
|
|
493
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
494
|
+
const el = n;
|
|
495
|
+
el.children.length = 0;
|
|
496
|
+
const t = new ServerText(text);
|
|
497
|
+
t.parent = el;
|
|
498
|
+
el.children.push(t);
|
|
499
|
+
} else if (n.kind === "text") {
|
|
500
|
+
n.data = text;
|
|
445
501
|
}
|
|
446
|
-
referenceNode = domNode;
|
|
447
502
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
if (!Object.is(oldVal, newVal)) {
|
|
458
|
-
patchNode(ctx, instance.graphNode, key, newVal);
|
|
503
|
+
getTextContent(node) {
|
|
504
|
+
const n = asServer(node);
|
|
505
|
+
if (n.kind === "text") return n.data;
|
|
506
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
507
|
+
let out = "";
|
|
508
|
+
for (const c of n.children) {
|
|
509
|
+
out += this.getTextContent(c) ?? "";
|
|
510
|
+
}
|
|
511
|
+
return out;
|
|
459
512
|
}
|
|
513
|
+
return null;
|
|
460
514
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
// ../renderer/src/mount.ts
|
|
464
|
-
var SKIP_PROP_KEYS = /* @__PURE__ */ new Set([
|
|
465
|
-
"text",
|
|
466
|
-
"label",
|
|
467
|
-
"level",
|
|
468
|
-
"inputType",
|
|
469
|
-
"src",
|
|
470
|
-
"alt",
|
|
471
|
-
"href",
|
|
472
|
-
"external",
|
|
473
|
-
"value",
|
|
474
|
-
"placeholder",
|
|
475
|
-
"disabled",
|
|
476
|
-
"_renderKey",
|
|
477
|
-
"key",
|
|
478
|
-
"name"
|
|
479
|
-
]);
|
|
480
|
-
function mountGraph(ctx) {
|
|
481
|
-
return mountNode(ctx, ctx.graph.root, ctx.container);
|
|
482
|
-
}
|
|
483
|
-
function mountNode(ctx, graphNode, parentDom) {
|
|
484
|
-
const { dom, graph } = ctx;
|
|
485
|
-
const staticHTML = ctx.staticHTML;
|
|
486
|
-
if (staticHTML !== void 0 && dom.createRawHTML !== void 0) {
|
|
487
|
-
const precomputed = staticHTML.get(graphNode.id);
|
|
488
|
-
if (precomputed !== void 0) {
|
|
489
|
-
const raw = dom.createRawHTML(precomputed);
|
|
490
|
-
dom.appendChild(parentDom, raw);
|
|
491
|
-
const instance2 = new NodeInstance(graphNode, raw);
|
|
492
|
-
ctx.instances.set(graphNode.id, instance2);
|
|
493
|
-
return instance2;
|
|
494
|
-
}
|
|
515
|
+
// Server nodes never dispatch events — listeners are a no-op on the server.
|
|
516
|
+
addEventListener() {
|
|
495
517
|
}
|
|
496
|
-
|
|
497
|
-
const instance2 = new NodeInstance(graphNode, parentDom);
|
|
498
|
-
ctx.instances.set(graphNode.id, instance2);
|
|
499
|
-
for (const child of graphNode.children) {
|
|
500
|
-
const childInstance = mountNode(ctx, child, parentDom);
|
|
501
|
-
instance2.addChild(childInstance);
|
|
502
|
-
}
|
|
503
|
-
return instance2;
|
|
518
|
+
removeEventListener() {
|
|
504
519
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
const el2 = dom.createElement("span");
|
|
508
|
-
const textNode = dom.createTextNode(text);
|
|
509
|
-
dom.appendChild(el2, textNode);
|
|
510
|
-
applyNodeProps(ctx, graphNode, el2);
|
|
511
|
-
const instance2 = new NodeInstance(graphNode, el2);
|
|
512
|
-
ctx.instances.set(graphNode.id, instance2);
|
|
513
|
-
wireEvents(dom, graph, graphNode, el2, instance2);
|
|
514
|
-
if (graphNode.stateRefs.length !== 0) {
|
|
515
|
-
wireSignalBindings(ctx, graphNode, instance2, textUpdate(dom, el2, textNode));
|
|
516
|
-
}
|
|
517
|
-
dom.appendChild(parentDom, el2);
|
|
518
|
-
return instance2;
|
|
520
|
+
querySelector() {
|
|
521
|
+
return null;
|
|
519
522
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
const tag2 = `h${level}`;
|
|
523
|
-
const el2 = dom.createElement(tag2);
|
|
524
|
-
const text = String(graphNode.getProp("text") ?? "");
|
|
525
|
-
dom.setTextContent(el2, text);
|
|
526
|
-
applyNodeProps(ctx, graphNode, el2);
|
|
527
|
-
const instance2 = new NodeInstance(graphNode, el2);
|
|
528
|
-
ctx.instances.set(graphNode.id, instance2);
|
|
529
|
-
wireEvents(dom, graph, graphNode, el2, instance2);
|
|
530
|
-
if (graphNode.stateRefs.length !== 0) {
|
|
531
|
-
wireSignalBindings(ctx, graphNode, instance2, headingUpdate(dom, el2));
|
|
532
|
-
}
|
|
533
|
-
dom.appendChild(parentDom, el2);
|
|
534
|
-
return instance2;
|
|
523
|
+
querySelectorAll() {
|
|
524
|
+
return [];
|
|
535
525
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
const inputType = String(graphNode.getProp("inputType") ?? "text");
|
|
539
|
-
dom.setAttribute(el2, "type", inputType);
|
|
540
|
-
const placeholder = graphNode.getProp("placeholder");
|
|
541
|
-
if (placeholder !== void 0) dom.setAttribute(el2, "placeholder", String(placeholder));
|
|
542
|
-
const value = graphNode.getProp("value");
|
|
543
|
-
if (value !== void 0) dom.setProperty(el2, "value", String(value));
|
|
544
|
-
applyNodeProps(ctx, graphNode, el2);
|
|
545
|
-
const instance2 = new NodeInstance(graphNode, el2);
|
|
546
|
-
ctx.instances.set(graphNode.id, instance2);
|
|
547
|
-
wireEvents(dom, graph, graphNode, el2, instance2);
|
|
548
|
-
if (graphNode.stateRefs.length !== 0) {
|
|
549
|
-
wireSignalBindings(ctx, graphNode, instance2, inputUpdate(dom, el2));
|
|
550
|
-
}
|
|
551
|
-
dom.appendChild(parentDom, el2);
|
|
552
|
-
return instance2;
|
|
526
|
+
getElementById() {
|
|
527
|
+
return null;
|
|
553
528
|
}
|
|
554
|
-
|
|
555
|
-
const el2 = dom.createElement("img");
|
|
556
|
-
const src = graphNode.getProp("src");
|
|
557
|
-
const alt = graphNode.getProp("alt");
|
|
558
|
-
if (src !== void 0) dom.setAttribute(el2, "src", String(src));
|
|
559
|
-
if (alt !== void 0) dom.setAttribute(el2, "alt", String(alt));
|
|
560
|
-
const width = graphNode.getProp("width");
|
|
561
|
-
const height = graphNode.getProp("height");
|
|
562
|
-
if (width !== void 0) dom.setAttribute(el2, "width", String(width));
|
|
563
|
-
if (height !== void 0) dom.setAttribute(el2, "height", String(height));
|
|
564
|
-
applyNodeProps(ctx, graphNode, el2);
|
|
565
|
-
const instance2 = new NodeInstance(graphNode, el2);
|
|
566
|
-
ctx.instances.set(graphNode.id, instance2);
|
|
567
|
-
dom.appendChild(parentDom, el2);
|
|
568
|
-
return instance2;
|
|
529
|
+
focus() {
|
|
569
530
|
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
const href = graphNode.getProp("href");
|
|
573
|
-
const label = graphNode.getProp("label");
|
|
574
|
-
const external = graphNode.getProp("external");
|
|
575
|
-
if (href !== void 0) dom.setAttribute(el2, "href", String(href));
|
|
576
|
-
if (label !== void 0) dom.setTextContent(el2, String(label));
|
|
577
|
-
if (external === true) {
|
|
578
|
-
dom.setAttribute(el2, "target", "_blank");
|
|
579
|
-
dom.setAttribute(el2, "rel", "noopener noreferrer");
|
|
580
|
-
}
|
|
581
|
-
applyNodeProps(ctx, graphNode, el2);
|
|
582
|
-
const instance2 = new NodeInstance(graphNode, el2);
|
|
583
|
-
ctx.instances.set(graphNode.id, instance2);
|
|
584
|
-
wireEvents(dom, graph, graphNode, el2, instance2);
|
|
585
|
-
dom.appendChild(parentDom, el2);
|
|
586
|
-
return instance2;
|
|
531
|
+
body() {
|
|
532
|
+
return null;
|
|
587
533
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
534
|
+
activeElement() {
|
|
535
|
+
return null;
|
|
536
|
+
}
|
|
537
|
+
contains(_ancestor, _node) {
|
|
538
|
+
return false;
|
|
539
|
+
}
|
|
540
|
+
matches(_element, _selector) {
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
isElement(node) {
|
|
544
|
+
return asServer(node).kind === "element";
|
|
545
|
+
}
|
|
546
|
+
isTextNode(node) {
|
|
547
|
+
return asServer(node).kind === "text";
|
|
548
|
+
}
|
|
549
|
+
tagName(element) {
|
|
550
|
+
return element.tagName;
|
|
551
|
+
}
|
|
552
|
+
parentNode(node) {
|
|
553
|
+
return asServer(node).parent ?? null;
|
|
554
|
+
}
|
|
555
|
+
nextSibling(node) {
|
|
556
|
+
const n = asServer(node);
|
|
557
|
+
const parent = n.parent;
|
|
558
|
+
if (parent === null) return null;
|
|
559
|
+
const idx = parent.children.indexOf(n);
|
|
560
|
+
if (idx === -1 || idx + 1 >= parent.children.length) return null;
|
|
561
|
+
return parent.children[idx + 1];
|
|
562
|
+
}
|
|
563
|
+
firstChild(node) {
|
|
564
|
+
const n = asServer(node);
|
|
565
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
566
|
+
const el = n;
|
|
567
|
+
return el.children[0] ?? null;
|
|
600
568
|
}
|
|
601
|
-
|
|
602
|
-
return instance2;
|
|
569
|
+
return null;
|
|
603
570
|
}
|
|
604
|
-
|
|
605
|
-
const
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
const instance2 = new NodeInstance(graphNode, el2);
|
|
609
|
-
ctx.instances.set(graphNode.id, instance2);
|
|
610
|
-
for (const child of graphNode.children) {
|
|
611
|
-
const childInstance = mountNode(ctx, child, el2);
|
|
612
|
-
instance2.addChild(childInstance);
|
|
571
|
+
childNodes(node) {
|
|
572
|
+
const n = asServer(node);
|
|
573
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
574
|
+
return n.children;
|
|
613
575
|
}
|
|
614
|
-
|
|
615
|
-
wireReactiveList(ctx, graphNode, instance2, el2);
|
|
616
|
-
return instance2;
|
|
576
|
+
return [];
|
|
617
577
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
dom.setAttribute(el, "data-streetui-key", String(itemKey));
|
|
578
|
+
// ── Server-only ────────────────────────────────────────────────────────────
|
|
579
|
+
/** Serialize a node's children ("inner HTML") to an HTML string. */
|
|
580
|
+
serializeInner(node) {
|
|
581
|
+
const n = asServer(node);
|
|
582
|
+
if (n.kind === "element" || n.kind === "fragment") {
|
|
583
|
+
return serializeChildren(n);
|
|
625
584
|
}
|
|
585
|
+
return "";
|
|
626
586
|
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
wireEvents(dom, graph, graphNode, el, instance);
|
|
631
|
-
}
|
|
632
|
-
for (const child of graphNode.children) {
|
|
633
|
-
const childInstance = mountNode(ctx, child, el);
|
|
634
|
-
instance.addChild(childInstance);
|
|
587
|
+
/** Serialize a node (including itself) to an HTML string. */
|
|
588
|
+
serializeOuter(node) {
|
|
589
|
+
return serializeServerNode(asServer(node));
|
|
635
590
|
}
|
|
636
|
-
|
|
637
|
-
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
// ../dom/src/focus.ts
|
|
594
|
+
var FOCUSABLE_SELECTOR = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
595
|
+
function focusById(dom, root, id) {
|
|
596
|
+
const el = dom.querySelector(root, `[id="${id}"]`);
|
|
597
|
+
if (el === null) return false;
|
|
598
|
+
dom.focus(el);
|
|
599
|
+
return true;
|
|
638
600
|
}
|
|
639
|
-
function
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
applyProp(dom, el, propKey, value);
|
|
645
|
-
}
|
|
646
|
-
};
|
|
601
|
+
function focusFirst(dom, container, selector = FOCUSABLE_SELECTOR) {
|
|
602
|
+
const el = dom.querySelector(container, selector);
|
|
603
|
+
if (el === null) return false;
|
|
604
|
+
dom.focus(el);
|
|
605
|
+
return true;
|
|
647
606
|
}
|
|
648
|
-
function
|
|
649
|
-
return (
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
} else {
|
|
653
|
-
applyProp(dom, el, propKey, value);
|
|
654
|
-
}
|
|
655
|
-
};
|
|
607
|
+
function getFocusable(dom, container, selector = FOCUSABLE_SELECTOR) {
|
|
608
|
+
return Array.from(dom.querySelectorAll(container, selector)).filter(
|
|
609
|
+
(el) => dom.matches(el, selector)
|
|
610
|
+
);
|
|
656
611
|
}
|
|
657
|
-
function
|
|
658
|
-
return (
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
612
|
+
function saveFocus(dom) {
|
|
613
|
+
return dom.activeElement();
|
|
614
|
+
}
|
|
615
|
+
function restoreFocus(dom, saved) {
|
|
616
|
+
if (saved !== null) dom.focus(saved);
|
|
617
|
+
}
|
|
618
|
+
function focusInitial(dom, container, initialFocusId) {
|
|
619
|
+
if (initialFocusId !== void 0 && focusById(dom, container, initialFocusId)) return;
|
|
620
|
+
focusFirst(dom, container);
|
|
621
|
+
}
|
|
622
|
+
function trapFocus(dom, container) {
|
|
623
|
+
const onKeydown = (event) => {
|
|
624
|
+
if (event.key !== "Tab") return;
|
|
625
|
+
const items = getFocusable(dom, container);
|
|
626
|
+
if (items.length === 0) {
|
|
627
|
+
event.preventDefault();
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
const first = items[0];
|
|
631
|
+
const last = items[items.length - 1];
|
|
632
|
+
const active = dom.activeElement();
|
|
633
|
+
if (active === null || !dom.contains(container, active)) {
|
|
634
|
+
event.preventDefault();
|
|
635
|
+
dom.focus(first);
|
|
636
|
+
} else if (event.shiftKey && active === first) {
|
|
637
|
+
event.preventDefault();
|
|
638
|
+
dom.focus(last);
|
|
639
|
+
} else if (!event.shiftKey && active === last) {
|
|
640
|
+
event.preventDefault();
|
|
641
|
+
dom.focus(first);
|
|
663
642
|
}
|
|
664
643
|
};
|
|
644
|
+
dom.addEventListener(container, "keydown", onKeydown);
|
|
645
|
+
return () => dom.removeEventListener(container, "keydown", onKeydown);
|
|
665
646
|
}
|
|
666
|
-
function
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
dom.removeAttribute(el, "disabled");
|
|
675
|
-
}
|
|
676
|
-
} else {
|
|
677
|
-
applyProp(dom, el, propKey, value);
|
|
647
|
+
function containFocus(dom, container) {
|
|
648
|
+
const body = dom.body();
|
|
649
|
+
if (body === null) return () => {
|
|
650
|
+
};
|
|
651
|
+
const onFocusIn = (event) => {
|
|
652
|
+
const target = event.target;
|
|
653
|
+
if (target !== null && !dom.contains(container, target)) {
|
|
654
|
+
focusFirst(dom, container);
|
|
678
655
|
}
|
|
679
656
|
};
|
|
657
|
+
dom.addEventListener(body, "focusin", onFocusIn);
|
|
658
|
+
return () => dom.removeEventListener(body, "focusin", onFocusIn);
|
|
680
659
|
}
|
|
681
|
-
function
|
|
682
|
-
const
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
}
|
|
660
|
+
function onEscape(dom, target, handler) {
|
|
661
|
+
const onKeydown = (event) => {
|
|
662
|
+
if (event.key === "Escape") handler();
|
|
663
|
+
};
|
|
664
|
+
dom.addEventListener(target, "keydown", onKeydown);
|
|
665
|
+
return () => dom.removeEventListener(target, "keydown", onKeydown);
|
|
688
666
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
667
|
+
|
|
668
|
+
// ../renderer/src/tag-map.ts
|
|
669
|
+
var TAG_MAP = {
|
|
670
|
+
application: "div",
|
|
671
|
+
page: "div",
|
|
672
|
+
section: "section",
|
|
673
|
+
container: "div",
|
|
674
|
+
heading: "h1",
|
|
675
|
+
text: "span",
|
|
676
|
+
button: "button",
|
|
677
|
+
input: "input",
|
|
678
|
+
form: "form",
|
|
679
|
+
list: "ul",
|
|
680
|
+
"list-item": "li",
|
|
681
|
+
image: "img",
|
|
682
|
+
link: "a",
|
|
683
|
+
component: "div",
|
|
684
|
+
slot: "div",
|
|
685
|
+
fragment: "div",
|
|
686
|
+
"reactive-list": "ul",
|
|
687
|
+
// A portal renders as a neutral inline anchor <div> at its declaration site;
|
|
688
|
+
// its children are relocated to a document.body container on the browser
|
|
689
|
+
// (see the portal branch in mount.ts). On the server (no body) it renders
|
|
690
|
+
// inline, so the anchor tag is what SSR/hydration positionally match on.
|
|
691
|
+
portal: "div"
|
|
692
|
+
};
|
|
693
|
+
function resolveTag(type) {
|
|
694
|
+
return TAG_MAP[type] ?? "div";
|
|
700
695
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
696
|
+
|
|
697
|
+
// ../renderer/src/patch.ts
|
|
698
|
+
function patchNode(ctx, graphNode, propKey, newValue) {
|
|
699
|
+
const instance = ctx.instances.get(graphNode.id);
|
|
700
|
+
if (instance === void 0) return;
|
|
701
|
+
const domNode = instance.domNode;
|
|
702
|
+
if (!ctx.dom.isElement(domNode)) return;
|
|
703
|
+
const oldValue = graphNode.getProp(propKey);
|
|
704
|
+
switch (propKey) {
|
|
705
|
+
case "text":
|
|
706
|
+
if (!Object.is(oldValue, newValue)) {
|
|
707
|
+
ctx.dom.setTextContent(domNode, String(newValue ?? ""));
|
|
708
|
+
graphNode.setProp("text", String(newValue ?? ""));
|
|
709
|
+
}
|
|
710
|
+
break;
|
|
711
|
+
case "label":
|
|
712
|
+
if (!Object.is(oldValue, newValue)) {
|
|
713
|
+
ctx.dom.setTextContent(domNode, String(newValue ?? ""));
|
|
714
|
+
graphNode.setProp("label", String(newValue ?? ""));
|
|
715
|
+
}
|
|
716
|
+
break;
|
|
717
|
+
case "disabled":
|
|
718
|
+
if (newValue === true) {
|
|
719
|
+
ctx.dom.setAttribute(domNode, "disabled", "");
|
|
712
720
|
} else {
|
|
713
|
-
|
|
721
|
+
ctx.dom.removeAttribute(domNode, "disabled");
|
|
714
722
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
);
|
|
728
|
-
listInstance.children.length = 0;
|
|
729
|
-
for (const inst of result.instances) listInstance.children.push(inst);
|
|
730
|
-
for (const removed of result.removed) {
|
|
731
|
-
forgetInstance(ctx, removed);
|
|
732
|
-
ctx.graph.detachNode(removed.graphNode);
|
|
733
|
-
}
|
|
734
|
-
const adopted = new Set(result.instances.map((i) => i.graphNode));
|
|
735
|
-
for (const node of result.built ?? []) {
|
|
736
|
-
if (!adopted.has(node)) ctx.graph.detachNode(node);
|
|
737
|
-
}
|
|
738
|
-
for (const child of [...listNode.children]) listNode.removeChild(child);
|
|
739
|
-
for (const inst of result.instances) listNode.appendChild(inst.graphNode);
|
|
740
|
-
}
|
|
741
|
-
function reconcileReactiveList(ctx, listNode, listInstance, listEl, newNodes) {
|
|
742
|
-
const oldInstances = [...listInstance.children];
|
|
743
|
-
const result = reconcileChildren(
|
|
744
|
-
ctx,
|
|
745
|
-
listEl,
|
|
746
|
-
oldInstances,
|
|
747
|
-
newNodes,
|
|
748
|
-
(node, parent) => mountNode(ctx, node, parent)
|
|
749
|
-
);
|
|
750
|
-
listInstance.children.length = 0;
|
|
751
|
-
for (const inst of result.instances) listInstance.children.push(inst);
|
|
752
|
-
for (const removed of result.removed) {
|
|
753
|
-
forgetInstance(ctx, removed);
|
|
754
|
-
ctx.graph.detachNode(removed.graphNode);
|
|
755
|
-
}
|
|
756
|
-
const adopted = new Set(result.instances.map((i) => i.graphNode));
|
|
757
|
-
for (const built of newNodes) {
|
|
758
|
-
if (!adopted.has(built)) ctx.graph.detachNode(built);
|
|
759
|
-
}
|
|
760
|
-
for (const child of [...listNode.children]) listNode.removeChild(child);
|
|
761
|
-
for (const inst of result.instances) listNode.appendChild(inst.graphNode);
|
|
762
|
-
}
|
|
763
|
-
function forgetInstance(ctx, instance) {
|
|
764
|
-
ctx.instances.delete(instance.graphNode.id);
|
|
765
|
-
for (const child of instance.children) forgetInstance(ctx, child);
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
// ../dom/src/server-node.ts
|
|
769
|
-
var ServerStyle = class {
|
|
770
|
-
declarations = /* @__PURE__ */ new Map();
|
|
771
|
-
setProperty(name, value) {
|
|
772
|
-
this.declarations.set(name, value);
|
|
773
|
-
}
|
|
774
|
-
get isEmpty() {
|
|
775
|
-
return this.declarations.size === 0;
|
|
776
|
-
}
|
|
777
|
-
toCss() {
|
|
778
|
-
return [...this.declarations.entries()].map(([k, v]) => `${k}: ${v}`).join("; ");
|
|
779
|
-
}
|
|
780
|
-
};
|
|
781
|
-
var ServerText = class {
|
|
782
|
-
kind = "text";
|
|
783
|
-
parent = null;
|
|
784
|
-
data;
|
|
785
|
-
constructor(data) {
|
|
786
|
-
this.data = data;
|
|
787
|
-
}
|
|
788
|
-
};
|
|
789
|
-
var ServerComment = class {
|
|
790
|
-
kind = "comment";
|
|
791
|
-
parent = null;
|
|
792
|
-
data;
|
|
793
|
-
constructor(data) {
|
|
794
|
-
this.data = data;
|
|
795
|
-
}
|
|
796
|
-
};
|
|
797
|
-
var ServerFragment = class {
|
|
798
|
-
kind = "fragment";
|
|
799
|
-
parent = null;
|
|
800
|
-
children = [];
|
|
801
|
-
};
|
|
802
|
-
var ServerRawHTML = class {
|
|
803
|
-
kind = "raw";
|
|
804
|
-
parent = null;
|
|
805
|
-
html;
|
|
806
|
-
constructor(html) {
|
|
807
|
-
this.html = html;
|
|
808
|
-
}
|
|
809
|
-
};
|
|
810
|
-
var ServerElement = class {
|
|
811
|
-
kind = "element";
|
|
812
|
-
parent = null;
|
|
813
|
-
tagName;
|
|
814
|
-
attributes = /* @__PURE__ */ new Map();
|
|
815
|
-
children = [];
|
|
816
|
-
// Lazily-allocated stores. On the 10k-row SSR corpus ~0% of elements carry JS
|
|
817
|
-
// properties or inline styles (measured, §5: 1 of 80,029 elements uses
|
|
818
|
-
// `properties`, 0 use `style`), so eagerly allocating a `properties` Map plus
|
|
819
|
-
// a `ServerStyle` (which itself holds a Map) per element wasted ~240k
|
|
820
|
-
// allocations per /users render — all in the dominant mount phase. These are
|
|
821
|
-
// created on first WRITE via the `properties`/`style` getters; the serializer
|
|
822
|
-
// reads the raw `_properties`/`_style` fields so a READ never forces an
|
|
823
|
-
// allocation. Output is byte-identical: an unset store previously serialized
|
|
824
|
-
// to nothing (empty `properties.has(...)` / `style.isEmpty`), and a null store
|
|
825
|
-
// is skipped the same way.
|
|
826
|
-
_properties = null;
|
|
827
|
-
_style = null;
|
|
828
|
-
constructor(tagName) {
|
|
829
|
-
this.tagName = tagName.toLowerCase();
|
|
723
|
+
graphNode.setProp("disabled", Boolean(newValue));
|
|
724
|
+
break;
|
|
725
|
+
case "value":
|
|
726
|
+
if (!Object.is(oldValue, newValue)) {
|
|
727
|
+
ctx.dom.setProperty(domNode, "value", String(newValue ?? ""));
|
|
728
|
+
graphNode.setProp("value", String(newValue ?? ""));
|
|
729
|
+
}
|
|
730
|
+
break;
|
|
731
|
+
default:
|
|
732
|
+
patchProp(ctx.dom, domNode, propKey, oldValue, newValue);
|
|
733
|
+
graphNode.setProp(propKey, newValue);
|
|
734
|
+
break;
|
|
830
735
|
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// ../renderer/src/reconciliation.ts
|
|
739
|
+
function reconcileChildren(ctx, parentDom, oldInstances, newNodes, mountFn) {
|
|
740
|
+
const oldByKey = /* @__PURE__ */ new Map();
|
|
741
|
+
for (const inst of oldInstances) {
|
|
742
|
+
const key = inst.graphNode.key ?? inst.graphNode.id;
|
|
743
|
+
oldByKey.set(key, inst);
|
|
834
744
|
}
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
745
|
+
const newInstances = [];
|
|
746
|
+
const usedKeys = /* @__PURE__ */ new Set();
|
|
747
|
+
for (const newNode of newNodes) {
|
|
748
|
+
const key = newNode.key ?? newNode.id;
|
|
749
|
+
const existing = oldByKey.get(key);
|
|
750
|
+
if (existing !== void 0) {
|
|
751
|
+
usedKeys.add(key);
|
|
752
|
+
const oldSig = existing.graphNode.getProp("_sig");
|
|
753
|
+
const newSig = newNode.getProp("_sig");
|
|
754
|
+
patchExistingInstance(ctx, existing, newNode);
|
|
755
|
+
if (!Object.is(oldSig, newSig)) {
|
|
756
|
+
reconcileItemChildren(ctx, existing, newNode, mountFn);
|
|
757
|
+
}
|
|
758
|
+
newInstances.push(existing);
|
|
759
|
+
} else {
|
|
760
|
+
const inst = mountFn(newNode, parentDom);
|
|
761
|
+
newInstances.push(inst);
|
|
762
|
+
}
|
|
838
763
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
"col",
|
|
845
|
-
"embed",
|
|
846
|
-
"hr",
|
|
847
|
-
"img",
|
|
848
|
-
"input",
|
|
849
|
-
"link",
|
|
850
|
-
"meta",
|
|
851
|
-
"param",
|
|
852
|
-
"source",
|
|
853
|
-
"track",
|
|
854
|
-
"wbr"
|
|
855
|
-
]);
|
|
856
|
-
var SERIALIZED_PROPERTIES = {
|
|
857
|
-
value: "attr",
|
|
858
|
-
checked: "boolean",
|
|
859
|
-
selected: "boolean"
|
|
860
|
-
};
|
|
861
|
-
var SERIALIZED_PROPERTY_ENTRIES = Object.entries(SERIALIZED_PROPERTIES);
|
|
862
|
-
var TEXT_SPECIAL = /[&<>]/;
|
|
863
|
-
var ATTR_SPECIAL = /[&<>"]/;
|
|
864
|
-
function escapeHtmlText(value) {
|
|
865
|
-
if (!TEXT_SPECIAL.test(value)) return value;
|
|
866
|
-
let out = "";
|
|
867
|
-
let last = 0;
|
|
868
|
-
for (let i = 0; i < value.length; i++) {
|
|
869
|
-
let esc;
|
|
870
|
-
switch (value.charCodeAt(i)) {
|
|
871
|
-
case 38:
|
|
872
|
-
esc = "&";
|
|
873
|
-
break;
|
|
874
|
-
// &
|
|
875
|
-
case 60:
|
|
876
|
-
esc = "<";
|
|
877
|
-
break;
|
|
878
|
-
// <
|
|
879
|
-
case 62:
|
|
880
|
-
esc = ">";
|
|
881
|
-
break;
|
|
882
|
-
// >
|
|
883
|
-
default:
|
|
884
|
-
continue;
|
|
764
|
+
const removed = [];
|
|
765
|
+
for (const inst of oldInstances) {
|
|
766
|
+
const key = inst.graphNode.key ?? inst.graphNode.id;
|
|
767
|
+
if (!usedKeys.has(key)) {
|
|
768
|
+
removed.push(inst);
|
|
885
769
|
}
|
|
886
|
-
out += value.slice(last, i) + esc;
|
|
887
|
-
last = i + 1;
|
|
888
770
|
}
|
|
889
|
-
|
|
771
|
+
for (const inst of removed) {
|
|
772
|
+
const parent = ctx.dom.parentNode(inst.domNode);
|
|
773
|
+
if (parent !== null) {
|
|
774
|
+
ctx.dom.removeChild(parent, inst.domNode);
|
|
775
|
+
}
|
|
776
|
+
inst.dispose();
|
|
777
|
+
}
|
|
778
|
+
reorderDom(ctx, parentDom, newInstances);
|
|
779
|
+
return { instances: newInstances, removed };
|
|
890
780
|
}
|
|
891
|
-
function
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
781
|
+
function reconcileChildrenByPlan(ctx, parentDom, oldInstances, plan, mountFn) {
|
|
782
|
+
const oldByKey = /* @__PURE__ */ new Map();
|
|
783
|
+
for (const inst of oldInstances) {
|
|
784
|
+
oldByKey.set(inst.graphNode.key ?? inst.graphNode.id, inst);
|
|
785
|
+
}
|
|
786
|
+
const newInstances = [];
|
|
787
|
+
const usedKeys = /* @__PURE__ */ new Set();
|
|
788
|
+
const built = [];
|
|
789
|
+
for (const entry of plan) {
|
|
790
|
+
const existing = oldByKey.get(entry.key);
|
|
791
|
+
if (existing !== void 0) {
|
|
792
|
+
usedKeys.add(entry.key);
|
|
793
|
+
const oldItem = existing.graphNode.getProp("_item");
|
|
794
|
+
if (!Object.is(oldItem, entry.item)) {
|
|
795
|
+
const newSig = entry.sig();
|
|
796
|
+
const oldSig = existing.graphNode.getProp("_sig");
|
|
797
|
+
if (!Object.is(oldSig, newSig)) {
|
|
798
|
+
const freshNode = entry.build();
|
|
799
|
+
built.push(freshNode);
|
|
800
|
+
patchExistingInstance(ctx, existing, freshNode);
|
|
801
|
+
reconcileItemChildren(ctx, existing, freshNode, mountFn);
|
|
802
|
+
existing.graphNode.setProp("_sig", newSig);
|
|
803
|
+
}
|
|
804
|
+
existing.graphNode.setProp("_item", entry.item);
|
|
805
|
+
}
|
|
806
|
+
newInstances.push(existing);
|
|
807
|
+
} else {
|
|
808
|
+
const freshNode = entry.build();
|
|
809
|
+
built.push(freshNode);
|
|
810
|
+
const inst = mountFn(freshNode, parentDom);
|
|
811
|
+
newInstances.push(inst);
|
|
916
812
|
}
|
|
917
|
-
out += value.slice(last, i) + esc;
|
|
918
|
-
last = i + 1;
|
|
919
813
|
}
|
|
920
|
-
|
|
814
|
+
const removed = [];
|
|
815
|
+
for (const inst of oldInstances) {
|
|
816
|
+
const key = inst.graphNode.key ?? inst.graphNode.id;
|
|
817
|
+
if (!usedKeys.has(key)) removed.push(inst);
|
|
818
|
+
}
|
|
819
|
+
for (const inst of removed) {
|
|
820
|
+
const parent = ctx.dom.parentNode(inst.domNode);
|
|
821
|
+
if (parent !== null) ctx.dom.removeChild(parent, inst.domNode);
|
|
822
|
+
inst.dispose();
|
|
823
|
+
}
|
|
824
|
+
reorderDomMinimal(ctx, parentDom, oldInstances, newInstances);
|
|
825
|
+
return { instances: newInstances, removed, built };
|
|
921
826
|
}
|
|
922
|
-
function
|
|
923
|
-
const
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
827
|
+
function reorderDomMinimal(ctx, parentDom, oldInstances, newInstances) {
|
|
828
|
+
const n = newInstances.length;
|
|
829
|
+
if (n === 0) return;
|
|
830
|
+
const oldIndexOf = /* @__PURE__ */ new Map();
|
|
831
|
+
for (let i = 0; i < oldInstances.length; i++) oldIndexOf.set(oldInstances[i], i);
|
|
832
|
+
const source = new Array(n);
|
|
833
|
+
let moved = false;
|
|
834
|
+
let lastSeen = -1;
|
|
835
|
+
for (let i = 0; i < n; i++) {
|
|
836
|
+
const oi = oldIndexOf.get(newInstances[i]);
|
|
837
|
+
if (oi === void 0) {
|
|
838
|
+
source[i] = -1;
|
|
839
|
+
moved = true;
|
|
927
840
|
} else {
|
|
928
|
-
|
|
841
|
+
source[i] = oi;
|
|
842
|
+
if (oi < lastSeen) moved = true;
|
|
843
|
+
else lastSeen = oi;
|
|
929
844
|
}
|
|
930
845
|
}
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
if (
|
|
938
|
-
|
|
939
|
-
} else {
|
|
940
|
-
if (raw !== void 0 && raw !== null) {
|
|
941
|
-
parts.push(` ${name}="${escapeHtmlAttr(String(raw))}"`);
|
|
942
|
-
}
|
|
846
|
+
if (!moved) return;
|
|
847
|
+
const keep = longestIncreasingSubsequence(source);
|
|
848
|
+
let refNode = null;
|
|
849
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
850
|
+
const domNode = newInstances[i].domNode;
|
|
851
|
+
if (source[i] === -1 || !keep.has(i)) {
|
|
852
|
+
if (ctx.dom.nextSibling(domNode) !== refNode) {
|
|
853
|
+
ctx.dom.insertBefore(parentDom, domNode, refNode);
|
|
943
854
|
}
|
|
944
855
|
}
|
|
856
|
+
refNode = domNode;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
function longestIncreasingSubsequence(source) {
|
|
860
|
+
const keep = /* @__PURE__ */ new Set();
|
|
861
|
+
const n = source.length;
|
|
862
|
+
const tails = [];
|
|
863
|
+
const prev = new Array(n).fill(-1);
|
|
864
|
+
for (let i = 0; i < n; i++) {
|
|
865
|
+
const v = source[i];
|
|
866
|
+
if (v < 0) continue;
|
|
867
|
+
let lo = 0;
|
|
868
|
+
let hi = tails.length;
|
|
869
|
+
while (lo < hi) {
|
|
870
|
+
const mid = lo + hi >> 1;
|
|
871
|
+
if (source[tails[mid]] < v) lo = mid + 1;
|
|
872
|
+
else hi = mid;
|
|
873
|
+
}
|
|
874
|
+
if (lo > 0) prev[i] = tails[lo - 1];
|
|
875
|
+
tails[lo] = i;
|
|
876
|
+
}
|
|
877
|
+
let idx = tails.length > 0 ? tails[tails.length - 1] : -1;
|
|
878
|
+
while (idx >= 0) {
|
|
879
|
+
keep.add(idx);
|
|
880
|
+
idx = prev[idx];
|
|
881
|
+
}
|
|
882
|
+
return keep;
|
|
883
|
+
}
|
|
884
|
+
function reconcileItemChildren(ctx, itemInstance, newItemNode, mountFn) {
|
|
885
|
+
const el = itemInstance.domNode;
|
|
886
|
+
if (!ctx.dom.isElement(el)) return;
|
|
887
|
+
const oldChildren = [...itemInstance.children];
|
|
888
|
+
const newChildNodes = [...newItemNode.children];
|
|
889
|
+
const nextChildren = [];
|
|
890
|
+
const kept = /* @__PURE__ */ new Set();
|
|
891
|
+
for (let i = 0; i < newChildNodes.length; i++) {
|
|
892
|
+
const newChild = newChildNodes[i];
|
|
893
|
+
const oldChild = oldChildren[i];
|
|
894
|
+
if (oldChild !== void 0 && oldChild.graphNode.type === newChild.type) {
|
|
895
|
+
patchExistingInstance(ctx, oldChild, newChild);
|
|
896
|
+
reconcileItemChildren(ctx, oldChild, newChild, mountFn);
|
|
897
|
+
nextChildren.push(oldChild);
|
|
898
|
+
kept.add(oldChild);
|
|
899
|
+
} else {
|
|
900
|
+
itemInstance.graphNode.appendChild(newChild);
|
|
901
|
+
const inst = mountFn(newChild, el);
|
|
902
|
+
nextChildren.push(inst);
|
|
903
|
+
}
|
|
945
904
|
}
|
|
946
|
-
const
|
|
947
|
-
|
|
948
|
-
|
|
905
|
+
for (const old of oldChildren) {
|
|
906
|
+
if (kept.has(old)) continue;
|
|
907
|
+
const parent = ctx.dom.parentNode(old.domNode);
|
|
908
|
+
if (parent !== null) ctx.dom.removeChild(parent, old.domNode);
|
|
909
|
+
old.dispose();
|
|
910
|
+
forgetInstanceTree(ctx, old);
|
|
911
|
+
ctx.graph.detachNode(old.graphNode);
|
|
949
912
|
}
|
|
950
|
-
|
|
913
|
+
reorderDom(ctx, el, nextChildren);
|
|
914
|
+
itemInstance.children.length = 0;
|
|
915
|
+
for (const c of nextChildren) itemInstance.children.push(c);
|
|
916
|
+
for (const c of [...itemInstance.graphNode.children]) {
|
|
917
|
+
itemInstance.graphNode.removeChild(c);
|
|
918
|
+
}
|
|
919
|
+
for (const c of nextChildren) itemInstance.graphNode.appendChild(c.graphNode);
|
|
951
920
|
}
|
|
952
|
-
function
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
return node.html;
|
|
962
|
-
case "element": {
|
|
963
|
-
const el = node;
|
|
964
|
-
const tag = el.tagName;
|
|
965
|
-
const attrs = serializeAttributes(el);
|
|
966
|
-
if (VOID_ELEMENTS.has(tag)) {
|
|
967
|
-
return `<${tag}${attrs}>`;
|
|
968
|
-
}
|
|
969
|
-
return `<${tag}${attrs}>${serializeChildren(el)}</${tag}>`;
|
|
921
|
+
function reorderDom(ctx, parentDom, instances) {
|
|
922
|
+
let referenceNode = null;
|
|
923
|
+
for (let i = instances.length - 1; i >= 0; i--) {
|
|
924
|
+
const inst = instances[i];
|
|
925
|
+
if (inst === void 0) continue;
|
|
926
|
+
const domNode = inst.domNode;
|
|
927
|
+
const currentNext = ctx.dom.nextSibling(domNode);
|
|
928
|
+
if (currentNext !== referenceNode) {
|
|
929
|
+
ctx.dom.insertBefore(parentDom, domNode, referenceNode);
|
|
970
930
|
}
|
|
931
|
+
referenceNode = domNode;
|
|
971
932
|
}
|
|
972
933
|
}
|
|
973
|
-
function
|
|
974
|
-
|
|
975
|
-
for (const child of
|
|
976
|
-
|
|
934
|
+
function forgetInstanceTree(ctx, instance) {
|
|
935
|
+
ctx.instances.delete(instance.graphNode.id);
|
|
936
|
+
for (const child of instance.children) forgetInstanceTree(ctx, child);
|
|
937
|
+
}
|
|
938
|
+
function patchExistingInstance(ctx, instance, newNode) {
|
|
939
|
+
const oldNode = instance.graphNode;
|
|
940
|
+
for (const [key, newVal] of Object.entries(newNode.props)) {
|
|
941
|
+
const oldVal = oldNode.getProp(key);
|
|
942
|
+
if (!Object.is(oldVal, newVal)) {
|
|
943
|
+
patchNode(ctx, instance.graphNode, key, newVal);
|
|
944
|
+
}
|
|
977
945
|
}
|
|
978
|
-
return out;
|
|
979
946
|
}
|
|
980
947
|
|
|
981
|
-
// ../
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
948
|
+
// ../renderer/src/mount.ts
|
|
949
|
+
var SKIP_PROP_KEYS = /* @__PURE__ */ new Set([
|
|
950
|
+
"text",
|
|
951
|
+
"label",
|
|
952
|
+
"level",
|
|
953
|
+
"inputType",
|
|
954
|
+
"src",
|
|
955
|
+
"alt",
|
|
956
|
+
"href",
|
|
957
|
+
"external",
|
|
958
|
+
"value",
|
|
959
|
+
"placeholder",
|
|
960
|
+
"disabled",
|
|
961
|
+
"_renderKey",
|
|
962
|
+
"key",
|
|
963
|
+
"name"
|
|
964
|
+
]);
|
|
965
|
+
function mountGraph(ctx) {
|
|
966
|
+
return mountNode(ctx, ctx.graph.root, ctx.container);
|
|
987
967
|
}
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
968
|
+
function mountNode(ctx, graphNode, parentDom) {
|
|
969
|
+
const { dom, graph } = ctx;
|
|
970
|
+
const staticHTML = ctx.staticHTML;
|
|
971
|
+
if (staticHTML !== void 0 && dom.createRawHTML !== void 0) {
|
|
972
|
+
const precomputed = staticHTML.get(graphNode.id);
|
|
973
|
+
if (precomputed !== void 0) {
|
|
974
|
+
const raw = dom.createRawHTML(precomputed);
|
|
975
|
+
dom.appendChild(parentDom, raw);
|
|
976
|
+
const instance2 = new NodeInstance(graphNode, raw);
|
|
977
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
978
|
+
return instance2;
|
|
979
|
+
}
|
|
997
980
|
}
|
|
998
|
-
|
|
999
|
-
|
|
981
|
+
if (graphNode.type === "application") {
|
|
982
|
+
const instance2 = new NodeInstance(graphNode, parentDom);
|
|
983
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
984
|
+
for (const child of graphNode.children) {
|
|
985
|
+
const childInstance = mountNode(ctx, child, parentDom);
|
|
986
|
+
instance2.addChild(childInstance);
|
|
987
|
+
}
|
|
988
|
+
return instance2;
|
|
1000
989
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
990
|
+
if (graphNode.type === "text") {
|
|
991
|
+
const text = String(graphNode.getProp("text") ?? "");
|
|
992
|
+
const el2 = dom.createElement("span");
|
|
993
|
+
const textNode = dom.createTextNode(text);
|
|
994
|
+
dom.appendChild(el2, textNode);
|
|
995
|
+
applyNodeProps(ctx, graphNode, el2);
|
|
996
|
+
const instance2 = new NodeInstance(graphNode, el2);
|
|
997
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
998
|
+
wireEvents(dom, graph, graphNode, el2, instance2);
|
|
999
|
+
if (graphNode.stateRefs.length !== 0) {
|
|
1000
|
+
wireSignalBindings(ctx, graphNode, instance2, textUpdate(dom, el2, textNode));
|
|
1001
|
+
}
|
|
1002
|
+
dom.appendChild(parentDom, el2);
|
|
1003
|
+
return instance2;
|
|
1009
1004
|
}
|
|
1010
|
-
|
|
1011
|
-
const
|
|
1012
|
-
const
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1005
|
+
if (graphNode.type === "heading") {
|
|
1006
|
+
const level = graphNode.getProp("level") ?? 1;
|
|
1007
|
+
const tag2 = `h${level}`;
|
|
1008
|
+
const el2 = dom.createElement(tag2);
|
|
1009
|
+
const text = String(graphNode.getProp("text") ?? "");
|
|
1010
|
+
dom.setTextContent(el2, text);
|
|
1011
|
+
applyNodeProps(ctx, graphNode, el2);
|
|
1012
|
+
const instance2 = new NodeInstance(graphNode, el2);
|
|
1013
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
1014
|
+
wireEvents(dom, graph, graphNode, el2, instance2);
|
|
1015
|
+
if (graphNode.stateRefs.length !== 0) {
|
|
1016
|
+
wireSignalBindings(ctx, graphNode, instance2, headingUpdate(dom, el2));
|
|
1017
|
+
}
|
|
1018
|
+
dom.appendChild(parentDom, el2);
|
|
1019
|
+
return instance2;
|
|
1016
1020
|
}
|
|
1017
|
-
|
|
1018
|
-
const
|
|
1019
|
-
const
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
if (
|
|
1023
|
-
|
|
1024
|
-
|
|
1021
|
+
if (graphNode.type === "input") {
|
|
1022
|
+
const el2 = dom.createElement("input");
|
|
1023
|
+
const inputType = String(graphNode.getProp("inputType") ?? "text");
|
|
1024
|
+
dom.setAttribute(el2, "type", inputType);
|
|
1025
|
+
const placeholder = graphNode.getProp("placeholder");
|
|
1026
|
+
if (placeholder !== void 0) dom.setAttribute(el2, "placeholder", String(placeholder));
|
|
1027
|
+
const value = graphNode.getProp("value");
|
|
1028
|
+
if (value !== void 0) dom.setProperty(el2, "value", String(value));
|
|
1029
|
+
applyNodeProps(ctx, graphNode, el2);
|
|
1030
|
+
const instance2 = new NodeInstance(graphNode, el2);
|
|
1031
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
1032
|
+
wireEvents(dom, graph, graphNode, el2, instance2);
|
|
1033
|
+
if (graphNode.stateRefs.length !== 0) {
|
|
1034
|
+
wireSignalBindings(ctx, graphNode, instance2, inputUpdate(dom, el2));
|
|
1025
1035
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
if (idx === -1) p.children.push(c);
|
|
1029
|
-
else p.children.splice(idx, 0, c);
|
|
1036
|
+
dom.appendChild(parentDom, el2);
|
|
1037
|
+
return instance2;
|
|
1030
1038
|
}
|
|
1031
|
-
|
|
1032
|
-
const
|
|
1033
|
-
const
|
|
1034
|
-
const
|
|
1035
|
-
if (
|
|
1036
|
-
|
|
1037
|
-
|
|
1039
|
+
if (graphNode.type === "image") {
|
|
1040
|
+
const el2 = dom.createElement("img");
|
|
1041
|
+
const src = graphNode.getProp("src");
|
|
1042
|
+
const alt = graphNode.getProp("alt");
|
|
1043
|
+
if (src !== void 0) dom.setAttribute(el2, "src", String(src));
|
|
1044
|
+
if (alt !== void 0) dom.setAttribute(el2, "alt", String(alt));
|
|
1045
|
+
const width = graphNode.getProp("width");
|
|
1046
|
+
const height = graphNode.getProp("height");
|
|
1047
|
+
if (width !== void 0) dom.setAttribute(el2, "width", String(width));
|
|
1048
|
+
if (height !== void 0) dom.setAttribute(el2, "height", String(height));
|
|
1049
|
+
applyNodeProps(ctx, graphNode, el2);
|
|
1050
|
+
const instance2 = new NodeInstance(graphNode, el2);
|
|
1051
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
1052
|
+
dom.appendChild(parentDom, el2);
|
|
1053
|
+
return instance2;
|
|
1054
|
+
}
|
|
1055
|
+
if (graphNode.type === "link") {
|
|
1056
|
+
const el2 = dom.createElement("a");
|
|
1057
|
+
const href = graphNode.getProp("href");
|
|
1058
|
+
const label = graphNode.getProp("label");
|
|
1059
|
+
const external = graphNode.getProp("external");
|
|
1060
|
+
if (href !== void 0) dom.setAttribute(el2, "href", String(href));
|
|
1061
|
+
if (label !== void 0) dom.setTextContent(el2, String(label));
|
|
1062
|
+
if (external === true) {
|
|
1063
|
+
dom.setAttribute(el2, "target", "_blank");
|
|
1064
|
+
dom.setAttribute(el2, "rel", "noopener noreferrer");
|
|
1038
1065
|
}
|
|
1066
|
+
applyNodeProps(ctx, graphNode, el2);
|
|
1067
|
+
const instance2 = new NodeInstance(graphNode, el2);
|
|
1068
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
1069
|
+
wireEvents(dom, graph, graphNode, el2, instance2);
|
|
1070
|
+
dom.appendChild(parentDom, el2);
|
|
1071
|
+
return instance2;
|
|
1039
1072
|
}
|
|
1040
|
-
|
|
1041
|
-
const
|
|
1042
|
-
const
|
|
1043
|
-
|
|
1044
|
-
const
|
|
1045
|
-
if (
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1073
|
+
if (graphNode.type === "button") {
|
|
1074
|
+
const el2 = dom.createElement("button");
|
|
1075
|
+
const label = graphNode.getProp("label");
|
|
1076
|
+
if (label !== void 0) dom.setTextContent(el2, String(label));
|
|
1077
|
+
const disabled = graphNode.getProp("disabled");
|
|
1078
|
+
if (disabled === true) dom.setAttribute(el2, "disabled", "");
|
|
1079
|
+
applyNodeProps(ctx, graphNode, el2);
|
|
1080
|
+
const instance2 = new NodeInstance(graphNode, el2);
|
|
1081
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
1082
|
+
wireEvents(dom, graph, graphNode, el2, instance2);
|
|
1083
|
+
if (graphNode.stateRefs.length !== 0) {
|
|
1084
|
+
wireSignalBindings(ctx, graphNode, instance2, buttonUpdate(dom, el2));
|
|
1085
|
+
}
|
|
1086
|
+
dom.appendChild(parentDom, el2);
|
|
1087
|
+
return instance2;
|
|
1050
1088
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1089
|
+
if (graphNode.type === "reactive-list" || graphNode.type === "conditional") {
|
|
1090
|
+
const tag2 = resolveTag(graphNode.type);
|
|
1091
|
+
const el2 = dom.createElement(tag2);
|
|
1092
|
+
applyNodeProps(ctx, graphNode, el2);
|
|
1093
|
+
const instance2 = new NodeInstance(graphNode, el2);
|
|
1094
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
1095
|
+
for (const child of graphNode.children) {
|
|
1096
|
+
const childInstance = mountNode(ctx, child, el2);
|
|
1097
|
+
instance2.addChild(childInstance);
|
|
1057
1098
|
}
|
|
1099
|
+
dom.appendChild(parentDom, el2);
|
|
1100
|
+
wireReactiveList(ctx, graphNode, instance2, el2);
|
|
1101
|
+
return instance2;
|
|
1058
1102
|
}
|
|
1059
|
-
|
|
1060
|
-
|
|
1103
|
+
if (graphNode.type === "portal") {
|
|
1104
|
+
const anchor = dom.createElement(resolveTag("portal"));
|
|
1105
|
+
dom.setAttribute(anchor, "data-streetui-portal", "");
|
|
1106
|
+
applyNodeProps(ctx, graphNode, anchor);
|
|
1107
|
+
const instance2 = new NodeInstance(graphNode, anchor);
|
|
1108
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
1109
|
+
const body = dom.body();
|
|
1110
|
+
let target = anchor;
|
|
1111
|
+
if (body !== null) {
|
|
1112
|
+
const portalContainer = dom.createElement("div");
|
|
1113
|
+
dom.setAttribute(portalContainer, "data-streetui-portal-container", "");
|
|
1114
|
+
dom.appendChild(body, portalContainer);
|
|
1115
|
+
instance2.trackCleanup(() => dom.removeChild(body, portalContainer));
|
|
1116
|
+
target = portalContainer;
|
|
1117
|
+
}
|
|
1118
|
+
for (const child of graphNode.children) {
|
|
1119
|
+
instance2.addChild(mountNode(ctx, child, target));
|
|
1120
|
+
}
|
|
1121
|
+
dom.appendChild(parentDom, anchor);
|
|
1122
|
+
wireOverlayBehavior(ctx, graphNode, instance2, target);
|
|
1123
|
+
return instance2;
|
|
1061
1124
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1125
|
+
const tag = resolveTag(graphNode.type);
|
|
1126
|
+
const el = dom.createElement(tag);
|
|
1127
|
+
applyNodeProps(ctx, graphNode, el);
|
|
1128
|
+
if (graphNode.type === "list-item") {
|
|
1129
|
+
const itemKey = graphNode.getProp("key");
|
|
1130
|
+
if (itemKey !== void 0) {
|
|
1131
|
+
dom.setAttribute(el, "data-streetui-key", String(itemKey));
|
|
1132
|
+
}
|
|
1064
1133
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1134
|
+
const instance = new NodeInstance(graphNode, el);
|
|
1135
|
+
ctx.instances.set(graphNode.id, instance);
|
|
1136
|
+
if (graphNode.type === "form") {
|
|
1137
|
+
wireEvents(dom, graph, graphNode, el, instance);
|
|
1067
1138
|
}
|
|
1068
|
-
|
|
1069
|
-
|
|
1139
|
+
for (const child of graphNode.children) {
|
|
1140
|
+
const childInstance = mountNode(ctx, child, el);
|
|
1141
|
+
instance.addChild(childInstance);
|
|
1070
1142
|
}
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
n.data = text;
|
|
1143
|
+
dom.appendChild(parentDom, el);
|
|
1144
|
+
return instance;
|
|
1145
|
+
}
|
|
1146
|
+
function textUpdate(dom, el, textNode) {
|
|
1147
|
+
return (propKey, value) => {
|
|
1148
|
+
if (propKey === "text") {
|
|
1149
|
+
dom.setTextContent(textNode, String(value ?? ""));
|
|
1150
|
+
} else {
|
|
1151
|
+
applyProp(dom, el, propKey, value);
|
|
1081
1152
|
}
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
if (
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1153
|
+
};
|
|
1154
|
+
}
|
|
1155
|
+
function headingUpdate(dom, el) {
|
|
1156
|
+
return (propKey, value) => {
|
|
1157
|
+
if (propKey === "text") {
|
|
1158
|
+
dom.setTextContent(el, String(value ?? ""));
|
|
1159
|
+
} else {
|
|
1160
|
+
applyProp(dom, el, propKey, value);
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
}
|
|
1164
|
+
function inputUpdate(dom, el) {
|
|
1165
|
+
return (propKey, value) => {
|
|
1166
|
+
if (propKey === "value") {
|
|
1167
|
+
dom.setProperty(el, "value", String(value ?? ""));
|
|
1168
|
+
} else {
|
|
1169
|
+
applyProp(dom, el, propKey, value);
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
function buttonUpdate(dom, el) {
|
|
1174
|
+
return (propKey, value) => {
|
|
1175
|
+
if (propKey === "label") {
|
|
1176
|
+
dom.setTextContent(el, String(value ?? ""));
|
|
1177
|
+
} else if (propKey === "disabled") {
|
|
1178
|
+
if (value === true) {
|
|
1179
|
+
dom.setAttribute(el, "disabled", "");
|
|
1180
|
+
} else {
|
|
1181
|
+
dom.removeAttribute(el, "disabled");
|
|
1090
1182
|
}
|
|
1091
|
-
|
|
1183
|
+
} else {
|
|
1184
|
+
applyProp(dom, el, propKey, value);
|
|
1092
1185
|
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
return null;
|
|
1102
|
-
}
|
|
1103
|
-
querySelectorAll() {
|
|
1104
|
-
return [];
|
|
1105
|
-
}
|
|
1106
|
-
getElementById() {
|
|
1107
|
-
return null;
|
|
1108
|
-
}
|
|
1109
|
-
focus() {
|
|
1110
|
-
}
|
|
1111
|
-
isElement(node) {
|
|
1112
|
-
return asServer(node).kind === "element";
|
|
1186
|
+
};
|
|
1187
|
+
}
|
|
1188
|
+
function applyNodeProps(ctx, graphNode, el) {
|
|
1189
|
+
const props = graphNode.props;
|
|
1190
|
+
for (const key in props) {
|
|
1191
|
+
if (!Object.hasOwn(props, key)) continue;
|
|
1192
|
+
if (SKIP_PROP_KEYS.has(key)) continue;
|
|
1193
|
+
applyProp(ctx.dom, el, key, props[key]);
|
|
1113
1194
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1195
|
+
}
|
|
1196
|
+
function wireSignalBindings(ctx, graphNode, instance, onUpdate) {
|
|
1197
|
+
if (graphNode.stateRefs.length === 0) return;
|
|
1198
|
+
for (const stateRef of graphNode.stateRefs) {
|
|
1199
|
+
const signalKey = `__signal__${stateRef.signalId}`;
|
|
1200
|
+
const maybeSig = ctx.graph.getHandler(signalKey);
|
|
1201
|
+
if (maybeSig === void 0 || typeof maybeSig.subscribe !== "function") continue;
|
|
1202
|
+
const unsub = maybeSig.subscribe((value) => {
|
|
1203
|
+
onUpdate(stateRef.propKey, value);
|
|
1204
|
+
});
|
|
1205
|
+
instance.trackCleanup(unsub);
|
|
1116
1206
|
}
|
|
1117
|
-
|
|
1118
|
-
|
|
1207
|
+
}
|
|
1208
|
+
function wireReactiveList(ctx, graphNode, instance, el) {
|
|
1209
|
+
const plan = ctx.graph.getHandler(`__listplan__${graphNode.id}`);
|
|
1210
|
+
const build = ctx.graph.getHandler(`__listbuild__${graphNode.id}`);
|
|
1211
|
+
if (plan === void 0 && build === void 0) return;
|
|
1212
|
+
for (const stateRef of graphNode.stateRefs) {
|
|
1213
|
+
if (stateRef.propKey !== "items") continue;
|
|
1214
|
+
const sig = ctx.graph.getHandler(`__signal__${stateRef.signalId}`);
|
|
1215
|
+
if (sig === void 0 || typeof sig.subscribe !== "function") continue;
|
|
1216
|
+
const unsub = sig.subscribe((value) => {
|
|
1217
|
+
if (plan !== void 0) {
|
|
1218
|
+
reconcileReactiveListByPlan(ctx, graphNode, instance, el, plan(value));
|
|
1219
|
+
} else {
|
|
1220
|
+
reconcileReactiveList(ctx, graphNode, instance, el, build(value));
|
|
1221
|
+
}
|
|
1222
|
+
});
|
|
1223
|
+
instance.trackCleanup(unsub);
|
|
1119
1224
|
}
|
|
1120
|
-
|
|
1121
|
-
|
|
1225
|
+
}
|
|
1226
|
+
function reconcileReactiveListByPlan(ctx, listNode, listInstance, listEl, plan) {
|
|
1227
|
+
const oldInstances = [...listInstance.children];
|
|
1228
|
+
const result = reconcileChildrenByPlan(
|
|
1229
|
+
ctx,
|
|
1230
|
+
listEl,
|
|
1231
|
+
oldInstances,
|
|
1232
|
+
plan,
|
|
1233
|
+
(node, parent) => mountNode(ctx, node, parent)
|
|
1234
|
+
);
|
|
1235
|
+
listInstance.children.length = 0;
|
|
1236
|
+
for (const inst of result.instances) listInstance.children.push(inst);
|
|
1237
|
+
for (const removed of result.removed) {
|
|
1238
|
+
forgetInstance(ctx, removed);
|
|
1239
|
+
ctx.graph.detachNode(removed.graphNode);
|
|
1122
1240
|
}
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
if (parent === null) return null;
|
|
1127
|
-
const idx = parent.children.indexOf(n);
|
|
1128
|
-
if (idx === -1 || idx + 1 >= parent.children.length) return null;
|
|
1129
|
-
return parent.children[idx + 1];
|
|
1241
|
+
const adopted = new Set(result.instances.map((i) => i.graphNode));
|
|
1242
|
+
for (const node of result.built ?? []) {
|
|
1243
|
+
if (!adopted.has(node)) ctx.graph.detachNode(node);
|
|
1130
1244
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1245
|
+
for (const child of [...listNode.children]) listNode.removeChild(child);
|
|
1246
|
+
for (const inst of result.instances) listNode.appendChild(inst.graphNode);
|
|
1247
|
+
}
|
|
1248
|
+
function reconcileReactiveList(ctx, listNode, listInstance, listEl, newNodes) {
|
|
1249
|
+
const oldInstances = [...listInstance.children];
|
|
1250
|
+
const result = reconcileChildren(
|
|
1251
|
+
ctx,
|
|
1252
|
+
listEl,
|
|
1253
|
+
oldInstances,
|
|
1254
|
+
newNodes,
|
|
1255
|
+
(node, parent) => mountNode(ctx, node, parent)
|
|
1256
|
+
);
|
|
1257
|
+
listInstance.children.length = 0;
|
|
1258
|
+
for (const inst of result.instances) listInstance.children.push(inst);
|
|
1259
|
+
for (const removed of result.removed) {
|
|
1260
|
+
forgetInstance(ctx, removed);
|
|
1261
|
+
ctx.graph.detachNode(removed.graphNode);
|
|
1138
1262
|
}
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
if (
|
|
1142
|
-
return n.children;
|
|
1143
|
-
}
|
|
1144
|
-
return [];
|
|
1263
|
+
const adopted = new Set(result.instances.map((i) => i.graphNode));
|
|
1264
|
+
for (const built of newNodes) {
|
|
1265
|
+
if (!adopted.has(built)) ctx.graph.detachNode(built);
|
|
1145
1266
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1267
|
+
for (const child of [...listNode.children]) listNode.removeChild(child);
|
|
1268
|
+
for (const inst of result.instances) listNode.appendChild(inst.graphNode);
|
|
1269
|
+
}
|
|
1270
|
+
function forgetInstance(ctx, instance) {
|
|
1271
|
+
ctx.instances.delete(instance.graphNode.id);
|
|
1272
|
+
for (const child of instance.children) forgetInstance(ctx, child);
|
|
1273
|
+
}
|
|
1274
|
+
function wireOverlayBehavior(ctx, graphNode, instance, target) {
|
|
1275
|
+
const { dom, graph } = ctx;
|
|
1276
|
+
if (dom.body() === null) return;
|
|
1277
|
+
const descFn = graph.getHandler(`__overlay__${graphNode.id}`);
|
|
1278
|
+
if (descFn === void 0) return;
|
|
1279
|
+
const desc = descFn();
|
|
1280
|
+
const openSig = desc.open;
|
|
1281
|
+
if (openSig === void 0 || typeof openSig.subscribe !== "function") return;
|
|
1282
|
+
let active = [];
|
|
1283
|
+
let saved = null;
|
|
1284
|
+
const teardown = () => {
|
|
1285
|
+
for (const fn of active) fn();
|
|
1286
|
+
active = [];
|
|
1287
|
+
};
|
|
1288
|
+
const onOpenChange = (isOpen) => {
|
|
1289
|
+
if (isOpen) {
|
|
1290
|
+
if (desc.restoreFocus) saved = saveFocus(dom);
|
|
1291
|
+
if (desc.takesFocus) focusInitial(dom, target, desc.initialFocusId);
|
|
1292
|
+
if (desc.modal) {
|
|
1293
|
+
active.push(trapFocus(dom, target));
|
|
1294
|
+
active.push(containFocus(dom, target));
|
|
1295
|
+
}
|
|
1296
|
+
if (desc.closeOnEscape && desc.onClose !== void 0) {
|
|
1297
|
+
active.push(onEscape(dom, target, desc.onClose));
|
|
1298
|
+
}
|
|
1299
|
+
} else {
|
|
1300
|
+
teardown();
|
|
1301
|
+
if (desc.restoreFocus && saved !== null) {
|
|
1302
|
+
restoreFocus(dom, saved);
|
|
1303
|
+
saved = null;
|
|
1304
|
+
}
|
|
1152
1305
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
};
|
|
1306
|
+
};
|
|
1307
|
+
const unsub = openSig.subscribe(onOpenChange);
|
|
1308
|
+
instance.trackCleanup(unsub);
|
|
1309
|
+
instance.trackCleanup(teardown);
|
|
1310
|
+
if (openSig.peek() === true) onOpenChange(true);
|
|
1311
|
+
}
|
|
1160
1312
|
|
|
1161
1313
|
// ../renderer/src/dehydrate.ts
|
|
1162
1314
|
var STATE_MARKER_ATTR = "data-streetui-state";
|
|
@@ -1223,7 +1375,8 @@ function analyzeGraph(graph) {
|
|
|
1223
1375
|
const hasEvents = node.events.length > 0;
|
|
1224
1376
|
const isList = node.type === "reactive-list";
|
|
1225
1377
|
const isConditional = node.type === "conditional";
|
|
1226
|
-
const
|
|
1378
|
+
const isPortal = node.type === "portal";
|
|
1379
|
+
const isStatic = node.stateRefs.length === 0 && !hasEvents && !isList && !isConditional && !isPortal;
|
|
1227
1380
|
const isStaticSubtree = isStatic && allChildrenStatic;
|
|
1228
1381
|
nodes.set(node.id, {
|
|
1229
1382
|
isStatic,
|
|
@@ -1310,7 +1463,7 @@ function renderToString(compiled, options = {}) {
|
|
|
1310
1463
|
}
|
|
1311
1464
|
|
|
1312
1465
|
// src/version.ts
|
|
1313
|
-
var VERSION = "1.
|
|
1466
|
+
var VERSION = "1.7.0";
|
|
1314
1467
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1315
1468
|
0 && (module.exports = {
|
|
1316
1469
|
STATE_MARKER_ATTR,
|