streetui 1.3.0 → 1.5.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/testing.cjs CHANGED
@@ -312,7 +312,6 @@ var BrowserDOMAdapter = class {
312
312
  return Array.from(node.childNodes);
313
313
  }
314
314
  };
315
- var browserDOMAdapter = new BrowserDOMAdapter();
316
315
 
317
316
  // ../dom/src/server-node.ts
318
317
  var ServerStyle = class {
@@ -353,13 +352,30 @@ var ServerElement = class {
353
352
  parent = null;
354
353
  tagName;
355
354
  attributes = /* @__PURE__ */ new Map();
356
- /** JS properties set via `setProperty` (e.g. input `value`, `checked`). */
357
- properties = /* @__PURE__ */ new Map();
358
355
  children = [];
359
- style = new ServerStyle();
356
+ // Lazily-allocated stores. On the 10k-row SSR corpus ~0% of elements carry JS
357
+ // properties or inline styles (measured, §5: 1 of 80,029 elements uses
358
+ // `properties`, 0 use `style`), so eagerly allocating a `properties` Map plus
359
+ // a `ServerStyle` (which itself holds a Map) per element wasted ~240k
360
+ // allocations per /users render — all in the dominant mount phase. These are
361
+ // created on first WRITE via the `properties`/`style` getters; the serializer
362
+ // reads the raw `_properties`/`_style` fields so a READ never forces an
363
+ // allocation. Output is byte-identical: an unset store previously serialized
364
+ // to nothing (empty `properties.has(...)` / `style.isEmpty`), and a null store
365
+ // is skipped the same way.
366
+ _properties = null;
367
+ _style = null;
360
368
  constructor(tagName) {
361
369
  this.tagName = tagName.toLowerCase();
362
370
  }
371
+ /** JS properties set via `setProperty` (e.g. input `value`, `checked`). Allocated on first access. */
372
+ get properties() {
373
+ return this._properties ??= /* @__PURE__ */ new Map();
374
+ }
375
+ /** Inline-style holder mirroring `element.style`. Allocated on first access. */
376
+ get style() {
377
+ return this._style ??= new ServerStyle();
378
+ }
363
379
  };
364
380
  var VOID_ELEMENTS = /* @__PURE__ */ new Set([
365
381
  "area",
@@ -382,11 +398,66 @@ var SERIALIZED_PROPERTIES = {
382
398
  checked: "boolean",
383
399
  selected: "boolean"
384
400
  };
401
+ var SERIALIZED_PROPERTY_ENTRIES = Object.entries(SERIALIZED_PROPERTIES);
402
+ var TEXT_SPECIAL = /[&<>]/;
403
+ var ATTR_SPECIAL = /[&<>"]/;
385
404
  function escapeHtmlText(value) {
386
- return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
405
+ if (!TEXT_SPECIAL.test(value)) return value;
406
+ let out = "";
407
+ let last = 0;
408
+ for (let i = 0; i < value.length; i++) {
409
+ let esc;
410
+ switch (value.charCodeAt(i)) {
411
+ case 38:
412
+ esc = "&amp;";
413
+ break;
414
+ // &
415
+ case 60:
416
+ esc = "&lt;";
417
+ break;
418
+ // <
419
+ case 62:
420
+ esc = "&gt;";
421
+ break;
422
+ // >
423
+ default:
424
+ continue;
425
+ }
426
+ out += value.slice(last, i) + esc;
427
+ last = i + 1;
428
+ }
429
+ return out + value.slice(last);
387
430
  }
388
431
  function escapeHtmlAttr(value) {
389
- return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
432
+ if (!ATTR_SPECIAL.test(value)) return value;
433
+ let out = "";
434
+ let last = 0;
435
+ for (let i = 0; i < value.length; i++) {
436
+ let esc;
437
+ switch (value.charCodeAt(i)) {
438
+ case 38:
439
+ esc = "&amp;";
440
+ break;
441
+ // &
442
+ case 60:
443
+ esc = "&lt;";
444
+ break;
445
+ // <
446
+ case 62:
447
+ esc = "&gt;";
448
+ break;
449
+ // >
450
+ case 34:
451
+ esc = "&quot;";
452
+ break;
453
+ // "
454
+ default:
455
+ continue;
456
+ }
457
+ out += value.slice(last, i) + esc;
458
+ last = i + 1;
459
+ }
460
+ return out + value.slice(last);
390
461
  }
391
462
  function serializeAttributes(el) {
392
463
  const parts = [];
@@ -397,20 +468,24 @@ function serializeAttributes(el) {
397
468
  parts.push(` ${name}="${escapeHtmlAttr(value)}"`);
398
469
  }
399
470
  }
400
- for (const [name, kind] of Object.entries(SERIALIZED_PROPERTIES)) {
401
- if (!el.properties.has(name)) continue;
402
- if (el.attributes.has(name)) continue;
403
- const raw = el.properties.get(name);
404
- if (kind === "boolean") {
405
- if (raw === true) parts.push(` ${name}`);
406
- } else {
407
- if (raw !== void 0 && raw !== null) {
408
- parts.push(` ${name}="${escapeHtmlAttr(String(raw))}"`);
471
+ const props = el._properties;
472
+ if (props !== null) {
473
+ for (const [name, kind] of SERIALIZED_PROPERTY_ENTRIES) {
474
+ if (!props.has(name)) continue;
475
+ if (el.attributes.has(name)) continue;
476
+ const raw = props.get(name);
477
+ if (kind === "boolean") {
478
+ if (raw === true) parts.push(` ${name}`);
479
+ } else {
480
+ if (raw !== void 0 && raw !== null) {
481
+ parts.push(` ${name}="${escapeHtmlAttr(String(raw))}"`);
482
+ }
409
483
  }
410
484
  }
411
485
  }
412
- if (!el.style.isEmpty && !el.attributes.has("style")) {
413
- parts.push(` style="${escapeHtmlAttr(el.style.toCss())}"`);
486
+ const style = el._style;
487
+ if (style !== null && !style.isEmpty && !el.attributes.has("style")) {
488
+ parts.push(` style="${escapeHtmlAttr(style.toCss())}"`);
414
489
  }
415
490
  return parts.join("");
416
491
  }
@@ -611,7 +686,6 @@ var ServerDOMAdapter = class {
611
686
  return serializeServerNode(asServer(node));
612
687
  }
613
688
  };
614
- var serverDOMAdapter = new ServerDOMAdapter();
615
689
 
616
690
  // ../renderer/src/render-context.ts
617
691
  function createRenderContext(dom, graph, container, hydrationDiagnostics) {
@@ -1998,7 +2072,7 @@ function formatInspection(inspection) {
1998
2072
  }
1999
2073
 
2000
2074
  // src/version.ts
2001
- var VERSION = "1.3.0";
2075
+ var VERSION = "1.5.0";
2002
2076
  // Annotate the CommonJS export names for ESM import in node:
2003
2077
  0 && (module.exports = {
2004
2078
  VERSION,