@oddo/lang 0.0.9 → 0.0.11

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/dist/index.js CHANGED
@@ -3586,7 +3586,7 @@ var traverse = _traverse3.default.default || _traverse3.default;
3586
3586
  function isValidJSIdentifier(name) {
3587
3587
  return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
3588
3588
  }
3589
- function wrapDependenciesWithCalls(arrowFunc, deps) {
3589
+ function wrapDependenciesWithCalls(arrowFunc, deps, prefix = "") {
3590
3590
  const depSet = new Set(deps);
3591
3591
  const locals = /* @__PURE__ */ new Set();
3592
3592
  const tempFile = t.file(t.program([t.expressionStatement(arrowFunc)]));
@@ -3602,6 +3602,14 @@ function wrapDependenciesWithCalls(arrowFunc, deps) {
3602
3602
  const shorthandToExpand = [];
3603
3603
  traverse(tempFile, {
3604
3604
  noScope: true,
3605
+ // Skip already-processed reactive expression calls - don't modify their deps arrays
3606
+ // These have the pattern: _x(fn, deps) or _computed(fn, deps) or similar
3607
+ CallExpression(path) {
3608
+ const callee = path.node.callee;
3609
+ if (t.isIdentifier(callee) && callee.name.startsWith("_") && path.node.arguments.length === 2 && t.isArrowFunctionExpression(path.node.arguments[0]) && t.isArrayExpression(path.node.arguments[1])) {
3610
+ path.skip();
3611
+ }
3612
+ },
3605
3613
  Identifier(path) {
3606
3614
  var _a;
3607
3615
  if (t.isArrowFunctionExpression(path.parent) && path.parent.params.includes(path.node)) {
@@ -3631,9 +3639,9 @@ function wrapDependenciesWithCalls(arrowFunc, deps) {
3631
3639
  });
3632
3640
  shorthandToExpand.forEach(({ prop, name }) => {
3633
3641
  prop.shorthand = false;
3634
- prop.value = t.callExpression(t.identifier(name), []);
3642
+ prop.value = t.callExpression(t.identifier(prefix + name), []);
3635
3643
  });
3636
- toReplace.forEach((p) => p.replaceWith(t.callExpression(t.identifier(p.node.name), [])));
3644
+ toReplace.forEach((p) => p.replaceWith(t.callExpression(t.identifier(prefix + p.node.name), [])));
3637
3645
  }
3638
3646
  function getReactiveDeps(identifiers) {
3639
3647
  return identifiers.filter((id) => {
@@ -3670,7 +3678,7 @@ function createLiftedExpr(valueExpr, identifiers) {
3670
3678
  );
3671
3679
  }
3672
3680
  function createReactiveExpr(oddoExpr, valueExpr, attrExpression = false) {
3673
- const allIdentifiers = collectOddoIdentifiersOnly(oddoExpr);
3681
+ const allIdentifiers = collectOddoIdentifiersOnly(oddoExpr, /* @__PURE__ */ new Set(), true);
3674
3682
  const identifiers = allIdentifiers.filter((id) => isReactive(id));
3675
3683
  const pragma = attrExpression ? "computed" : "x";
3676
3684
  if (identifiers.length === 0) {
@@ -3685,10 +3693,10 @@ function createReactiveExpr(oddoExpr, valueExpr, attrExpression = false) {
3685
3693
  );
3686
3694
  }
3687
3695
  usedModifiers.add(pragma);
3688
- const params = identifiers.map((id) => t.identifier(id));
3696
+ const params = identifiers.map((id) => t.identifier("_" + id));
3689
3697
  const deps = identifiers.map((id) => t.identifier(id));
3690
3698
  const arrowFunc = t.arrowFunctionExpression(params, valueExpr);
3691
- wrapDependenciesWithCalls(arrowFunc, identifiers);
3699
+ wrapDependenciesWithCalls(arrowFunc, identifiers, "_");
3692
3700
  return t.callExpression(
3693
3701
  t.identifier(modifierAliases[pragma]),
3694
3702
  [arrowFunc, t.arrayExpression(deps)]
@@ -3698,10 +3706,29 @@ var MODIFIER_TRANSFORMATIONS = {
3698
3706
  state: {
3699
3707
  needsImport: true,
3700
3708
  // @state x = 3 -> const [x, setX] = _state(3);
3701
- transform: (valueExpr, leftExpr) => {
3709
+ // @state x = reactiveVar -> const [x, setX] = _state(_lift(_reactiveVar => _reactiveVar(), [reactiveVar]));
3710
+ // Receives Oddo AST, extracts deps, lifts if needed
3711
+ transform: (oddoExpr, leftExpr) => {
3712
+ const allIdentifiers = collectOddoIdentifiersOnly(oddoExpr);
3713
+ const reactiveDeps = allIdentifiers.filter((id) => isReactive(id));
3714
+ const convertedExpr = convertExpression2(oddoExpr);
3715
+ let stateArg;
3716
+ if (reactiveDeps.length > 0) {
3717
+ usedModifiers.add("lift");
3718
+ const prefixedParams = reactiveDeps.map((id) => t.identifier("_" + id));
3719
+ const deps = reactiveDeps.map((id) => t.identifier(id));
3720
+ const arrowFunc = t.arrowFunctionExpression(prefixedParams, convertedExpr);
3721
+ wrapDependenciesWithCalls(arrowFunc, reactiveDeps, "_");
3722
+ stateArg = t.callExpression(
3723
+ t.identifier(modifierAliases["lift"]),
3724
+ [arrowFunc, t.arrayExpression(deps)]
3725
+ );
3726
+ } else {
3727
+ stateArg = convertedExpr;
3728
+ }
3702
3729
  const stateCall = t.callExpression(
3703
3730
  t.identifier(modifierAliases["state"]),
3704
- [valueExpr]
3731
+ [stateArg]
3705
3732
  );
3706
3733
  if (leftExpr && t.isIdentifier(leftExpr)) {
3707
3734
  const getterName = leftExpr.name;
@@ -3717,6 +3744,19 @@ var MODIFIER_TRANSFORMATIONS = {
3717
3744
  stateCall
3718
3745
  )
3719
3746
  ]);
3747
+ } else if (leftExpr && t.isArrayPattern(leftExpr) && leftExpr.elements.length === 2) {
3748
+ const getterName = leftExpr.elements[0].name;
3749
+ const setterName = leftExpr.elements[1].name;
3750
+ stateSetterMap.set(getterName, setterName);
3751
+ return t.variableDeclaration("const", [
3752
+ t.variableDeclarator(
3753
+ t.arrayPattern([
3754
+ t.identifier(getterName),
3755
+ t.identifier(setterName)
3756
+ ]),
3757
+ stateCall
3758
+ )
3759
+ ]);
3720
3760
  }
3721
3761
  return t.expressionStatement(stateCall);
3722
3762
  }
@@ -4019,7 +4059,7 @@ var moduleScope = null;
4019
4059
  var currentScope = null;
4020
4060
  var reactiveScope = /* @__PURE__ */ Symbol("reactive-scope");
4021
4061
  function declareVariable(name, type) {
4022
- const reactive = type === "state" || type === "computed" || type === "param" || type === "import-oddo";
4062
+ const reactive = type === "state" || type === "computed" || type === "reactive-param" || type === "import-oddo";
4023
4063
  currentScope[name] = { type, reactive };
4024
4064
  }
4025
4065
  function isDeclared(name) {
@@ -4074,7 +4114,7 @@ function generateUniqueId(baseName) {
4074
4114
  return candidate;
4075
4115
  }
4076
4116
  function collectOddoIdentifiers(node, names = /* @__PURE__ */ new Set()) {
4077
- var _a, _b, _c, _d;
4117
+ var _a, _b, _c, _d, _e, _f;
4078
4118
  if (!node || typeof node !== "object") return names;
4079
4119
  if (node.type === "program") {
4080
4120
  moduleScope = /* @__PURE__ */ Object.create(null);
@@ -4085,15 +4125,21 @@ function collectOddoIdentifiers(node, names = /* @__PURE__ */ new Set()) {
4085
4125
  names.add(node.name);
4086
4126
  }
4087
4127
  if (node.type === "expressionStatement") {
4088
- const varName = (_b = (_a = node.expression) == null ? void 0 : _a.left) == null ? void 0 : _b.name;
4089
- if (varName) {
4128
+ const left = (_a = node.expression) == null ? void 0 : _a.left;
4129
+ const varName = left == null ? void 0 : left.name;
4130
+ if (node.modifier === "state" && (left == null ? void 0 : left.type) === "arrayPattern" && ((_b = left.elements) == null ? void 0 : _b.length) === 2) {
4131
+ const getterName = (_c = left.elements[0]) == null ? void 0 : _c.name;
4132
+ const setterName = (_d = left.elements[1]) == null ? void 0 : _d.name;
4133
+ if (getterName) declareVariable(getterName, "state");
4134
+ if (setterName) declareVariable(setterName, "immutable");
4135
+ } else if (varName) {
4090
4136
  if (node.modifier === "state") {
4091
4137
  declareVariable(varName, "state");
4092
4138
  } else if (node.modifier === "computed") {
4093
4139
  declareVariable(varName, "computed");
4094
4140
  } else if (node.modifier === "mutable") {
4095
4141
  declareVariable(varName, "mutable");
4096
- } else if (!node.modifier && ((_c = node.expression) == null ? void 0 : _c.type) === "variableDeclaration") {
4142
+ } else if (!node.modifier && ((_e = node.expression) == null ? void 0 : _e.type) === "variableDeclaration") {
4097
4143
  declareVariable(varName, "immutable");
4098
4144
  }
4099
4145
  }
@@ -4125,7 +4171,7 @@ function collectOddoIdentifiers(node, names = /* @__PURE__ */ new Set()) {
4125
4171
  for (const name of boundNames) {
4126
4172
  declareVariable(name, "param");
4127
4173
  }
4128
- } else if (param.type === "restElement" && ((_d = param.argument) == null ? void 0 : _d.name)) {
4174
+ } else if (param.type === "restElement" && ((_f = param.argument) == null ? void 0 : _f.name)) {
4129
4175
  declareVariable(param.argument.name, "param");
4130
4176
  }
4131
4177
  }
@@ -4268,13 +4314,13 @@ function convertExpressionStatement2(stmt) {
4268
4314
  let leftExpr = null;
4269
4315
  if (stmt.expression.type === "variableDeclaration" || stmt.expression.type === "assignment") {
4270
4316
  leftExpr = convertExpression2(stmt.expression.left);
4271
- if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook") {
4317
+ if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook" || stmt.modifier === "state") {
4272
4318
  valueExpr = stmt.expression.right;
4273
4319
  } else {
4274
4320
  valueExpr = convertExpression2(stmt.expression.right);
4275
4321
  }
4276
4322
  } else {
4277
- if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook") {
4323
+ if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook" || stmt.modifier === "state") {
4278
4324
  valueExpr = stmt.expression;
4279
4325
  } else {
4280
4326
  valueExpr = convertExpression2(stmt.expression);
@@ -4295,13 +4341,13 @@ function convertExpressionStatement2(stmt) {
4295
4341
  let leftExpr = null;
4296
4342
  if (blockStmt.expression.type === "variableDeclaration" || blockStmt.expression.type === "assignment") {
4297
4343
  leftExpr = convertExpression2(blockStmt.expression.left);
4298
- if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook") {
4344
+ if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook" || stmt.modifier === "state") {
4299
4345
  valueExpr = blockStmt.expression.right;
4300
4346
  } else {
4301
4347
  valueExpr = convertExpression2(blockStmt.expression.right);
4302
4348
  }
4303
4349
  } else {
4304
- if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook") {
4350
+ if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook" || stmt.modifier === "state") {
4305
4351
  valueExpr = blockStmt.expression;
4306
4352
  } else {
4307
4353
  valueExpr = convertExpression2(blockStmt.expression);
@@ -4345,7 +4391,31 @@ function convertExpressionStatement2(stmt) {
4345
4391
  }
4346
4392
  let expression = null;
4347
4393
  if (stmt.expression) {
4348
- expression = convertExpression2(stmt.expression);
4394
+ const isPlainExpr = stmt.expression.type !== "variableDeclaration" && stmt.expression.type !== "assignment" && stmt.expression.type !== "arraySliceAssignment";
4395
+ if (isPlainExpr) {
4396
+ const allIdentifiers = collectOddoIdentifiersOnly(stmt.expression);
4397
+ const reactiveDeps = allIdentifiers.filter((id) => isReactive(id));
4398
+ if (reactiveDeps.length > 0) {
4399
+ const savedScope = currentScope;
4400
+ currentScope = Object.create(currentScope);
4401
+ currentScope[reactiveScope] = false;
4402
+ const convertedExpr = convertExpression2(stmt.expression);
4403
+ currentScope = savedScope;
4404
+ usedModifiers.add("lift");
4405
+ const prefixedParams = reactiveDeps.map((id) => t.identifier("_" + id));
4406
+ const deps = reactiveDeps.map((id) => t.identifier(id));
4407
+ const arrowFunc = t.arrowFunctionExpression(prefixedParams, convertedExpr);
4408
+ wrapDependenciesWithCalls(arrowFunc, reactiveDeps, "_");
4409
+ expression = t.callExpression(
4410
+ t.identifier(modifierAliases["lift"]),
4411
+ [arrowFunc, t.arrayExpression(deps)]
4412
+ );
4413
+ } else {
4414
+ expression = convertExpression2(stmt.expression);
4415
+ }
4416
+ } else {
4417
+ expression = convertExpression2(stmt.expression);
4418
+ }
4349
4419
  }
4350
4420
  if (stmt.block) {
4351
4421
  const block = convertBlockStatement(stmt.block);
@@ -4596,17 +4666,20 @@ function convertReactiveContainer(expr) {
4596
4666
  currentScope = savedScope;
4597
4667
  return t.functionExpression(null, params, body);
4598
4668
  }
4599
- function collectOddoIdentifiersOnly(node, names = /* @__PURE__ */ new Set()) {
4669
+ function collectOddoIdentifiersOnly(node, names = /* @__PURE__ */ new Set(), stopAtJsxExpressions = false) {
4600
4670
  if (!node || typeof node !== "object") return Array.from(names);
4671
+ if (stopAtJsxExpressions && node.type === "jsxExpression") {
4672
+ return Array.from(names);
4673
+ }
4601
4674
  if (node.type === "identifier") {
4602
4675
  names.add(node.name);
4603
4676
  }
4604
4677
  if (node.type === "property") {
4605
4678
  if (node.computed && node.key) {
4606
- collectOddoIdentifiersOnly(node.key, names);
4679
+ collectOddoIdentifiersOnly(node.key, names, stopAtJsxExpressions);
4607
4680
  }
4608
4681
  if (node.value) {
4609
- collectOddoIdentifiersOnly(node.value, names);
4682
+ collectOddoIdentifiersOnly(node.value, names, stopAtJsxExpressions);
4610
4683
  }
4611
4684
  return Array.from(names);
4612
4685
  }
@@ -4614,9 +4687,9 @@ function collectOddoIdentifiersOnly(node, names = /* @__PURE__ */ new Set()) {
4614
4687
  if (key === "type") continue;
4615
4688
  const val = node[key];
4616
4689
  if (Array.isArray(val)) {
4617
- val.forEach((item) => collectOddoIdentifiersOnly(item, names));
4690
+ val.forEach((item) => collectOddoIdentifiersOnly(item, names, stopAtJsxExpressions));
4618
4691
  } else if (val && typeof val === "object") {
4619
- collectOddoIdentifiersOnly(val, names);
4692
+ collectOddoIdentifiersOnly(val, names, stopAtJsxExpressions);
4620
4693
  }
4621
4694
  }
4622
4695
  return Array.from(names);