@estjs/template 0.0.15-beta.12 → 0.0.15-beta.13

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.
@@ -1,5 +1,5 @@
1
- import { error, isHTMLElement, isPrimitive, isFalsy, isNull, isObject, isArray, isHtmlInputElement, isHtmlSelectElement, isHtmlTextAreaElement, isFunction, coerceArray, hasChanged, isPromise, startsWith, isString, isBrowser, normalizeClassName, camelCase, capitalize, warn, isSpecialBooleanAttr, isBooleanAttr, includeBooleanAttr, isSymbol, isUndefined, isNumber, isTextNode } from '@estjs/shared';
2
- import { effect, shallowReactive, isSignal, isComputed, signal } from '@estjs/signals';
1
+ import { error, isHTMLElement, isPrimitive, isFalsy, isNull, isObject, isArray, isHtmlInputElement, isHtmlSelectElement, isHtmlTextAreaElement, isFunction, hasChanged, isPromise, coerceArray, startsWith, isString, isBrowser, normalizeClassName, camelCase, capitalize, warn, isSpecialBooleanAttr, isBooleanAttr, includeBooleanAttr, isSymbol, isUndefined, isNumber, isTextNode } from '@estjs/shared';
2
+ import { effect, shallowReactive, isSignal, isComputed, signal, memoEffect, untrack } from '@estjs/signals';
3
3
 
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -155,6 +155,7 @@ var NORMAL_COMPONENT = /* @__PURE__ */ Symbol("Normal Component" );
155
155
  var FRAGMENT_COMPONENT = /* @__PURE__ */ Symbol("Fragment Component" );
156
156
  var PORTAL_COMPONENT = /* @__PURE__ */ Symbol("Portal Component" );
157
157
  var SUSPENSE_COMPONENT = /* @__PURE__ */ Symbol("Suspense Component" );
158
+ var FOR_COMPONENT = /* @__PURE__ */ Symbol("For Component" );
158
159
  var MAX_KEY_LENGTH = 1e3;
159
160
  var componentKeyPrefixCache = /* @__PURE__ */ new WeakMap();
