solid-js 1.4.2 → 1.4.5

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/web/dist/dev.js CHANGED
@@ -2,8 +2,8 @@ import { createMemo, createRoot, createRenderEffect, sharedConfig, enableHydrati
2
2
  export { ErrorBoundary, For, Index, Match, Show, Suspense, SuspenseList, Switch, createComponent, createRenderEffect as effect, getOwner, mergeProps } from 'solid-js';
3
3
 
4
4
  const booleans = ["allowfullscreen", "async", "autofocus", "autoplay", "checked", "controls", "default", "disabled", "formnovalidate", "hidden", "indeterminate", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "seamless", "selected"];
5
- const Properties = new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]);
6
- const ChildProperties = new Set(["innerHTML", "textContent", "innerText", "children"]);
5
+ const Properties = /*#__PURE__*/new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]);
6
+ const ChildProperties = /*#__PURE__*/new Set(["innerHTML", "textContent", "innerText", "children"]);
7
7
  const Aliases = {
8
8
  className: "class",
9
9
  htmlFor: "for"
@@ -16,8 +16,8 @@ const PropAliases = {
16
16
  playsinline: "playsInline",
17
17
  readonly: "readOnly"
18
18
  };
19
- const DelegatedEvents = new Set(["beforeinput", "click", "dblclick", "contextmenu", "focusin", "focusout", "input", "keydown", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "pointerdown", "pointermove", "pointerout", "pointerover", "pointerup", "touchend", "touchmove", "touchstart"]);
20
- const SVGElements = new Set([
19
+ 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"]);
20
+ const SVGElements = /*#__PURE__*/new Set([
21
21
  "altGlyph", "altGlyphDef", "altGlyphItem", "animate", "animateColor", "animateMotion", "animateTransform", "circle", "clipPath", "color-profile", "cursor", "defs", "desc", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "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",
22
22
  "set", "stop",
23
23
  "svg", "switch", "symbol", "text", "textPath",
@@ -26,7 +26,7 @@ const SVGNamespace = {
26
26
  xlink: "http://www.w3.org/1999/xlink",
27
27
  xml: "http://www.w3.org/XML/1998/namespace"
28
28
  };
29
- const DOMElements = new Set(["html", "base", "head", "link", "meta", "style", "title", "body", "address", "article", "aside", "footer", "header", "main", "nav", "section", "body", "blockquote", "dd", "div", "dl", "dt", "figcaption", "figure", "hr", "li", "ol", "p", "pre", "ul", "a", "abbr", "b", "bdi", "bdo", "br", "cite", "code", "data", "dfn", "em", "i", "kbd", "mark", "q", "rp", "rt", "ruby", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "u", "var", "wbr", "area", "audio", "img", "map", "track", "video", "embed", "iframe", "object", "param", "picture", "portal", "source", "svg", "math", "canvas", "noscript", "script", "del", "ins", "caption", "col", "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "button", "datalist", "fieldset", "form", "input", "label", "legend", "meter", "optgroup", "option", "output", "progress", "select", "textarea", "details", "dialog", "menu", "summary", "details", "slot", "template", "acronym", "applet", "basefont", "bgsound", "big", "blink", "center", "content", "dir", "font", "frame", "frameset", "hgroup", "image", "keygen", "marquee", "menuitem", "nobr", "noembed", "noframes", "plaintext", "rb", "rtc", "shadow", "spacer", "strike", "tt", "xmp", "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "nav", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "portal", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp", "input"]);
29
+ const DOMElements = /*#__PURE__*/new Set(["html", "base", "head", "link", "meta", "style", "title", "body", "address", "article", "aside", "footer", "header", "main", "nav", "section", "body", "blockquote", "dd", "div", "dl", "dt", "figcaption", "figure", "hr", "li", "ol", "p", "pre", "ul", "a", "abbr", "b", "bdi", "bdo", "br", "cite", "code", "data", "dfn", "em", "i", "kbd", "mark", "q", "rp", "rt", "ruby", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "u", "var", "wbr", "area", "audio", "img", "map", "track", "video", "embed", "iframe", "object", "param", "picture", "portal", "source", "svg", "math", "canvas", "noscript", "script", "del", "ins", "caption", "col", "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "button", "datalist", "fieldset", "form", "input", "label", "legend", "meter", "optgroup", "option", "output", "progress", "select", "textarea", "details", "dialog", "menu", "summary", "details", "slot", "template", "acronym", "applet", "basefont", "bgsound", "big", "blink", "center", "content", "dir", "font", "frame", "frameset", "hgroup", "image", "keygen", "marquee", "menuitem", "nobr", "noembed", "noframes", "plaintext", "rb", "rtc", "shadow", "spacer", "strike", "tt", "xmp", "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "nav", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "portal", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp", "input"]);
30
30
 
31
31
  function memo(fn, equals) {
32
32
  return createMemo(fn, undefined, !equals ? {
@@ -143,7 +143,8 @@ function addEventListener(node, name, handler, delegate) {
143
143
  node[`$$${name}Data`] = handler[1];
144
144
  } else node[`$$${name}`] = handler;
145
145
  } else if (Array.isArray(handler)) {
146
- node.addEventListener(name, e => handler[0](handler[1], e));
146
+ const handlerFn = handler[0];
147
+ node.addEventListener(name, handler[0] = e => handlerFn.call(node, handler[1], e));
147
148
  } else node.addEventListener(name, handler);
148
149
  }
149
150
  function classList(node, value, prev = {}) {
@@ -307,14 +308,24 @@ function assignProp(node, prop, value, prev, isSVG, skipRef) {
307
308
  value(node);
308
309
  }
309
310
  } else if (prop.slice(0, 3) === "on:") {
310
- node.addEventListener(prop.slice(3), value);
311
+ const e = prop.slice(3);
312
+ prev && node.removeEventListener(e, prev);
313
+ value && node.addEventListener(e, value);
311
314
  } else if (prop.slice(0, 10) === "oncapture:") {
312
- node.addEventListener(prop.slice(10), value, true);
315
+ const e = prop.slice(10);
316
+ prev && node.removeEventListener(e, prev, true);
317
+ value && node.addEventListener(e, value, true);
313
318
  } else if (prop.slice(0, 2) === "on") {
314
319
  const name = prop.slice(2).toLowerCase();
315
320
  const delegate = DelegatedEvents.has(name);
316
- addEventListener(node, name, value, delegate);
317
- delegate && delegateEvents([name]);
321
+ if (!delegate && prev) {
322
+ const h = Array.isArray(prev) ? prev[0] : prev;
323
+ node.removeEventListener(name, h);
324
+ }
325
+ if (delegate || value) {
326
+ addEventListener(node, name, value, delegate);
327
+ delegate && delegateEvents([name]);
328
+ }
318
329
  } else if ((isChildProp = ChildProperties.has(prop)) || !isSVG && (PropAliases[prop] || (isProp = Properties.has(prop))) || (isCE = node.nodeName.includes("-"))) {
319
330
  if (prop === "class" || prop === "className") className(node, value);else if (isCE && !isProp && !isChildProp) node[toPropertyName(prop)] = value;else node[PropAliases[prop] || prop] = value;
320
331
  } else {
@@ -346,7 +357,7 @@ function eventHandler(e) {
346
357
  const handler = node[key];
347
358
  if (handler && !node.disabled) {
348
359
  const data = node[`${key}Data`];
349
- data !== undefined ? handler(data, e) : handler(e);
360
+ data !== undefined ? handler.call(node, data, e) : handler.call(node, e);
350
361
  if (e.cancelBubble) return;
351
362
  }
352
363
  node = node.host && node.host !== node && node.host instanceof Node ? node.host : node.parentNode;
@@ -394,7 +405,8 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
394
405
  return () => current;
395
406
  } else if (Array.isArray(value)) {
396
407
  const array = [];
397
- if (normalizeIncomingArray(array, value, unwrapArray)) {
408
+ const currentArray = current && Array.isArray(current);
409
+ if (normalizeIncomingArray(array, value, current, unwrapArray)) {
398
410
  createRenderEffect(() => current = insertExpression(parent, array, current, marker, true));
399
411
  return () => current;
400
412
  }
@@ -406,7 +418,7 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
406
418
  if (array.length === 0) {
407
419
  current = cleanChildren(parent, current, marker);
408
420
  if (multi) return current;
409
- } else if (Array.isArray(current)) {
421
+ } else if (currentArray) {
410
422
  if (current.length === 0) {
411
423
  appendNodes(parent, array, marker);
412
424
  } else reconcileArrays(parent, current, array);
@@ -427,26 +439,30 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
427
439
  } else console.warn(`Unrecognized value. Skipped inserting`, value);
428
440
  return current;
429
441
  }
430
- function normalizeIncomingArray(normalized, array, unwrap) {
442
+ function normalizeIncomingArray(normalized, array, current, unwrap) {
431
443
  let dynamic = false;
432
444
  for (let i = 0, len = array.length; i < len; i++) {
433
445
  let item = array[i],
446
+ prev = current && current[i],
434
447
  t;
435
448
  if (item instanceof Node) {
436
449
  normalized.push(item);
437
450
  } else if (item == null || item === true || item === false) ; else if (Array.isArray(item)) {
438
- dynamic = normalizeIncomingArray(normalized, item) || dynamic;
439
- } else if ((t = typeof item) === "string") {
440
- normalized.push(document.createTextNode(item));
441
- } else if (t === "function") {
451
+ dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic;
452
+ } else if ((t = typeof item) === "function") {
442
453
  if (unwrap) {
443
454
  while (typeof item === "function") item = item();
444
- dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item]) || dynamic;
455
+ dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], prev) || dynamic;
445
456
  } else {
446
457
  normalized.push(item);
447
458
  dynamic = true;
448
459
  }
449
- } else normalized.push(document.createTextNode(item.toString()));
460
+ } else {
461
+ const value = t === "string" ? item : item.string();
462
+ if (prev && prev.nodeType === 3 && prev.data === value) {
463
+ normalized.push(prev);
464
+ } else normalized.push(document.createTextNode(value));
465
+ }
450
466
  }
451
467
  return dynamic;
452
468
  }
@@ -505,7 +521,7 @@ function resolveSSRNode(node) {}
505
521
  function ssrClassList(value) {}
506
522
  function ssrStyle(value) {}
507
523
  function ssrSpread(accessor) {}
508
- function ssrBoolean(key, value) {}
524
+ function ssrAttribute(key, value) {}
509
525
  function ssrHydrationKey() {}
510
526
  function escape(html) {}
511
527
  function generateHydrationScript() {}
@@ -558,8 +574,9 @@ function Portal(props) {
558
574
  }
559
575
  function Dynamic(props) {
560
576
  const [p, others] = splitProps(props, ["component"]);
577
+ const cached = createMemo(() => p.component);
561
578
  return createMemo(() => {
562
- const component = p.component;
579
+ const component = cached();
563
580
  switch (typeof component) {
564
581
  case "function":
565
582
  Object.assign(component, {
@@ -575,4 +592,4 @@ function Dynamic(props) {
575
592
  });
576
593
  }
577
594
 
578
- export { Aliases, Assets, ChildProperties, DOMElements, DelegatedEvents, Dynamic, Assets as HydrationScript, NoHydration, Portal, PropAliases, Properties, SVGElements, SVGNamespace, addEventListener, assign, classList, className, clearDelegatedEvents, delegateEvents, dynamicProperty, escape, generateHydrationScript, getHydrationKey, getNextElement, getNextMarker, getNextMatch, hydrate, innerHTML, insert, isServer, memo, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, setAttribute, setAttributeNS, spread, ssr, ssrBoolean, ssrClassList, ssrHydrationKey, ssrSpread, ssrStyle, style, template };
595
+ export { Aliases, Assets, ChildProperties, DOMElements, DelegatedEvents, Dynamic, Assets as HydrationScript, NoHydration, Portal, PropAliases, Properties, SVGElements, SVGNamespace, addEventListener, assign, classList, className, clearDelegatedEvents, delegateEvents, dynamicProperty, escape, generateHydrationScript, getHydrationKey, getNextElement, getNextMarker, getNextMatch, hydrate, innerHTML, insert, isServer, memo, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, setAttribute, setAttributeNS, spread, ssr, ssrAttribute, ssrClassList, ssrHydrationKey, ssrSpread, ssrStyle, style, template };
@@ -5,8 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var solidJs = require('solid-js');
6
6
 
7
7
  const booleans = ["allowfullscreen", "async", "autofocus", "autoplay", "checked", "controls", "default", "disabled", "formnovalidate", "hidden", "indeterminate", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "seamless", "selected"];
8
- const BooleanAttributes = new Set(booleans);
9
- new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]);
8
+ const BooleanAttributes = /*#__PURE__*/new Set(booleans);
9
+ /*#__PURE__*/new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]);
10
10
  const Aliases = {
11
11
  className: "class",
12
12
  htmlFor: "for"
@@ -273,7 +273,10 @@ function renderToStringAsync(code, options = {}) {
273
273
  p.then(d => scripts += serializeSet(dedupe, id, d) + ";").catch(() => scripts += `_$HY.set("${id}", {});`);
274
274
  }
275
275
  };
276
- const timeout = new Promise((_, reject) => setTimeout(() => reject("renderToString timed out"), timeoutMs));
276
+ let timeoutHandle;
277
+ const timeout = new Promise((_, reject) => {
278
+ timeoutHandle = setTimeout(() => reject("renderToString timed out"), timeoutMs);
279
+ });
277
280
  function asyncWrap(fn) {
278
281
  return new Promise(resolve => {
279
282
  const registry = new Set();
@@ -304,6 +307,7 @@ function renderToStringAsync(code, options = {}) {
304
307
  });
305
308
  }
306
309
  return Promise.race([asyncWrap(() => escape(code())), timeout]).then(res => {
310
+ clearTimeout(timeoutHandle);
307
311
  let html = injectAssets(context.assets, resolveSSRNode(res));
308
312
  if (scripts.length) html = injectScripts(html, scripts, nonce);
309
313
  return html;
@@ -2,8 +2,8 @@ import { sharedConfig, splitProps } from 'solid-js';
2
2
  export { ErrorBoundary, For, Index, Match, Show, Suspense, SuspenseList, Switch, createComponent, mergeProps } from 'solid-js';
3
3
 
4
4
  const booleans = ["allowfullscreen", "async", "autofocus", "autoplay", "checked", "controls", "default", "disabled", "formnovalidate", "hidden", "indeterminate", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "seamless", "selected"];
5
- const BooleanAttributes = new Set(booleans);
6
- new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]);
5
+ const BooleanAttributes = /*#__PURE__*/new Set(booleans);
6
+ /*#__PURE__*/new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]);
7
7
  const Aliases = {
8
8
  className: "class",
9
9
  htmlFor: "for"
@@ -270,7 +270,10 @@ function renderToStringAsync(code, options = {}) {
270
270
  p.then(d => scripts += serializeSet(dedupe, id, d) + ";").catch(() => scripts += `_$HY.set("${id}", {});`);
271
271
  }
272
272
  };
273
- const timeout = new Promise((_, reject) => setTimeout(() => reject("renderToString timed out"), timeoutMs));
273
+ let timeoutHandle;
274
+ const timeout = new Promise((_, reject) => {
275
+ timeoutHandle = setTimeout(() => reject("renderToString timed out"), timeoutMs);
276
+ });
274
277
  function asyncWrap(fn) {
275
278
  return new Promise(resolve => {
276
279
  const registry = new Set();
@@ -301,6 +304,7 @@ function renderToStringAsync(code, options = {}) {
301
304
  });
302
305
  }
303
306
  return Promise.race([asyncWrap(() => escape(code())), timeout]).then(res => {
307
+ clearTimeout(timeoutHandle);
304
308
  let html = injectAssets(context.assets, resolveSSRNode(res));
305
309
  if (scripts.length) html = injectScripts(html, scripts, nonce);
306
310
  return html;
package/web/dist/web.cjs CHANGED
@@ -5,8 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var solidJs = require('solid-js');
6
6
 
7
7
  const booleans = ["allowfullscreen", "async", "autofocus", "autoplay", "checked", "controls", "default", "disabled", "formnovalidate", "hidden", "indeterminate", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "seamless", "selected"];
8
- const Properties = new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]);
9
- const ChildProperties = new Set(["innerHTML", "textContent", "innerText", "children"]);
8
+ const Properties = /*#__PURE__*/new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]);
9
+ const ChildProperties = /*#__PURE__*/new Set(["innerHTML", "textContent", "innerText", "children"]);
10
10
  const Aliases = {
11
11
  className: "class",
12
12
  htmlFor: "for"
@@ -19,8 +19,8 @@ const PropAliases = {
19
19
  playsinline: "playsInline",
20
20
  readonly: "readOnly"
21
21
  };
22
- const DelegatedEvents = new Set(["beforeinput", "click", "dblclick", "contextmenu", "focusin", "focusout", "input", "keydown", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "pointerdown", "pointermove", "pointerout", "pointerover", "pointerup", "touchend", "touchmove", "touchstart"]);
23
- const SVGElements = new Set([
22
+ 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"]);
23
+ const SVGElements = /*#__PURE__*/new Set([
24
24
  "altGlyph", "altGlyphDef", "altGlyphItem", "animate", "animateColor", "animateMotion", "animateTransform", "circle", "clipPath", "color-profile", "cursor", "defs", "desc", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "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",
25
25
  "set", "stop",
26
26
  "svg", "switch", "symbol", "text", "textPath",
@@ -29,7 +29,7 @@ const SVGNamespace = {
29
29
  xlink: "http://www.w3.org/1999/xlink",
30
30
  xml: "http://www.w3.org/XML/1998/namespace"
31
31
  };
32
- const DOMElements = new Set(["html", "base", "head", "link", "meta", "style", "title", "body", "address", "article", "aside", "footer", "header", "main", "nav", "section", "body", "blockquote", "dd", "div", "dl", "dt", "figcaption", "figure", "hr", "li", "ol", "p", "pre", "ul", "a", "abbr", "b", "bdi", "bdo", "br", "cite", "code", "data", "dfn", "em", "i", "kbd", "mark", "q", "rp", "rt", "ruby", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "u", "var", "wbr", "area", "audio", "img", "map", "track", "video", "embed", "iframe", "object", "param", "picture", "portal", "source", "svg", "math", "canvas", "noscript", "script", "del", "ins", "caption", "col", "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "button", "datalist", "fieldset", "form", "input", "label", "legend", "meter", "optgroup", "option", "output", "progress", "select", "textarea", "details", "dialog", "menu", "summary", "details", "slot", "template", "acronym", "applet", "basefont", "bgsound", "big", "blink", "center", "content", "dir", "font", "frame", "frameset", "hgroup", "image", "keygen", "marquee", "menuitem", "nobr", "noembed", "noframes", "plaintext", "rb", "rtc", "shadow", "spacer", "strike", "tt", "xmp", "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "nav", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "portal", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp", "input"]);
32
+ const DOMElements = /*#__PURE__*/new Set(["html", "base", "head", "link", "meta", "style", "title", "body", "address", "article", "aside", "footer", "header", "main", "nav", "section", "body", "blockquote", "dd", "div", "dl", "dt", "figcaption", "figure", "hr", "li", "ol", "p", "pre", "ul", "a", "abbr", "b", "bdi", "bdo", "br", "cite", "code", "data", "dfn", "em", "i", "kbd", "mark", "q", "rp", "rt", "ruby", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "u", "var", "wbr", "area", "audio", "img", "map", "track", "video", "embed", "iframe", "object", "param", "picture", "portal", "source", "svg", "math", "canvas", "noscript", "script", "del", "ins", "caption", "col", "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "button", "datalist", "fieldset", "form", "input", "label", "legend", "meter", "optgroup", "option", "output", "progress", "select", "textarea", "details", "dialog", "menu", "summary", "details", "slot", "template", "acronym", "applet", "basefont", "bgsound", "big", "blink", "center", "content", "dir", "font", "frame", "frameset", "hgroup", "image", "keygen", "marquee", "menuitem", "nobr", "noembed", "noframes", "plaintext", "rb", "rtc", "shadow", "spacer", "strike", "tt", "xmp", "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "nav", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "portal", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp", "input"]);
33
33
 
34
34
  function memo(fn, equals) {
35
35
  return solidJs.createMemo(fn, undefined, !equals ? {
@@ -145,7 +145,8 @@ function addEventListener(node, name, handler, delegate) {
145
145
  node[`$$${name}Data`] = handler[1];
146
146
  } else node[`$$${name}`] = handler;
147
147
  } else if (Array.isArray(handler)) {
148
- node.addEventListener(name, e => handler[0](handler[1], e));
148
+ const handlerFn = handler[0];
149
+ node.addEventListener(name, handler[0] = e => handlerFn.call(node, handler[1], e));
149
150
  } else node.addEventListener(name, handler);
150
151
  }
151
152
  function classList(node, value, prev = {}) {
@@ -309,14 +310,24 @@ function assignProp(node, prop, value, prev, isSVG, skipRef) {
309
310
  value(node);
310
311
  }
311
312
  } else if (prop.slice(0, 3) === "on:") {
312
- node.addEventListener(prop.slice(3), value);
313
+ const e = prop.slice(3);
314
+ prev && node.removeEventListener(e, prev);
315
+ value && node.addEventListener(e, value);
313
316
  } else if (prop.slice(0, 10) === "oncapture:") {
314
- node.addEventListener(prop.slice(10), value, true);
317
+ const e = prop.slice(10);
318
+ prev && node.removeEventListener(e, prev, true);
319
+ value && node.addEventListener(e, value, true);
315
320
  } else if (prop.slice(0, 2) === "on") {
316
321
  const name = prop.slice(2).toLowerCase();
317
322
  const delegate = DelegatedEvents.has(name);
318
- addEventListener(node, name, value, delegate);
319
- delegate && delegateEvents([name]);
323
+ if (!delegate && prev) {
324
+ const h = Array.isArray(prev) ? prev[0] : prev;
325
+ node.removeEventListener(name, h);
326
+ }
327
+ if (delegate || value) {
328
+ addEventListener(node, name, value, delegate);
329
+ delegate && delegateEvents([name]);
330
+ }
320
331
  } else if ((isChildProp = ChildProperties.has(prop)) || !isSVG && (PropAliases[prop] || (isProp = Properties.has(prop))) || (isCE = node.nodeName.includes("-"))) {
321
332
  if (prop === "class" || prop === "className") className(node, value);else if (isCE && !isProp && !isChildProp) node[toPropertyName(prop)] = value;else node[PropAliases[prop] || prop] = value;
322
333
  } else {
@@ -348,7 +359,7 @@ function eventHandler(e) {
348
359
  const handler = node[key];
349
360
  if (handler && !node.disabled) {
350
361
  const data = node[`${key}Data`];
351
- data !== undefined ? handler(data, e) : handler(e);
362
+ data !== undefined ? handler.call(node, data, e) : handler.call(node, e);
352
363
  if (e.cancelBubble) return;
353
364
  }
354
365
  node = node.host && node.host !== node && node.host instanceof Node ? node.host : node.parentNode;
@@ -396,7 +407,8 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
396
407
  return () => current;
397
408
  } else if (Array.isArray(value)) {
398
409
  const array = [];
399
- if (normalizeIncomingArray(array, value, unwrapArray)) {
410
+ const currentArray = current && Array.isArray(current);
411
+ if (normalizeIncomingArray(array, value, current, unwrapArray)) {
400
412
  solidJs.createRenderEffect(() => current = insertExpression(parent, array, current, marker, true));
401
413
  return () => current;
402
414
  }
@@ -408,7 +420,7 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
408
420
  if (array.length === 0) {
409
421
  current = cleanChildren(parent, current, marker);
410
422
  if (multi) return current;
411
- } else if (Array.isArray(current)) {
423
+ } else if (currentArray) {
412
424
  if (current.length === 0) {
413
425
  appendNodes(parent, array, marker);
414
426
  } else reconcileArrays(parent, current, array);
@@ -429,26 +441,30 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
429
441
  } else ;
430
442
  return current;
431
443
  }
432
- function normalizeIncomingArray(normalized, array, unwrap) {
444
+ function normalizeIncomingArray(normalized, array, current, unwrap) {
433
445
  let dynamic = false;
434
446
  for (let i = 0, len = array.length; i < len; i++) {
435
447
  let item = array[i],
448
+ prev = current && current[i],
436
449
  t;
437
450
  if (item instanceof Node) {
438
451
  normalized.push(item);
439
452
  } else if (item == null || item === true || item === false) ; else if (Array.isArray(item)) {
440
- dynamic = normalizeIncomingArray(normalized, item) || dynamic;
441
- } else if ((t = typeof item) === "string") {
442
- normalized.push(document.createTextNode(item));
443
- } else if (t === "function") {
453
+ dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic;
454
+ } else if ((t = typeof item) === "function") {
444
455
  if (unwrap) {
445
456
  while (typeof item === "function") item = item();
446
- dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item]) || dynamic;
457
+ dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], prev) || dynamic;
447
458
  } else {
448
459
  normalized.push(item);
449
460
  dynamic = true;
450
461
  }
451
- } else normalized.push(document.createTextNode(item.toString()));
462
+ } else {
463
+ const value = t === "string" ? item : item.string();
464
+ if (prev && prev.nodeType === 3 && prev.data === value) {
465
+ normalized.push(prev);
466
+ } else normalized.push(document.createTextNode(value));
467
+ }
452
468
  }
453
469
  return dynamic;
454
470
  }
@@ -507,7 +523,7 @@ function resolveSSRNode(node) {}
507
523
  function ssrClassList(value) {}
508
524
  function ssrStyle(value) {}
509
525
  function ssrSpread(accessor) {}
510
- function ssrBoolean(key, value) {}
526
+ function ssrAttribute(key, value) {}
511
527
  function ssrHydrationKey() {}
512
528
  function escape(html) {}
513
529
  function generateHydrationScript() {}
@@ -560,8 +576,9 @@ function Portal(props) {
560
576
  }
561
577
  function Dynamic(props) {
562
578
  const [p, others] = solidJs.splitProps(props, ["component"]);
579
+ const cached = solidJs.createMemo(() => p.component);
563
580
  return solidJs.createMemo(() => {
564
- const component = p.component;
581
+ const component = cached();
565
582
  switch (typeof component) {
566
583
  case "function":
567
584
  return solidJs.untrack(() => component(others));
@@ -663,7 +680,7 @@ exports.setAttribute = setAttribute;
663
680
  exports.setAttributeNS = setAttributeNS;
664
681
  exports.spread = spread;
665
682
  exports.ssr = ssr;
666
- exports.ssrBoolean = ssrBoolean;
683
+ exports.ssrAttribute = ssrAttribute;
667
684
  exports.ssrClassList = ssrClassList;
668
685
  exports.ssrHydrationKey = ssrHydrationKey;
669
686
  exports.ssrSpread = ssrSpread;
package/web/dist/web.js CHANGED
@@ -2,8 +2,8 @@ import { createMemo, createRoot, createRenderEffect, sharedConfig, enableHydrati
2
2
  export { ErrorBoundary, For, Index, Match, Show, Suspense, SuspenseList, Switch, createComponent, createRenderEffect as effect, getOwner, mergeProps } from 'solid-js';
3
3
 
4
4
  const booleans = ["allowfullscreen", "async", "autofocus", "autoplay", "checked", "controls", "default", "disabled", "formnovalidate", "hidden", "indeterminate", "ismap", "loop", "multiple", "muted", "nomodule", "novalidate", "open", "playsinline", "readonly", "required", "reversed", "seamless", "selected"];
5
- const Properties = new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]);
6
- const ChildProperties = new Set(["innerHTML", "textContent", "innerText", "children"]);
5
+ const Properties = /*#__PURE__*/new Set(["className", "value", "readOnly", "formNoValidate", "isMap", "noModule", "playsInline", ...booleans]);
6
+ const ChildProperties = /*#__PURE__*/new Set(["innerHTML", "textContent", "innerText", "children"]);
7
7
  const Aliases = {
8
8
  className: "class",
9
9
  htmlFor: "for"
@@ -16,8 +16,8 @@ const PropAliases = {
16
16
  playsinline: "playsInline",
17
17
  readonly: "readOnly"
18
18
  };
19
- const DelegatedEvents = new Set(["beforeinput", "click", "dblclick", "contextmenu", "focusin", "focusout", "input", "keydown", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "pointerdown", "pointermove", "pointerout", "pointerover", "pointerup", "touchend", "touchmove", "touchstart"]);
20
- const SVGElements = new Set([
19
+ 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"]);
20
+ const SVGElements = /*#__PURE__*/new Set([
21
21
  "altGlyph", "altGlyphDef", "altGlyphItem", "animate", "animateColor", "animateMotion", "animateTransform", "circle", "clipPath", "color-profile", "cursor", "defs", "desc", "ellipse", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting", "feDisplacementMap", "feDistantLight", "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",
22
22
  "set", "stop",
23
23
  "svg", "switch", "symbol", "text", "textPath",
@@ -26,7 +26,7 @@ const SVGNamespace = {
26
26
  xlink: "http://www.w3.org/1999/xlink",
27
27
  xml: "http://www.w3.org/XML/1998/namespace"
28
28
  };
29
- const DOMElements = new Set(["html", "base", "head", "link", "meta", "style", "title", "body", "address", "article", "aside", "footer", "header", "main", "nav", "section", "body", "blockquote", "dd", "div", "dl", "dt", "figcaption", "figure", "hr", "li", "ol", "p", "pre", "ul", "a", "abbr", "b", "bdi", "bdo", "br", "cite", "code", "data", "dfn", "em", "i", "kbd", "mark", "q", "rp", "rt", "ruby", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "u", "var", "wbr", "area", "audio", "img", "map", "track", "video", "embed", "iframe", "object", "param", "picture", "portal", "source", "svg", "math", "canvas", "noscript", "script", "del", "ins", "caption", "col", "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "button", "datalist", "fieldset", "form", "input", "label", "legend", "meter", "optgroup", "option", "output", "progress", "select", "textarea", "details", "dialog", "menu", "summary", "details", "slot", "template", "acronym", "applet", "basefont", "bgsound", "big", "blink", "center", "content", "dir", "font", "frame", "frameset", "hgroup", "image", "keygen", "marquee", "menuitem", "nobr", "noembed", "noframes", "plaintext", "rb", "rtc", "shadow", "spacer", "strike", "tt", "xmp", "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "nav", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "portal", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp", "input"]);
29
+ const DOMElements = /*#__PURE__*/new Set(["html", "base", "head", "link", "meta", "style", "title", "body", "address", "article", "aside", "footer", "header", "main", "nav", "section", "body", "blockquote", "dd", "div", "dl", "dt", "figcaption", "figure", "hr", "li", "ol", "p", "pre", "ul", "a", "abbr", "b", "bdi", "bdo", "br", "cite", "code", "data", "dfn", "em", "i", "kbd", "mark", "q", "rp", "rt", "ruby", "s", "samp", "small", "span", "strong", "sub", "sup", "time", "u", "var", "wbr", "area", "audio", "img", "map", "track", "video", "embed", "iframe", "object", "param", "picture", "portal", "source", "svg", "math", "canvas", "noscript", "script", "del", "ins", "caption", "col", "colgroup", "table", "tbody", "td", "tfoot", "th", "thead", "tr", "button", "datalist", "fieldset", "form", "input", "label", "legend", "meter", "optgroup", "option", "output", "progress", "select", "textarea", "details", "dialog", "menu", "summary", "details", "slot", "template", "acronym", "applet", "basefont", "bgsound", "big", "blink", "center", "content", "dir", "font", "frame", "frameset", "hgroup", "image", "keygen", "marquee", "menuitem", "nobr", "noembed", "noframes", "plaintext", "rb", "rtc", "shadow", "spacer", "strike", "tt", "xmp", "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "col", "colgroup", "content", "data", "datalist", "dd", "del", "details", "dfn", "dialog", "dir", "div", "dl", "dt", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", "head", "header", "hgroup", "hr", "html", "i", "iframe", "image", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "nav", "nobr", "noembed", "noframes", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "picture", "plaintext", "portal", "pre", "progress", "q", "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "script", "section", "select", "shadow", "slot", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp", "input"]);
30
30
 
31
31
  function memo(fn, equals) {
32
32
  return createMemo(fn, undefined, !equals ? {
@@ -142,7 +142,8 @@ function addEventListener(node, name, handler, delegate) {
142
142
  node[`$$${name}Data`] = handler[1];
143
143
  } else node[`$$${name}`] = handler;
144
144
  } else if (Array.isArray(handler)) {
145
- node.addEventListener(name, e => handler[0](handler[1], e));
145
+ const handlerFn = handler[0];
146
+ node.addEventListener(name, handler[0] = e => handlerFn.call(node, handler[1], e));
146
147
  } else node.addEventListener(name, handler);
147
148
  }
148
149
  function classList(node, value, prev = {}) {
@@ -306,14 +307,24 @@ function assignProp(node, prop, value, prev, isSVG, skipRef) {
306
307
  value(node);
307
308
  }
308
309
  } else if (prop.slice(0, 3) === "on:") {
309
- node.addEventListener(prop.slice(3), value);
310
+ const e = prop.slice(3);
311
+ prev && node.removeEventListener(e, prev);
312
+ value && node.addEventListener(e, value);
310
313
  } else if (prop.slice(0, 10) === "oncapture:") {
311
- node.addEventListener(prop.slice(10), value, true);
314
+ const e = prop.slice(10);
315
+ prev && node.removeEventListener(e, prev, true);
316
+ value && node.addEventListener(e, value, true);
312
317
  } else if (prop.slice(0, 2) === "on") {
313
318
  const name = prop.slice(2).toLowerCase();
314
319
  const delegate = DelegatedEvents.has(name);
315
- addEventListener(node, name, value, delegate);
316
- delegate && delegateEvents([name]);
320
+ if (!delegate && prev) {
321
+ const h = Array.isArray(prev) ? prev[0] : prev;
322
+ node.removeEventListener(name, h);
323
+ }
324
+ if (delegate || value) {
325
+ addEventListener(node, name, value, delegate);
326
+ delegate && delegateEvents([name]);
327
+ }
317
328
  } else if ((isChildProp = ChildProperties.has(prop)) || !isSVG && (PropAliases[prop] || (isProp = Properties.has(prop))) || (isCE = node.nodeName.includes("-"))) {
318
329
  if (prop === "class" || prop === "className") className(node, value);else if (isCE && !isProp && !isChildProp) node[toPropertyName(prop)] = value;else node[PropAliases[prop] || prop] = value;
319
330
  } else {
@@ -345,7 +356,7 @@ function eventHandler(e) {
345
356
  const handler = node[key];
346
357
  if (handler && !node.disabled) {
347
358
  const data = node[`${key}Data`];
348
- data !== undefined ? handler(data, e) : handler(e);
359
+ data !== undefined ? handler.call(node, data, e) : handler.call(node, e);
349
360
  if (e.cancelBubble) return;
350
361
  }
351
362
  node = node.host && node.host !== node && node.host instanceof Node ? node.host : node.parentNode;
@@ -393,7 +404,8 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
393
404
  return () => current;
394
405
  } else if (Array.isArray(value)) {
395
406
  const array = [];
396
- if (normalizeIncomingArray(array, value, unwrapArray)) {
407
+ const currentArray = current && Array.isArray(current);
408
+ if (normalizeIncomingArray(array, value, current, unwrapArray)) {
397
409
  createRenderEffect(() => current = insertExpression(parent, array, current, marker, true));
398
410
  return () => current;
399
411
  }
@@ -405,7 +417,7 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
405
417
  if (array.length === 0) {
406
418
  current = cleanChildren(parent, current, marker);
407
419
  if (multi) return current;
408
- } else if (Array.isArray(current)) {
420
+ } else if (currentArray) {
409
421
  if (current.length === 0) {
410
422
  appendNodes(parent, array, marker);
411
423
  } else reconcileArrays(parent, current, array);
@@ -426,26 +438,30 @@ function insertExpression(parent, value, current, marker, unwrapArray) {
426
438
  } else ;
427
439
  return current;
428
440
  }
429
- function normalizeIncomingArray(normalized, array, unwrap) {
441
+ function normalizeIncomingArray(normalized, array, current, unwrap) {
430
442
  let dynamic = false;
431
443
  for (let i = 0, len = array.length; i < len; i++) {
432
444
  let item = array[i],
445
+ prev = current && current[i],
433
446
  t;
434
447
  if (item instanceof Node) {
435
448
  normalized.push(item);
436
449
  } else if (item == null || item === true || item === false) ; else if (Array.isArray(item)) {
437
- dynamic = normalizeIncomingArray(normalized, item) || dynamic;
438
- } else if ((t = typeof item) === "string") {
439
- normalized.push(document.createTextNode(item));
440
- } else if (t === "function") {
450
+ dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic;
451
+ } else if ((t = typeof item) === "function") {
441
452
  if (unwrap) {
442
453
  while (typeof item === "function") item = item();
443
- dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item]) || dynamic;
454
+ dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], prev) || dynamic;
444
455
  } else {
445
456
  normalized.push(item);
446
457
  dynamic = true;
447
458
  }
448
- } else normalized.push(document.createTextNode(item.toString()));
459
+ } else {
460
+ const value = t === "string" ? item : item.string();
461
+ if (prev && prev.nodeType === 3 && prev.data === value) {
462
+ normalized.push(prev);
463
+ } else normalized.push(document.createTextNode(value));
464
+ }
449
465
  }
450
466
  return dynamic;
451
467
  }
@@ -504,7 +520,7 @@ function resolveSSRNode(node) {}
504
520
  function ssrClassList(value) {}
505
521
  function ssrStyle(value) {}
506
522
  function ssrSpread(accessor) {}
507
- function ssrBoolean(key, value) {}
523
+ function ssrAttribute(key, value) {}
508
524
  function ssrHydrationKey() {}
509
525
  function escape(html) {}
510
526
  function generateHydrationScript() {}
@@ -557,8 +573,9 @@ function Portal(props) {
557
573
  }
558
574
  function Dynamic(props) {
559
575
  const [p, others] = splitProps(props, ["component"]);
576
+ const cached = createMemo(() => p.component);
560
577
  return createMemo(() => {
561
- const component = p.component;
578
+ const component = cached();
562
579
  switch (typeof component) {
563
580
  case "function":
564
581
  return untrack(() => component(others));
@@ -571,4 +588,4 @@ function Dynamic(props) {
571
588
  });
572
589
  }
573
590
 
574
- export { Aliases, Assets, ChildProperties, DOMElements, DelegatedEvents, Dynamic, Assets as HydrationScript, NoHydration, Portal, PropAliases, Properties, SVGElements, SVGNamespace, addEventListener, assign, classList, className, clearDelegatedEvents, delegateEvents, dynamicProperty, escape, generateHydrationScript, getHydrationKey, getNextElement, getNextMarker, getNextMatch, hydrate, innerHTML, insert, isServer, memo, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, setAttribute, setAttributeNS, spread, ssr, ssrBoolean, ssrClassList, ssrHydrationKey, ssrSpread, ssrStyle, style, template };
591
+ export { Aliases, Assets, ChildProperties, DOMElements, DelegatedEvents, Dynamic, Assets as HydrationScript, NoHydration, Portal, PropAliases, Properties, SVGElements, SVGNamespace, addEventListener, assign, classList, className, clearDelegatedEvents, delegateEvents, dynamicProperty, escape, generateHydrationScript, getHydrationKey, getNextElement, getNextMarker, getNextMatch, hydrate, innerHTML, insert, isServer, memo, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, setAttribute, setAttributeNS, spread, ssr, ssrAttribute, ssrClassList, ssrHydrationKey, ssrSpread, ssrStyle, style, template };