@solidjs/web 2.0.0-beta.22 → 2.0.0-beta.24

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.
Files changed (46) hide show
  1. package/dist/dev.cjs +25 -1
  2. package/dist/dev.js +25 -2
  3. package/dist/server.cjs +109 -45
  4. package/dist/server.js +109 -46
  5. package/dist/web.cjs +25 -1
  6. package/dist/web.js +25 -2
  7. package/frames/dist/client.cjs +1467 -0
  8. package/frames/dist/client.js +1455 -0
  9. package/frames/dist/server.cjs +1723 -0
  10. package/frames/dist/server.js +1712 -0
  11. package/frames/package.json +30 -0
  12. package/package.json +78 -5
  13. package/serialization/dist/serialization.cjs +83 -0
  14. package/serialization/dist/serialization.js +82 -1
  15. package/serialization/types/index.d.ts +12 -0
  16. package/serialization/types-cjs/index.d.cts +12 -0
  17. package/server-functions/dist/client.cjs +82 -55
  18. package/server-functions/dist/client.js +83 -56
  19. package/server-functions/dist/server.cjs +28 -7
  20. package/server-functions/dist/server.js +28 -7
  21. package/types/client.d.ts +8 -0
  22. package/types/core.d.ts +2 -1
  23. package/types/frames/client.d.ts +53 -0
  24. package/types/frames/frame-client.d.ts +222 -0
  25. package/types/frames/frame-sink.d.ts +145 -0
  26. package/types/frames/frame-transport.d.ts +106 -0
  27. package/types/frames/serializer.d.ts +151 -0
  28. package/types/frames/server.d.ts +21 -0
  29. package/types/serializer.d.ts +12 -0
  30. package/types/server-functions/client.d.ts +24 -0
  31. package/types/server-functions/server.d.ts +17 -0
  32. package/types/server-functions/shared.d.ts +17 -0
  33. package/types/server.d.ts +2 -0
  34. package/types-cjs/client.d.cts +8 -0
  35. package/types-cjs/core.d.cts +2 -1
  36. package/types-cjs/frames/client.d.cts +53 -0
  37. package/types-cjs/frames/frame-client.d.cts +222 -0
  38. package/types-cjs/frames/frame-sink.d.cts +145 -0
  39. package/types-cjs/frames/frame-transport.d.cts +106 -0
  40. package/types-cjs/frames/serializer.d.cts +151 -0
  41. package/types-cjs/frames/server.d.cts +21 -0
  42. package/types-cjs/serializer.d.cts +12 -0
  43. package/types-cjs/server-functions/client.d.cts +24 -0
  44. package/types-cjs/server-functions/server.d.cts +17 -0
  45. package/types-cjs/server-functions/shared.d.cts +17 -0
  46. package/types-cjs/server.d.cts +2 -0