160
161
  function getComponentKey(type) {
@@ -282,60 +283,46 @@ function shallowCompare(a, b) {
282
283
  if (isArray(a) !== isArray(b)) return false;
283
284
  const aRecord = a;
284
285
  const bRecord = b;
285
- for (const key in aRecord) {
286
- if (aRecord[key] !== bRecord[key]) return false;
287
- }
288
- for (const key in bRecord) {
289
- if (!(key in aRecord)) return false;
286
+ const aKeys = Object.keys(aRecord);
287
+ const bKeys = Object.keys(bRecord);
288
+ if (aKeys.length !== bKeys.length) return false;
289
+ for (const key of aKeys) {
290
+ if (!(key in bRecord) || aRecord[key] !== bRecord[key]) {
291
+ return false;
292
+ }
290
293
  }
291
294
  return true;
292
295
  }
293
296
  function removeNode(node) {
294
297
  if (!node) return;
295
- try {
296
- if (isComponent(node)) {
297
- node.destroy();
298
- } else {
299
- const element = node;
300
- if (element.parentElement) {
301
- element.remove();
302
- }
303
- }
304
- } catch (_error) {
305
- error("Failed to remove node:", _error);
298
+ if (isComponent(node)) {
299
+ node.destroy();
300
+ return;
301
+ }
302
+ const element = node;
303
+ if (element.parentElement) {
304
+ element.remove();
306
305
  }
307
306
  }
308
307
  function insertNode(parent, child, before) {
309
308
  if (!parent || !child) return;
310
- try {
311
- const beforeNode = isComponent(before) ? before.firstChild : before;
312
- if (isComponent(child)) {
313
- child.mount(parent, beforeNode);
314
- return;
315
- }
316
- if (beforeNode) {
317
- parent.insertBefore(child, beforeNode);
318
- } else {
319
- if (true) {
320
- if (!child) {
321
- error("insertNode: child is not a Node", child);
322
- }
323
- }
324
- parent.appendChild(child);
325
- }
326
- } catch (_error) {
327
- error("Failed to insert node:", _error);
309
+ if (isComponent(child)) {
310
+ const beforeNode2 = isComponent(before) ? before.firstChild : before;
311
+ child.mount(parent, beforeNode2);
312
+ return;
313
+ }
314
+ const beforeNode = isComponent(before) ? before.firstChild : before;
315
+ if (beforeNode) {
316
+ parent.insertBefore(child, beforeNode);
317
+ } else {
318
+ parent.appendChild(child);
328
319
  }
329
320
  }
330
321
  function replaceNode(parent, newNode, oldNode) {
331
322
  if (!parent || !newNode || !oldNode || newNode === oldNode) return;
332
- try {
333
- const beforeNode = isComponent(oldNode) ? oldNode.beforeNode : oldNode.nextSibling;
334
- removeNode(oldNode);
335
- insertNode(parent, newNode, beforeNode);
336
- } catch (_error) {
337
- error("Failed to replace node:", _error);
338
- }
323
+ const beforeNode = isComponent(oldNode) ? oldNode.beforeNode : oldNode.nextSibling;
324
+ removeNode(oldNode);
325
+ insertNode(parent, newNode, beforeNode);
339
326
  }
340
327
  function getFirstDOMNode(node) {
341
328
  if (!node) {
@@ -716,10 +703,18 @@ function bindSelectElement(node, setter) {
716
703
  function insert(parent, nodeFactory, before) {
717
704
  if (!parent) return;
718
705
  let renderedNodes = [];
706
+ const currentScope = getActiveScope();
719
707
  const cleanup = effect(() => {
720
- const rawNodes = isFunction(nodeFactory) ? nodeFactory() : nodeFactory;
721
- const nodes = coerceArray(rawNodes).map((item) => isFunction(item) ? item() : item).flatMap(normalizeNode);
722
- renderedNodes = patchChildren(parent, renderedNodes, nodes, before);
708
+ const run = () => {
709
+ const rawNodes = isFunction(nodeFactory) ? nodeFactory() : nodeFactory;
710
+ const nodes = coerceArray(rawNodes).map((item) => isFunction(item) ? item() : item).flatMap(normalizeNode);
711
+ renderedNodes = patchChildren(parent, renderedNodes, nodes, before);
712
+ };
713
+ if (currentScope) {
714
+ runWithScope(currentScope, run);
715
+ } else {
716
+ run();
717
+ }
723
718
  });
724
719
  onCleanup(() => {
725
720
  cleanup();
@@ -891,7 +886,7 @@ var Component = class {
891
886
  return void 0;
892
887
  }
893
888
  mount(parentNode, beforeNode) {
894
- var _a2;
889
+ var _a2, _b;
895
890
  this.parentNode = parentNode;
896
891
  this.beforeNode = beforeNode;
897
892
  this.state = 1 /* MOUNTING */;
@@ -902,27 +897,21 @@ var Component = class {
902
897
  this.state = 2 /* MOUNTED */;
903
898
  return this.renderedNodes;
904
899
  }
905
- const parent = (_a2 = this.parentScope) != null ? _a2 : getActiveScope();
906
- this.scope = createScope(parent);
907
- const renderedNodes = runWithScope(this.scope, () => {
908
- var _a3;
909
- let result = this.component(this.reactiveProps);
910
- if (isFunction(result)) {
911
- result = result(this.reactiveProps);
912
- }
913
- if (isSignal(result) || isComputed(result)) {
914
- result = result.value;
915
- }
916
- return (_a3 = insert(parentNode, result, beforeNode)) != null ? _a3 : [];
917
- });
900
+ const parentScope = (_a2 = this.parentScope) != null ? _a2 : getActiveScope();
901
+ this.scope = createScope(parentScope);
902
+ setActiveScope(this.scope);
903
+ let result = this.component(this.reactiveProps);
904
+ if (isFunction(result)) {
905
+ result = result(this.reactiveProps);
906
+ }
907
+ if (isSignal(result) || isComputed(result)) {
908
+ result = result.value;
909
+ }
910
+ const renderedNodes = (_b = insert(parentNode, result, beforeNode)) != null ? _b : [];
918
911
  this.renderedNodes = renderedNodes;
919
- runWithScope(this.scope, () => {
920
- this.applyProps(this.props);
921
- });
912
+ this.applyProps(this.props);
922
913
  this.state = 2 /* MOUNTED */;
923
- if (this.scope) {
924
- triggerMountHooks(this.scope);
925
- }
914
+ triggerMountHooks(this.scope);
926
915
  return this.renderedNodes;
927
916
  }
928
917
  update(prevNode) {
@@ -944,9 +933,8 @@ var Component = class {
944
933
  return this;
945
934
  }
946
935
  if (this.scope) {
947
- runWithScope(this.scope, () => {
948
- this.applyProps(this.props);
949
- });
936
+ setActiveScope(this.scope);
937
+ this.applyProps(this.props);
950
938
  triggerUpdateHooks(this.scope);
951
939
  }
952
940
  return this;
@@ -1020,9 +1008,9 @@ var Component = class {
1020
1008
  if (this.scope) {
1021
1009
  triggerUpdateHooks(this.scope);
1022
1010
  }
1023
- } catch (error9) {
1011
+ } catch (error8) {
1024
1012
  this.renderedNodes = originalNodes;
1025
- throw error9;
1013
+ throw error8;
1026
1014
  }
1027
1015
  }
1028
1016
  /**
@@ -1047,14 +1035,14 @@ var Component = class {
1047
1035
  return;
1048
1036
  }
1049
1037
  this.state = 4 /* DESTROYING */;
1038
+ for (const node of this.renderedNodes) {
1039
+ removeNode(node);
1040
+ }
1050
1041
  const scope = this.scope;
1051
1042
  if (scope) {
1052
1043
  disposeScope(scope);
1053
1044
  this.scope = null;
1054
1045
  }
1055
- for (const node of this.renderedNodes) {
1056
- removeNode(node);
1057
- }
1058
1046
  this.renderedNodes = [];
1059
1047
  this.parentNode = void 0;
1060
1048
  this.beforeNode = void 0;
@@ -1709,9 +1697,9 @@ function Suspense(props) {
1709
1697
  if (pendingCount === 0) {
1710
1698
  showChildren();
1711
1699
  }
1712
- }).catch((error9) => {
1700
+ }).catch((error8) => {
1713
1701
  {
1714
- warn("[Suspense] Resource failed:", error9);
1702
+ warn("[Suspense] Resource failed:", error8);
1715
1703
  }
1716
1704
  if (!isMounted) return;
1717
1705
  pendingCount--;
@@ -1759,7 +1747,7 @@ function isSuspense(node) {
1759
1747
  function createResource(fetcher, options) {
1760
1748
  const value = signal(options == null ? void 0 : options.initialValue);
1761
1749
  const loading = signal(true);
1762
- const error9 = signal(null);
1750
+ const error8 = signal(null);
1763
1751
  const state = signal("pending");
1764
1752
  let fetchId = 0;
1765
1753
  let currentPromise = null;
@@ -1767,7 +1755,7 @@ function createResource(fetcher, options) {
1767
1755
  const currentFetchId = ++fetchId;
1768
1756
  loading.value = true;
1769
1757
  state.value = "pending";
1770
- error9.value = null;
1758
+ error8.value = null;
1771
1759
  try {
1772
1760
  const promise = fetcher();
1773
1761
  currentPromise = promise.then(() => {
@@ -1781,7 +1769,7 @@ function createResource(fetcher, options) {
1781
1769
  }
1782
1770
  } catch (error_) {
1783
1771
  if (currentFetchId === fetchId) {
1784
- error9.value = error_ instanceof Error ? error_ : new Error(String(error_));
1772
+ error8.value = error_ instanceof Error ? error_ : new Error(String(error_));
1785
1773
  state.value = "errored";
1786
1774
  loading.value = false;
1787
1775
  }
@@ -1798,14 +1786,14 @@ function createResource(fetcher, options) {
1798
1786
  return value.value;
1799
1787
  });
1800
1788
  resource.loading = loading;
1801
- resource.error = error9;
1789
+ resource.error = error8;
1802
1790
  resource.state = state;
1803
1791
  const actions = {
1804
1792
  mutate: (newValue) => {
1805
1793
  value.value = newValue;
1806
1794
  state.value = "ready";
1807
1795
  loading.value = false;
1808
- error9.value = null;
1796
+ error8.value = null;
1809
1797
  },
1810
1798
  refetch: () => __async(null, null, function* () {
1811
1799
  yield fetch();
@@ -1813,7 +1801,173 @@ function createResource(fetcher, options) {
1813
1801
  };
1814
1802
  return [resource, actions];
1815
1803
  }
1804
+ function For(props) {
1805
+ const fragment = document.createDocumentFragment();
1806
+ const marker = document.createComment("");
1807
+ fragment.appendChild(marker);
1808
+ let entries = [];
1809
+ let fallbackNode = null;
1810
+ const keyFn = props.keyFn;
1811
+ const renderFn = props.children;
1812
+ const getList = () => {
1813
+ var _a2, _b;
1814
+ const input = props.each;
1815
+ if (isSignal(input)) return (_a2 = input.value) != null ? _a2 : [];
1816
+ if (typeof input === "function") return (_b = input()) != null ? _b : [];
1817
+ return input != null ? input : [];
1818
+ };
1819
+ const getKey = (item) => keyFn ? keyFn(item) : item;
1820
+ const renderItem = (item, index, parent, before) => {
1821
+ var _a2;
1822
+ const prevScope = getActiveScope();
1823
+ const scope = createScope(prevScope);
1824
+ setActiveScope(scope);
1825
+ let node;
1826
+ try {
1827
+ const result = renderFn(item, index);
1828
+ if (isComponent(result)) {
1829
+ result.mount(parent, before);
1830
+ node = (_a2 = result.firstChild) != null ? _a2 : document.createComment("empty");
1831
+ } else {
1832
+ node = result;
1833
+ if (!node.parentNode) {
1834
+ if (before) {
1835
+ parent.insertBefore(node, before);
1836
+ } else {
1837
+ parent.appendChild(node);
1838
+ }
1839
+ }
1840
+ }
1841
+ } finally {
1842
+ setActiveScope(prevScope);
1843
+ }
1844
+ return { key: getKey(item), node, scope };
1845
+ };
1846
+ const disposeItem = (entry) => {
1847
+ disposeScope(entry.scope);
1848
+ if (entry.node.parentNode) {
1849
+ entry.node.parentNode.removeChild(entry.node);
1850
+ }
1851
+ };
1852
+ memoEffect(
1853
+ ({ prev }) => {
1854
+ var _a2;
1855
+ const newItems = getList();
1856
+ if (prev === newItems) return { prev: newItems };
1857
+ const parent = marker.parentNode;
1858
+ if (!parent) {
1859
+ if (newItems.length === 0) {
1860
+ if (props.fallback) {
1861
+ const fb = props.fallback();
1862
+ if (isComponent(fb)) {
1863
+ fb.mount(fragment, marker);
1864
+ fallbackNode = (_a2 = fb.firstChild) != null ? _a2 : document.createComment("empty");
1865
+ } else {
1866
+ fallbackNode = fb;
1867
+ fragment.insertBefore(fallbackNode, marker);
1868
+ }
1869
+ }
1870
+ return { prev: newItems };
1871
+ }
1872
+ entries = new Array(newItems.length);
1873
+ for (const [i, newItem] of newItems.entries()) {
1874
+ entries[i] = renderItem(newItem, i, fragment, marker);
1875
+ }
1876
+ return { prev: newItems };
1877
+ }
1878
+ untrack(() => reconcile(parent, newItems));
1879
+ return { prev: newItems };
1880
+ },
1881
+ {
1882
+ prev: []
1883
+ }
1884
+ );
1885
+ function reconcile(parent, newItems) {
1886
+ var _a2;
1887
+ const oldLen = entries.length;
1888
+ const newLen = newItems.length;
1889
+ if (newLen === 0) {
1890
+ for (let i = 0; i < oldLen; i++) {
1891
+ disposeItem(entries[i]);
1892
+ }
1893
+ entries = [];
1894
+ if (props.fallback && !fallbackNode) {
1895
+ const fb = props.fallback();
1896
+ if (isComponent(fb)) {
1897
+ fb.mount(parent, marker);
1898
+ fallbackNode = (_a2 = fb.firstChild) != null ? _a2 : document.createComment("empty");
1899
+ } else {
1900
+ fallbackNode = fb;
1901
+ parent.insertBefore(fallbackNode, marker);
1902
+ }
1903
+ }
1904
+ return;
1905
+ }
1906
+ if (oldLen === 0 || fallbackNode) {
1907
+ if (fallbackNode) {
1908
+ if (fallbackNode.parentNode) fallbackNode.parentNode.removeChild(fallbackNode);
1909
+ fallbackNode = null;
1910
+ }
1911
+ entries = new Array(newLen);
1912
+ const batchFragment2 = document.createDocumentFragment();
1913
+ for (let i = 0; i < newLen; i++) {
1914
+ entries[i] = renderItem(newItems[i], i, batchFragment2, null);
1915
+ }
1916
+ parent.insertBefore(batchFragment2, marker);
1917
+ return;
1918
+ }
1919
+ const oldKeyMap = /* @__PURE__ */ new Map();
1920
+ for (let i = 0; i < oldLen; i++) {
1921
+ const entry = entries[i];
1922
+ const list = oldKeyMap.get(entry.key);
1923
+ if (list) {
1924
+ list.push(entry);
1925
+ } else {
1926
+ oldKeyMap.set(entry.key, [entry]);
1927
+ }
1928
+ }
1929
+ const newEntries = new Array(newLen);
1930
+ const toRemove = [];
1931
+ const batchFragment = document.createDocumentFragment();
1932
+ for (let i = 0; i < newLen; i++) {
1933
+ const item = newItems[i];
1934
+ const key = getKey(item);
1935
+ const oldList = oldKeyMap.get(key);
1936
+ if (oldList && oldList.length > 0) {
1937
+ newEntries[i] = oldList.shift();
1938
+ } else {
1939
+ newEntries[i] = renderItem(item, i, batchFragment, null);
1940
+ }
1941
+ }
1942
+ for (const list of oldKeyMap.values()) {
1943
+ for (const entry of list) {
1944
+ toRemove.push(entry);
1945
+ }
1946
+ }
1947
+ for (const entry of toRemove) {
1948
+ disposeItem(entry);
1949
+ }
1950
+ for (let i = 0; i < newLen; i++) {
1951
+ const node = newEntries[i].node;
1952
+ parent.insertBefore(node, marker);
1953
+ }
1954
+ entries = newEntries;
1955
+ }
1956
+ onCleanup(() => {
1957
+ for (const entry of entries) {
1958
+ disposeItem(entry);
1959
+ }
1960
+ if (fallbackNode && fallbackNode.parentNode) {
1961
+ fallbackNode.parentNode.removeChild(fallbackNode);
1962
+ }
1963
+ if (marker.parentNode) {
1964
+ marker.parentNode.removeChild(marker);
1965
+ }
1966
+ });
1967
+ return fragment;
1968
+ }
1969
+ For[FOR_COMPONENT] = true;
1816
1970
 
1817
- export { Component, Fragment, Portal, Suspense, addEvent, addEventListener, bindElement, createApp, createComponent, createResource, createScope, delegateEvents, disposeScope, endHydration, getActiveScope, getFirstDOMNode, getHydrationKey, getRenderedElement, hydrate, inject, insert, insertNode, isComponent, isFragment, isHydrating, isPortal, isSameNode, isSuspense, mapNodes, mapSSRNodes, normalizeClass, normalizeNode, omitProps, onCleanup, onDestroy, onMount, onUpdate, patchAttr, patchClass, patchStyle, provide, removeNode, replaceNode, resetHydrationKey, runWithScope, setActiveScope, setStyle, shallowCompare, startHydration, template };
1971
+ export { Component, For, Fragment, Portal, Suspense, addEvent, addEventListener, bindElement, createApp, createComponent, createResource, createScope, delegateEvents, disposeScope, endHydration, getActiveScope, getFirstDOMNode, getHydrationKey, getRenderedElement, hydrate, inject, insert, insertNode, isComponent, isFragment, isHydrating, isPortal, isSameNode, isSuspense, mapNodes, mapSSRNodes, normalizeClass, normalizeNode, omitProps, onCleanup, onDestroy, onMount, onUpdate, patchAttr, patchClass, patchStyle, provide, removeNode, replaceNode, resetHydrationKey, runWithScope, setActiveScope, setStyle, shallowCompare, startHydration, template };
1818
1972
  //# sourceMappingURL=template.dev.esm.js.map
1819
1973
  //# sourceMappingURL=template.dev.esm.js.map