@constela/runtime 0.16.5 → 0.16.6

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 (2) hide show
  1. package/dist/index.js +158 -0
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -14539,6 +14539,8 @@ function hydrateChildren(children, parent, ctx) {
14539
14539
  hydrate(childNode, firstDomChild, ctx);
14540
14540
  domIndex += itemCount;
14541
14541
  }
14542
+ } else {
14543
+ hydrateEachEmpty(childNode, parent, domChildren[domIndex] || null, ctx);
14542
14544
  }
14543
14545
  } else {
14544
14546
  const domChild = domChildren[domIndex];
@@ -14766,6 +14768,162 @@ function hydrateIfWithoutDom(node, parent, nextSibling, ctx, branchInfo) {
14766
14768
  }
14767
14769
  });
14768
14770
  }
14771
+ function hydrateEachEmpty(node, parent, insertBefore, ctx) {
14772
+ const anchor = document.createComment("each");
14773
+ if (insertBefore) {
14774
+ parent.insertBefore(anchor, insertBefore);
14775
+ } else {
14776
+ parent.appendChild(anchor);
14777
+ }
14778
+ const hasKey = !!node.key;
14779
+ let itemStateMap = /* @__PURE__ */ new Map();
14780
+ let currentNodes = [];
14781
+ let itemCleanups = [];
14782
+ const effectCleanup = createEffect(() => {
14783
+ const items = evaluate(node.items, {
14784
+ state: ctx.state,
14785
+ locals: ctx.locals,
14786
+ ...ctx.imports && { imports: ctx.imports },
14787
+ ...ctx.route && { route: ctx.route }
14788
+ });
14789
+ if (!hasKey || !node.key) {
14790
+ for (const cleanup of itemCleanups) {
14791
+ cleanup();
14792
+ }
14793
+ itemCleanups = [];
14794
+ for (const oldNode of currentNodes) {
14795
+ if (oldNode.parentNode) {
14796
+ oldNode.parentNode.removeChild(oldNode);
14797
+ }
14798
+ }
14799
+ currentNodes = [];
14800
+ if (Array.isArray(items)) {
14801
+ items.forEach((item, index) => {
14802
+ const itemLocals = {
14803
+ ...ctx.locals,
14804
+ [node.as]: item
14805
+ };
14806
+ if (node.index) {
14807
+ itemLocals[node.index] = index;
14808
+ }
14809
+ const localCleanups = [];
14810
+ const itemCtx = {
14811
+ state: ctx.state,
14812
+ actions: ctx.actions,
14813
+ locals: itemLocals,
14814
+ cleanups: localCleanups,
14815
+ ...ctx.imports && { imports: ctx.imports }
14816
+ };
14817
+ const itemNode = render(node.body, itemCtx);
14818
+ currentNodes.push(itemNode);
14819
+ itemCleanups.push(...localCleanups);
14820
+ if (anchor.parentNode) {
14821
+ let refNode = anchor.nextSibling;
14822
+ if (currentNodes.length > 1) {
14823
+ const lastExisting = currentNodes[currentNodes.length - 2];
14824
+ if (lastExisting) {
14825
+ refNode = lastExisting.nextSibling;
14826
+ }
14827
+ }
14828
+ anchor.parentNode.insertBefore(itemNode, refNode);
14829
+ }
14830
+ });
14831
+ }
14832
+ return;
14833
+ }
14834
+ const newItemStateMap = /* @__PURE__ */ new Map();
14835
+ const newNodes = [];
14836
+ const seenKeys = /* @__PURE__ */ new Set();
14837
+ if (Array.isArray(items)) {
14838
+ items.forEach((item, index) => {
14839
+ const tempLocals = {
14840
+ ...ctx.locals,
14841
+ [node.as]: item,
14842
+ ...node.index ? { [node.index]: index } : {}
14843
+ };
14844
+ const keyValue = evaluate(node.key, {
14845
+ state: ctx.state,
14846
+ locals: tempLocals,
14847
+ ...ctx.imports && { imports: ctx.imports },
14848
+ ...ctx.route && { route: ctx.route }
14849
+ });
14850
+ if (seenKeys.has(keyValue)) {
14851
+ if (typeof process !== "undefined" && process.env?.["NODE_ENV"] !== "production") {
14852
+ console.warn(`Duplicate key "${keyValue}" in each loop. Keys should be unique.`);
14853
+ }
14854
+ }
14855
+ seenKeys.add(keyValue);
14856
+ const existingState = itemStateMap.get(keyValue);
14857
+ if (existingState) {
14858
+ existingState.itemSignal.set(item);
14859
+ existingState.indexSignal.set(index);
14860
+ newItemStateMap.set(keyValue, existingState);
14861
+ newNodes.push(existingState.node);
14862
+ } else {
14863
+ const itemSignal = createSignal(item);
14864
+ const indexSignal = createSignal(index);
14865
+ const reactiveLocals = createReactiveLocals2(
14866
+ ctx.locals,
14867
+ itemSignal,
14868
+ indexSignal,
14869
+ node.as,
14870
+ node.index
14871
+ );
14872
+ const localCleanups = [];
14873
+ const itemCtx = {
14874
+ state: ctx.state,
14875
+ actions: ctx.actions,
14876
+ locals: reactiveLocals,
14877
+ cleanups: localCleanups,
14878
+ ...ctx.imports && { imports: ctx.imports }
14879
+ };
14880
+ const itemNode = render(node.body, itemCtx);
14881
+ const newState = {
14882
+ key: keyValue,
14883
+ node: itemNode,
14884
+ cleanups: localCleanups,
14885
+ itemSignal,
14886
+ indexSignal
14887
+ };
14888
+ newItemStateMap.set(keyValue, newState);
14889
+ newNodes.push(itemNode);
14890
+ }
14891
+ });
14892
+ }
14893
+ for (const [key2, state] of itemStateMap) {
14894
+ if (!newItemStateMap.has(key2)) {
14895
+ for (const cleanup of state.cleanups) {
14896
+ cleanup();
14897
+ }
14898
+ if (state.node.parentNode) {
14899
+ state.node.parentNode.removeChild(state.node);
14900
+ }
14901
+ }
14902
+ }
14903
+ if (anchor.parentNode) {
14904
+ let refNode = anchor;
14905
+ for (const itemNode of newNodes) {
14906
+ const nextSibling = refNode.nextSibling;
14907
+ if (nextSibling !== itemNode) {
14908
+ anchor.parentNode.insertBefore(itemNode, refNode.nextSibling);
14909
+ }
14910
+ refNode = itemNode;
14911
+ }
14912
+ }
14913
+ itemStateMap = newItemStateMap;
14914
+ currentNodes = newNodes;
14915
+ itemCleanups = [];
14916
+ for (const state of itemStateMap.values()) {
14917
+ itemCleanups.push(...state.cleanups);
14918
+ }
14919
+ });
14920
+ ctx.cleanups.push(effectCleanup);
14921
+ ctx.cleanups.push(() => {
14922
+ for (const cleanup of itemCleanups) {
14923
+ cleanup();
14924
+ }
14925
+ });
14926
+ }
14769
14927
  function hydrateEach(node, firstItemDomNode, ctx) {
14770
14928
  const parent = firstItemDomNode.parentNode;
14771
14929
  if (!parent) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/runtime",
3
- "version": "0.16.5",
3
+ "version": "0.16.6",
4
4
  "description": "Runtime DOM renderer for Constela UI framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",