package/dist/dev.cjs CHANGED
@@ -33,6 +33,7 @@ const DOMWithState = {
33
33
  const ChildProperties = /*#__PURE__*/new Set(["innerHTML", "textContent", "innerText", "children"]);
34
34
  const $$SLOT = /*#__PURE__*/Symbol("slot");
35
35
  const $$HOST = /*#__PURE__*/Symbol("host");
36
+ const $$FRAME = /*#__PURE__*/Symbol.for("dom-expressions.frame");
36
37
  const DelegatedEvents = /*#__PURE__*/new Set(["beforeinput", "click", "dblclick", "contextmenu", "focusin", "focusout", "input", "keydown", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "pointerdown", "pointermove", "pointerout", "pointerover", "pointerup", "touchend", "touchmove", "touchstart"]);
37
38
  const SVGElements = /*#__PURE__*/new Set([
38
39
  "altGlyph", "altGlyphDef", "altGlyphItem", "animate", "animateColor", "animateMotion", "animateTransform", "circle", "clipPath", "color-profile", "cursor", "defs", "desc", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "font", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "foreignObject", "g", "glyph", "glyphRef", "hkern", "image", "line", "linearGradient", "marker", "mask", "metadata", "missing-glyph", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect",
@@ -283,13 +284,29 @@ function setProperty(node, name, value) {
283
284
  node[name] = value;
284
285
  }
285
286
  let claimHandlers = null;
287
+ const CLAIM_SEAM = Symbol.for("dom-expressions.element-claims");
286
288
  function registerElementClaim(handler) {
287
- (claimHandlers || (claimHandlers = [])).push(handler);
289
+ (claimHandlers || (claimHandlers = globalThis[CLAIM_SEAM] = [])).push(handler);
288
290
  return () => {
289
291
  const index = claimHandlers.indexOf(handler);
290
292
  index > -1 && claimHandlers.splice(index, 1);
291
293
  };
292
294
  }
295
+ const CLAIMED_ELEMENTS = "a[href], form[action]";
296
+ function claimElementTree(root) {
297
+ const handlers = globalThis[CLAIM_SEAM];
298
+ if (handlers === undefined || handlers.length === 0) return root;
299
+ const isElement = root.nodeType === 1;
300
+ if (!isElement && root.nodeType !== 11) return root;
301
+ if (isElement && root.matches(CLAIMED_ELEMENTS)) {
302
+ for (let i = 0; i < handlers.length; i++) handlers[i](root);
303
+ }
304
+ const found = root.querySelectorAll(CLAIMED_ELEMENTS);
305
+ for (let i = 0; i < found.length; i++) {
306
+ for (let j = 0; j < handlers.length; j++) handlers[j](found[i]);
307
+ }
308
+ return root;
309
+ }
293
310
  function claimElement(node) {
294
311
  if (claimHandlers !== null) {
295
312
  for (let i = 0; i < claimHandlers.length; i++) claimHandlers[i](node);
@@ -1008,6 +1025,11 @@ function insertExpression(parent, value, current, marker) {
1008
1025
  parent.appendChild(value);
1009
1026
  }
1010
1027
  if (marker) value[$$SLOT] = marker;
1028
+ } else if (value[$$FRAME]) {
1029
+ if (current) {
1030
+ cleanChildren(parent, Array.isArray(current) ? current : [current], multi ? marker : null);
1031
+ }
1032
+ value[$$FRAME](parent, multi ? marker : null);
1011
1033
  } else if (Array.isArray(value)) {
1012
1034
  const currentArray = current && Array.isArray(current);
1013
1035
  if (value.length === 0) {
@@ -1028,6 +1050,7 @@ function normalize(value, current, multi, doNotUnwrap) {
1028
1050
  doNotUnwrap
1029
1051
  });
1030
1052
  if (doNotUnwrap && typeof value === "function") return value;
1053
+ if (value != null && value[$$FRAME]) return value;
1031
1054
  if (multi && !Array.isArray(value)) value = [value != null ? value : ""];
1032
1055
  if (Array.isArray(value)) {
1033
1056
  for (let i = 0, len = value.length; i < len; i++) {
@@ -1378,6 +1401,7 @@ exports.addEvent = addEvent;
1378
1401
  exports.applyRef = applyRef;
1379
1402
  exports.assign = assign;
1380
1403
  exports.claimElement = claimElement;
1404
+ exports.claimElementTree = claimElementTree;
1381
1405
  exports.className = className;
1382
1406
  exports.delegateEvents = delegateEvents;
1383
1407
  exports.dynamic = dynamic;
package/dist/dev.js CHANGED
@@ -32,6 +32,7 @@ const DOMWithState = {
32
32
  const ChildProperties = /*#__PURE__*/new Set(["innerHTML", "textContent", "innerText", "children"]);
33
33
  const $$SLOT = /*#__PURE__*/Symbol("slot");
34
34
  const $$HOST = /*#__PURE__*/Symbol("host");
35
+ const $$FRAME = /*#__PURE__*/Symbol.for("dom-expressions.frame");
35
36
  const DelegatedEvents = /*#__PURE__*/new Set(["beforeinput", "click", "dblclick", "contextmenu", "focusin", "focusout", "input", "keydown", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "pointerdown", "pointermove", "pointerout", "pointerover", "pointerup", "touchend", "touchmove", "touchstart"]);
36
37
  const SVGElements = /*#__PURE__*/new Set([
37
38
  "altGlyph", "altGlyphDef", "altGlyphItem", "animate", "animateColor", "animateMotion", "animateTransform", "circle", "clipPath", "color-profile", "cursor", "defs", "desc", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "feDropShadow", "feFlood", "feFuncA", "feFuncB", "feFuncG", "feFuncR", "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "fePointLight", "feSpecularLighting", "feSpotLight", "feTile", "feTurbulence", "filter", "font", "font-face", "font-face-format", "font-face-name", "font-face-src", "font-face-uri", "foreignObject", "g", "glyph", "glyphRef", "hkern", "image", "line", "linearGradient", "marker", "mask", "metadata", "missing-glyph", "mpath", "path", "pattern", "polygon", "polyline", "radialGradient", "rect",
@@ -282,13 +283,29 @@ function setProperty(node, name, value) {
282
283
  node[name] = value;
283
284
  }
284
285
  let claimHandlers = null;
286
+ const CLAIM_SEAM = Symbol.for("dom-expressions.element-claims");
285
287
  function registerElementClaim(handler) {
286
- (claimHandlers || (claimHandlers = [])).push(handler);
288
+ (claimHandlers || (claimHandlers = globalThis[CLAIM_SEAM] = [])).push(handler);
287
289
  return () => {
288
290
  const index = claimHandlers.indexOf(handler);
289
291
  index > -1 && claimHandlers.splice(index, 1);
290
292
  };
291
293
  }
294
+ const CLAIMED_ELEMENTS = "a[href], form[action]";
295
+ function claimElementTree(root) {
296
+ const handlers = globalThis[CLAIM_SEAM];
297
+ if (handlers === undefined || handlers.length === 0) return root;
298
+ const isElement = root.nodeType === 1;
299
+ if (!isElement && root.nodeType !== 11) return root;
300
+ if (isElement && root.matches(CLAIMED_ELEMENTS)) {
301
+ for (let i = 0; i < handlers.length; i++) handlers[i](root);
302
+ }
303
+ const found = root.querySelectorAll(CLAIMED_ELEMENTS);
304
+ for (let i = 0; i < found.length; i++) {
305
+ for (let j = 0; j < handlers.length; j++) handlers[j](found[i]);
306
+ }
307
+ return root;
308
+ }
292
309
  function claimElement(node) {
293
310
  if (claimHandlers !== null) {
294
311
  for (let i = 0; i < claimHandlers.length; i++) claimHandlers[i](node);
@@ -1007,6 +1024,11 @@ function insertExpression(parent, value, current, marker) {
1007
1024
  parent.appendChild(value);
1008
1025
  }
1009
1026
  if (marker) value[$$SLOT] = marker;
1027
+ } else if (value[$$FRAME]) {
1028
+ if (current) {
1029
+ cleanChildren(parent, Array.isArray(current) ? current : [current], multi ? marker : null);
1030
+ }
1031
+ value[$$FRAME](parent, multi ? marker : null);
1010
1032
  } else if (Array.isArray(value)) {
1011
1033
  const currentArray = current && Array.isArray(current);
1012
1034
  if (value.length === 0) {
@@ -1027,6 +1049,7 @@ function normalize(value, current, multi, doNotUnwrap) {
1027
1049
  doNotUnwrap
1028
1050
  });
1029
1051
  if (doNotUnwrap && typeof value === "function") return value;
1052
+ if (value != null && value[$$FRAME]) return value;
1030
1053
  if (multi && !Array.isArray(value)) value = [value != null ? value : ""];
1031
1054
  if (Array.isArray(value)) {
1032
1055
  for (let i = 0, len = value.length; i < len; i++) {
@@ -1304,4 +1327,4 @@ function createElement(tagName, is = undefined) {
1304
1327
  });
1305
1328
  }
1306
1329
 
1307
- export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, claimElement, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, installHydrationRuntime, isDev, isHref, isResponseEnvelope, isServer, memo, mergeProps, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, respond, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
1330
+ export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, HREF, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, ResponseEnvelope, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, claimElement, claimElementTree, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, installHydrationRuntime, isDev, isHref, isResponseEnvelope, isServer, memo, mergeProps, redirect, ref, registerDelegatedContainer, registerDelegatedRoot, registerElementClaim, reload, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, respond, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
package/dist/server.cjs CHANGED
@@ -313,7 +313,8 @@ function renderToStream(code, options = {}) {
313
313
  }
314
314
  tasks += task + ";";
315
315
  if (!timer && firstFlushed) {
316
- timer = setTimeout(writeTasks);
316
+ timer = true;
317
+ queue(() => queue(writeTasks));
317
318
  }
318
319
  };
319
320
  const onDone = () => {
@@ -328,10 +329,53 @@ function renderToStream(code, options = {}) {
328
329
  completed = true;
329
330
  if (firstFlushed) dispose();
330
331
  };
331
- const serializer = createHydrationSerializer({
332
+ const sink = {
333
+ data(payload) {
334
+ pushTask(payload);
335
+ },
336
+ fragment(key, value, meta) {
337
+ const deferActivation = !!meta.revealGroup;
338
+ const styles = meta.styles;
339
+ for (let i = 0; i < styles.inline.length; i++) {
340
+ buffer.write(renderInlineStyle(styles.inline[i], nonce));
341
+ }
342
+ if (styles.links.length) {
343
+ emitTask(`$dfs("${key}",${styles.links.length},${deferActivation ? 1 : 0})`);
344
+ writeTasks();
345
+ for (const url of styles.links) {
346
+ buffer.write(`<link rel="stylesheet" href="${url}" onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
347
+ }
348
+ buffer.write(`<template id="${key}">${value}</template>`);
349
+ } else {
350
+ buffer.write(`<template id="${key}">${value}</template>`);
351
+ if (!deferActivation) {
352
+ emitTask(`$df("${key}")`);
353
+ }
354
+ }
355
+ },
356
+ reveal(keys, meta) {
357
+ emitTask(`${meta.fallback ? "$dflj" : "$dfj"}(${JSON.stringify(keys)})`);
358
+ },
359
+ asset(type, value) {
360
+ if (type === "module") {
361
+ buffer.write(`<link rel="modulepreload" href="${value}">`);
362
+ } else if (type === "inline-style") {
363
+ buffer.write(renderInlineStyle(value, nonce));
364
+ }
365
+ },
366
+ shell(shellHtml, meta) {
367
+ shellHtml = injectBeforeHead(shellHtml, meta.assets);
368
+ shellHtml = injectPreloadLinks(meta.preloads, shellHtml);
369
+ shellHtml = injectInlineStyles(meta.inlineStyles, shellHtml, nonce);
370
+ if (meta.tasks.length) shellHtml = injectScripts(shellHtml, meta.tasks, nonce);
371
+ buffer.write(shellHtml);
372
+ },
373
+ ...options.sink
374
+ };
375
+ const serializer = (options.serializer || createHydrationSerializer)({
332
376
  scopeId: options.renderId,
333
377
  plugins: options.plugins,
334
- onData: pushTask,
378
+ onData: payload => sink.data(payload),
335
379
  onDone,
336
380
  onError: options.onError
337
381
  });
@@ -353,7 +397,6 @@ function renderToStream(code, options = {}) {
353
397
  buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>${tasks}</script>`);
354
398
  tasks = "";
355
399
  }
356
- timer && clearTimeout(timer);
357
400
  timer = null;
358
401
  };
359
402
  let context;
@@ -405,7 +448,7 @@ function renderToStream(code, options = {}) {
405
448
  const entry = tracking.registerInlineStyle(value);
406
449
  if (firstFlushed && !tracking.currentBoundaryId && !entry.emitted) {
407
450
  entry.emitted = true;
408
- buffer.write(renderInlineStyle(entry, nonce));
451
+ sink.asset("inline-style", entry);
409
452
  }
410
453
  return;
411
454
  }
@@ -419,9 +462,7 @@ function renderToStream(code, options = {}) {
419
462
  }
420
463
  if (!tracking.emittedAssets.has(value)) {
421
464
  tracking.emittedAssets.add(value);
422
- if (firstFlushed && type === "module") {
423
- buffer.write(`<link rel="modulepreload" href="${value}">`);
424
- }
465
+ if (firstFlushed) sink.asset(type, value);
425
466
  }
426
467
  },
427
468
  block(p) {
@@ -503,23 +544,11 @@ function renderToStream(code, options = {}) {
503
544
  } else {
504
545
  serializeFragmentAssets(key, tracking.boundaryModules, context);
505
546
  const styles = collectStreamStyles(key, tracking, headStyles);
506
- const deferActivation = !!revealGroup;
507
- for (let i = 0; i < styles.inline.length; i++) {
508
- buffer.write(renderInlineStyle(styles.inline[i], nonce));
509
- }
510
- if (styles.links.length) {
511
- emitTask(`$dfs("${key}",${styles.links.length},${deferActivation ? 1 : 0})`);
512
- writeTasks();
513
- for (const url of styles.links) {
514
- buffer.write(`<link rel="stylesheet" href="${url}" onload="$dfc('${key}')" onerror="$dfc('${key}')">`);
515
- }
516
- buffer.write(`<template id="${key}">${value !== undefined ? value : " "}</template>`);
517
- } else {
518
- buffer.write(`<template id="${key}">${value !== undefined ? value : " "}</template>`);
519
- if (!deferActivation) {
520
- emitTask(`$df("${key}")`);
521
- }
522
- }
547
+ sink.fragment(key, value !== undefined ? value : " ", {
548
+ styles,
549
+ revealGroup,
550
+ error
551
+ });
523
552
  item.resolve(error);
524
553
  }
525
554
  }
@@ -530,12 +559,16 @@ function renderToStream(code, options = {}) {
530
559
  revealFragments(groupOrKeys) {
531
560
  const keys = resolveRevealKeys(groupOrKeys, true, true);
532
561
  if (!keys) return;
533
- emitTask(`$dfj(${JSON.stringify(keys)})`);
562
+ sink.reveal(keys, {
563
+ fallback: false
564
+ });
534
565
  },
535
566
  revealFallbacks(groupOrKeys) {
536
567
  const keys = resolveRevealKeys(groupOrKeys, false, false);
537
568
  if (!keys) return;
538
- emitTask(`$dflj(${JSON.stringify(keys)})`);
569
+ sink.reveal(keys, {
570
+ fallback: true
571
+ });
539
572
  }
540
573
  };
541
574
  applyAssetTracking(context, tracking, manifest);
@@ -595,16 +628,18 @@ function renderToStream(code, options = {}) {
595
628
  if (shellCompleted) return;
596
629
  if (!resolveRootHoles()) return;
597
630
  solidJs.sharedConfig.context = context;
598
- html = injectAssets(context.assets, html);
631
+ const assetsHtml = resolveAssetsHtml(context.assets);
599
632
  headStyles = new Set();
600
633
  for (const url of tracking.emittedAssets) {
601
634
  if (url.endsWith(".css")) headStyles.add(url);
602
635
  }
603
- html = injectPreloadLinks(tracking.emittedAssets, html);
604
- html = injectInlineStyles(tracking.inlineStyles, html, nonce);
605
636
  serializeRootAssets();
606
- if (tasks.length) html = injectScripts(html, tasks, nonce);
607
- buffer.write(html);
637
+ sink.shell(html, {
638
+ assets: assetsHtml,
639
+ preloads: tracking.emittedAssets,
640
+ inlineStyles: tracking.inlineStyles,
641
+ tasks
642
+ });
608
643
  tasks = "";
609
644
  onCompleteShell && onCompleteShell({
610
645
  write(v) {
@@ -613,6 +648,26 @@ function renderToStream(code, options = {}) {
613
648
  });
614
649
  shellCompleted = true;
615
650
  }
651
+ const MIN_DRAIN_TURNS = 8;
652
+ let lastBlockingSize = -1;
653
+ let lastRegistrySize = -1;
654
+ let drainTurn = 0;
655
+ const scheduleFlush = fn => {
656
+ const attempt = () => {
657
+ if (registry.size !== lastRegistrySize || drainTurn++ < MIN_DRAIN_TURNS) {
658
+ if (registry.size !== lastRegistrySize) drainTurn = 0;
659
+ lastRegistrySize = registry.size;
660
+ queue(attempt);
661
+ return;
662
+ }
663
+ fn();
664
+ };
665
+ const progressed = blockingPromises.size !== lastBlockingSize;
666
+ lastBlockingSize = blockingPromises.size;
667
+ lastRegistrySize = -1;
668
+ drainTurn = 0;
669
+ progressed ? queue(attempt) : setTimeout(attempt);
670
+ };
616
671
  return {
617
672
  then(fn) {
618
673
  function complete() {
@@ -628,7 +683,7 @@ function renderToStream(code, options = {}) {
628
683
  } else onCompleteAll = complete;
629
684
  function flush() {
630
685
  allSettled(blockingPromises).then(() => {
631
- setTimeout(() => {
686
+ scheduleFlush(() => {
632
687
  if (!resolveRootHoles()) return flush();
633
688
  queue(flushEnd);
634
689
  });
@@ -639,7 +694,7 @@ function renderToStream(code, options = {}) {
639
694
  pipe(w) {
640
695
  function flush() {
641
696
  allSettled(blockingPromises).then(() => {
642
- setTimeout(() => {
697
+ scheduleFlush(() => {
643
698
  doShell();
644
699
  if (!shellCompleted) return flush();
645
700
  buffer = writable = w;
@@ -659,7 +714,7 @@ function renderToStream(code, options = {}) {
659
714
  const p = new Promise(r => resolve = r);
660
715
  function flush() {
661
716
  allSettled(blockingPromises).then(() => {
662
- setTimeout(() => {
717
+ scheduleFlush(() => {
663
718
  doShell();
664
719
  if (!shellCompleted) return flush();
665
720
  const encoder = new TextEncoder();
@@ -962,14 +1017,12 @@ function escape(s, attr) {
962
1017
  }
963
1018
  return s;
964
1019
  }
965
- const delimCode = attr ? 34 : 60;
966
- const len = s.length;
967
- for (let i = 0; i < len; i++) {
968
- const c = s.charCodeAt(i);
969
- if (c === 38 || c === delimCode) return escapeSlow(s, attr, i);
970
- }
971
- return s;
1020
+ const i = s.search(attr ? ESCAPE_ATTR : ESCAPE_CONTENT);
1021
+ if (i < 0) return s;
1022
+ return escapeSlow(s, attr, i);
972
1023
  }
1024
+ const ESCAPE_CONTENT = /[&<]/;
1025
+ const ESCAPE_ATTR = /[&"]/;
973
1026
  function escapeSlow(s, attr, start) {
974
1027
  const delim = attr ? '"' : "<";
975
1028
  const delimCode = attr ? 34 : 60;
@@ -1054,13 +1107,20 @@ function allSettled(promises) {
1054
1107
  return;
1055
1108
  });
1056
1109
  }
1057
- function injectAssets(assets, html) {
1058
- if (!assets || !assets.length) return html;
1110
+ function resolveAssetsHtml(assets) {
1111
+ if (!assets || !assets.length) return "";
1059
1112
  let out = "";
1060
1113
  for (let i = 0, len = assets.length; i < len; i++) out += assets[i]();
1114
+ return out;
1115
+ }
1116
+ function injectBeforeHead(html, content) {
1117
+ if (!content) return html;
1061
1118
  const index = html.indexOf("</head>");
1062
1119
  if (index === -1) return html;
1063
- return html.slice(0, index) + out + html.slice(index);
1120
+ return html.slice(0, index) + content + html.slice(index);
1121
+ }
1122
+ function injectAssets(assets, html) {
1123
+ return injectBeforeHead(html, resolveAssetsHtml(assets));
1064
1124
  }
1065
1125
  function injectPreloadLinks(emittedAssets, html, nonce) {
1066
1126
  if (!emittedAssets.size) return html;
@@ -1279,6 +1339,9 @@ function noopCleanup() {}
1279
1339
  function claimElement(node) {
1280
1340
  return node;
1281
1341
  }
1342
+ function claimElementTree(root) {
1343
+ return root;
1344
+ }
1282
1345
  function notSup() {
1283
1346
  throw new Error("Client-only API called on the server side. Run client-only code in onMount, or conditionally run client-only component with <Show>.");
1284
1347
  }
@@ -1483,6 +1546,7 @@ exports.addEvent = notSup;
1483
1546
  exports.applyRef = applyRef;
1484
1547
  exports.assign = notSup;
1485
1548
  exports.claimElement = claimElement;
1549
+ exports.claimElementTree = claimElementTree;
1486
1550
  exports.className = notSup;
1487
1551
  exports.delegateEvents = notSup;
1488
1552
  exports.dynamic = dynamic;