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