@constela/runtime 0.18.2 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +118 -4
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -199,12 +199,14 @@ function setValueAtPath(obj, path, value) {
199
199
  if (path.length === 0) return value;
200
200
  const head2 = path[0];
201
201
  const rest = path.slice(1);
202
- const isArrayIndex = typeof head2 === "number";
203
202
  let clone3;
204
- if (isArrayIndex) {
205
- clone3 = Array.isArray(obj) ? [...obj] : [];
203
+ if (Array.isArray(obj)) {
204
+ clone3 = [...obj];
205
+ } else if (obj != null && typeof obj === "object") {
206
+ clone3 = { ...obj };
206
207
  } else {
207
- clone3 = obj != null && typeof obj === "object" ? { ...obj } : {};
208
+ const isArrayIndex = typeof head2 === "number" || typeof head2 === "string" && /^\d+$/.test(head2);
209
+ clone3 = isArrayIndex ? [] : {};
208
210
  }
209
211
  const objRecord = obj;
210
212
  clone3[head2] = setValueAtPath(
@@ -14625,6 +14627,86 @@ function createReactiveLocals2(baseLocals, itemSignal, indexSignal, itemName, in
14625
14627
  }
14626
14628
  });
14627
14629
  }
14630
+ function createLocalStateStore2(stateDefs) {
14631
+ const signals = {};
14632
+ for (const [name, def] of Object.entries(stateDefs)) {
14633
+ signals[name] = createSignal(def.initial);
14634
+ }
14635
+ return {
14636
+ get(name) {
14637
+ return signals[name]?.get();
14638
+ },
14639
+ set(name, value) {
14640
+ signals[name]?.set(value);
14641
+ },
14642
+ signals
14643
+ };
14644
+ }
14645
+ function createLocalsWithLocalState2(baseLocals, localStore) {
14646
+ return new Proxy(baseLocals, {
14647
+ get(target, prop) {
14648
+ if (prop in localStore.signals) {
14649
+ return localStore.get(prop);
14650
+ }
14651
+ return target[prop];
14652
+ },
14653
+ has(target, prop) {
14654
+ if (prop in localStore.signals) return true;
14655
+ return prop in target;
14656
+ },
14657
+ ownKeys(target) {
14658
+ const keys = Reflect.ownKeys(target);
14659
+ for (const key2 of Object.keys(localStore.signals)) {
14660
+ if (!keys.includes(key2)) keys.push(key2);
14661
+ }
14662
+ return keys;
14663
+ },
14664
+ getOwnPropertyDescriptor(target, prop) {
14665
+ if (prop in localStore.signals) {
14666
+ return { enumerable: true, configurable: true };
14667
+ }
14668
+ return Reflect.getOwnPropertyDescriptor(target, prop);
14669
+ }
14670
+ });
14671
+ }
14672
+ function createStateWithLocalState2(globalState, localStore) {
14673
+ return {
14674
+ get(name) {
14675
+ if (name in localStore.signals) {
14676
+ return localStore.get(name);
14677
+ }
14678
+ return globalState.get(name);
14679
+ },
14680
+ set(name, value) {
14681
+ if (name in localStore.signals) {
14682
+ localStore.set(name, value);
14683
+ return;
14684
+ }
14685
+ globalState.set(name, value);
14686
+ },
14687
+ setPath(name, path, value) {
14688
+ globalState.setPath(name, path, value);
14689
+ },
14690
+ subscribe(name, fn) {
14691
+ if (name in localStore.signals) {
14692
+ return localStore.signals[name].subscribe(fn);
14693
+ }
14694
+ return globalState.subscribe(name, fn);
14695
+ },
14696
+ getPath(name, path) {
14697
+ return globalState.getPath(name, path);
14698
+ },
14699
+ subscribeToPath(name, path, fn) {
14700
+ return globalState.subscribeToPath(name, path, fn);
14701
+ },
14702
+ serialize() {
14703
+ return globalState.serialize();
14704
+ },
14705
+ restore(snapshot, newDefinitions) {
14706
+ globalState.restore(snapshot, newDefinitions);
14707
+ }
14708
+ };
14709
+ }
14628
14710
  function isEventHandler2(value) {
14629
14711
  return typeof value === "object" && value !== null && "event" in value && "action" in value;
14630
14712
  }
@@ -14719,10 +14801,37 @@ function hydrate(node, domNode, ctx) {
14719
14801
  case "markdown":
14720
14802
  case "code":
14721
14803
  break;
14804
+ case "localState":
14805
+ hydrateLocalState(node, domNode, ctx);
14806
+ break;
14722
14807
  default:
14723
14808
  break;
14724
14809
  }
14725
14810
  }
14811
+ function hydrateLocalState(node, domNode, ctx) {
14812
+ const localStore = createLocalStateStore2(node.state);
14813
+ const mergedLocals = createLocalsWithLocalState2(ctx.locals, localStore);
14814
+ const mergedState = createStateWithLocalState2(ctx.state, localStore);
14815
+ const mergedActions = { ...ctx.actions };
14816
+ for (const [name, action] of Object.entries(node.actions)) {
14817
+ mergedActions[name] = {
14818
+ ...action,
14819
+ _isLocalAction: true,
14820
+ _localStore: localStore
14821
+ };
14822
+ }
14823
+ const childCtx = {
14824
+ ...ctx,
14825
+ state: mergedState,
14826
+ locals: mergedLocals,
14827
+ actions: mergedActions,
14828
+ localState: {
14829
+ store: localStore,
14830
+ actions: node.actions
14831
+ }
14832
+ };
14833
+ hydrate(node.child, domNode, childCtx);
14834
+ }
14726
14835
  function hydrateElement(node, el, ctx) {
14727
14836
  if (node.ref && ctx.refs) {
14728
14837
  ctx.refs[node.ref] = el;
@@ -14818,6 +14927,11 @@ function hydrateChildren(children, parent, ctx) {
14818
14927
  if (domChild && domChild.nodeType === Node.TEXT_NODE) {
14819
14928
  hydrateTextGroup(textNodes, domChild, ctx);
14820
14929
  domIndex++;
14930
+ } else {
14931
+ const textNode = document.createTextNode("");
14932
+ const insertBefore = domChildren[domIndex] || null;
14933
+ parent.insertBefore(textNode, insertBefore);
14934
+ hydrateTextGroup(textNodes, textNode, ctx);
14821
14935
  }
14822
14936
  } else if (childNode.kind === "element") {
14823
14937
  const domChild = domChildren[domIndex];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/runtime",
3
- "version": "0.18.2",
3
+ "version": "0.19.0",
4
4
  "description": "Runtime DOM renderer for Constela UI framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",