octane 0.13.4 → 0.13.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.
@@ -21,7 +21,7 @@ __export(version_exports, {
21
21
  version: () => version
22
22
  });
23
23
  module.exports = __toCommonJS(version_exports);
24
- const version = "0.13.4";
24
+ const version = "0.13.5";
25
25
  // Annotate the CommonJS export names for ESM import in node:
26
26
  0 && (module.exports = {
27
27
  version
@@ -3872,7 +3872,9 @@ const CALCULATION_VALUE_PROOFS = [
3872
3872
  * a pure projection from template evaluation to the end of setup is
3873
3873
  * unobservable. Positions whose evaluation is conditional or deferred keep
3874
3874
  * their expression: directive arms, component children (the child decides
3875
- * whether and when they render), and built-in boundaries. An expression holding
3875
+ * whether and when they render), and built-in boundaries. Already-evaluated
3876
+ * named literals can still be read at eligible props inside component children;
3877
+ * only their identifier reads are collected there. An expression holding
3876
3878
  * JSX keeps its list and descriptor lowering, and event handlers and keys keep
3877
3879
  * their wiring. Ref arrays use the same identity proof as props. A render tree that writes to anything keeps its whole
3878
3880
  * evaluation order.
@@ -3887,27 +3889,27 @@ function hoistStrongRenderCalculations(jsxNodes, ctx, immutableStates, literalsO
3887
3889
  const declarations = [];
3888
3890
  const names = [];
3889
3891
  const literalReads = new Map();
3890
- const nodes = mapNodes(jsxNodes, visitNode);
3892
+ const nodes = mapNodes(jsxNodes, (node) => visitNode(node, false));
3891
3893
  return declarations.length === 0 && literalReads.size === 0
3892
3894
  ? null
3893
3895
  : { jsxNodes: nodes, declarations, names, literalReads };
3894
3896
 
3895
- function visitNode(node) {
3897
+ function visitNode(node, deferred) {
3896
3898
  switch (node?.type) {
3897
3899
  case 'JSXElement':
3898
- return visitElement(node);
3900
+ return visitElement(node, deferred);
3899
3901
  case 'JSXFragment': {
3900
- const children = mapNodes(node.children, visitNode);
3902
+ const children = mapNodes(node.children, (child) => visitNode(child, deferred));
3901
3903
  return children === node.children ? node : { ...node, children };
3902
3904
  }
3903
3905
  case 'JSXExpressionContainer':
3904
- return visitContainer(node);
3906
+ return deferred ? node : visitContainer(node);
3905
3907
  default:
3906
3908
  return node;
3907
3909
  }
3908
3910
  }
3909
3911
 
3910
- function visitElement(node) {
3912
+ function visitElement(node, deferred) {
3911
3913
  const opening = node.openingElement;
3912
3914
  const tag = opening?.name;
3913
3915
  const component = isComponentTag(node);
@@ -3942,11 +3944,12 @@ function hoistStrongRenderCalculations(jsxNodes, ctx, immutableStates, literalsO
3942
3944
  return attribute;
3943
3945
  if (!component && /^on[A-Z]/.test(name)) return attribute;
3944
3946
  if (attribute.value?.type !== 'JSXExpressionContainer') return attribute;
3945
- const value = visitContainer(attribute.value, true);
3947
+ const value = visitContainer(attribute.value, true, deferred);
3946
3948
  return value === attribute.value ? attribute : { ...attribute, value };
3947
3949
  });
3948
- // Component children render inside the child, if at all.
3949
- const children = component ? node.children : mapNodes(node.children, visitNode);
3950
+ // Component children own evaluation. Discover named reads without moving
3951
+ // any expression from those children into the parent's render.
3952
+ const children = mapNodes(node.children, (child) => visitNode(child, deferred || component));
3950
3953
  if (attributes === opening.attributes && children === node.children) return node;
3951
3954
  return {
3952
3955
  ...node,
@@ -3955,7 +3958,7 @@ function hoistStrongRenderCalculations(jsxNodes, ctx, immutableStates, literalsO
3955
3958
  };
3956
3959
  }
3957
3960
 
3958
- function visitContainer(container, prop = false) {
3961
+ function visitContainer(container, prop = false, deferred = false) {
3959
3962
  const expression = container.expression;
3960
3963
  const inner = unwrapTsExpr(expression);
3961
3964
  if (!inner || inner.type === 'JSXEmptyExpression' || containsJsxNode(inner)) return container;
@@ -3964,6 +3967,7 @@ function hoistStrongRenderCalculations(jsxNodes, ctx, immutableStates, literalsO
3964
3967
  if (!nodes) literalReads.set(inner.name, (nodes = new Set()));
3965
3968
  nodes.add(inner);
3966
3969
  }
3970
+ if (deferred) return container;
3967
3971
  const calculation = autoCalculationOf(
3968
3972
  inner,
3969
3973
  null,
@@ -1,4 +1,4 @@
1
- const version = "0.13.4";
1
+ const version = "0.13.5";
2
2
  export {
3
3
  version
4
4
  };
package/dist/version.js CHANGED
@@ -1,4 +1,4 @@
1
- const version = "0.13.4";
1
+ const version = "0.13.5";
2
2
  export {
3
3
  version
4
4
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "octane",
3
- "version": "0.13.4",
3
+ "version": "0.13.5",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": [