@oddo/lang 0.0.7 → 0.0.9

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,71 +3586,6 @@ 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 extractIdentifiers(babelNode) {
3590
- const identifiers = /* @__PURE__ */ new Set();
3591
- const locals = /* @__PURE__ */ new Set();
3592
- function traverse2(node) {
3593
- var _a, _b, _c;
3594
- if (!node) return;
3595
- if (t.isIdentifier(node)) {
3596
- if (!locals.has(node.name) && !node.name.startsWith("__ODDO_IMPORT_")) {
3597
- identifiers.add(node.name);
3598
- }
3599
- } else if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
3600
- traverse2(node.object);
3601
- if (node.computed) traverse2(node.property);
3602
- } else if (t.isCallExpression(node) || t.isOptionalCallExpression(node)) {
3603
- traverse2(node.callee);
3604
- (_a = node.arguments) == null ? void 0 : _a.forEach((arg) => traverse2(arg));
3605
- } else if (t.isBinaryExpression(node) || t.isLogicalExpression(node)) {
3606
- traverse2(node.left);
3607
- traverse2(node.right);
3608
- } else if (t.isUnaryExpression(node)) {
3609
- traverse2(node.argument);
3610
- } else if (t.isConditionalExpression(node)) {
3611
- traverse2(node.test);
3612
- traverse2(node.consequent);
3613
- traverse2(node.alternate);
3614
- } else if (t.isArrayExpression(node)) {
3615
- (_b = node.elements) == null ? void 0 : _b.forEach((el) => traverse2(el));
3616
- } else if (t.isObjectExpression(node)) {
3617
- (_c = node.properties) == null ? void 0 : _c.forEach((prop) => {
3618
- if (t.isObjectProperty(prop)) {
3619
- if (prop.computed) traverse2(prop.key);
3620
- traverse2(prop.value);
3621
- } else if (t.isSpreadElement(prop)) {
3622
- traverse2(prop.argument);
3623
- }
3624
- });
3625
- } else if (t.isArrowFunctionExpression(node)) {
3626
- node.params.forEach((p) => {
3627
- var _a2;
3628
- if (t.isIdentifier(p)) locals.add(p.name);
3629
- else if (t.isObjectPattern(p)) p.properties.forEach((prop) => t.isIdentifier(prop.value) && locals.add(prop.value.name));
3630
- else if (t.isArrayPattern(p)) (_a2 = p.elements) == null ? void 0 : _a2.forEach((el) => t.isIdentifier(el) && locals.add(el.name));
3631
- });
3632
- if (t.isBlockStatement(node.body)) node.body.body.forEach((s) => traverse2(s));
3633
- else traverse2(node.body);
3634
- } else if (t.isBlockStatement(node)) {
3635
- node.body.forEach((s) => traverse2(s));
3636
- } else if (t.isExpressionStatement(node)) {
3637
- traverse2(node.expression);
3638
- } else if (t.isReturnStatement(node)) {
3639
- traverse2(node.argument);
3640
- } else if (t.isSequenceExpression(node)) {
3641
- node.expressions.forEach((expr) => traverse2(expr));
3642
- } else if (t.isUpdateExpression(node)) {
3643
- traverse2(node.argument);
3644
- } else if (t.isAssignmentExpression(node)) {
3645
- traverse2(node.left);
3646
- traverse2(node.right);
3647
- } else if (t.isSpreadElement(node)) {
3648
- traverse2(node.argument);
3649
- }
3650
- }
3651
- traverse2(babelNode);
3652
- return Array.from(identifiers);
3653
- }
3654
3589
  function wrapDependenciesWithCalls(arrowFunc, deps) {
3655
3590
  const depSet = new Set(deps);
3656
3591
  const locals = /* @__PURE__ */ new Set();
@@ -3734,9 +3669,9 @@ function createLiftedExpr(valueExpr, identifiers) {
3734
3669
  [arrowFunc, t.arrayExpression(depsArray)]
3735
3670
  );
3736
3671
  }
3737
- function createReactiveExpr(valueExpr, attrExpression = false) {
3738
- const allIdentifiers = extractIdentifiers(valueExpr);
3739
- const identifiers = getReactiveDeps(allIdentifiers);
3672
+ function createReactiveExpr(oddoExpr, valueExpr, attrExpression = false) {
3673
+ const allIdentifiers = collectOddoIdentifiersOnly(oddoExpr);
3674
+ const identifiers = allIdentifiers.filter((id) => isReactive(id));
3740
3675
  const pragma = attrExpression ? "computed" : "x";
3741
3676
  if (identifiers.length === 0) {
3742
3677
  if (t.isLiteral(valueExpr)) {
@@ -3789,9 +3724,15 @@ var MODIFIER_TRANSFORMATIONS = {
3789
3724
  computed: {
3790
3725
  needsImport: true,
3791
3726
  // @computed sum = x + y -> const sum = _computed((x, y) => x() + y(), [x, y])
3792
- transform: (valueExpr, leftExpr) => {
3793
- const allIds = extractIdentifiers(valueExpr);
3794
- const identifiers = getReactiveDeps(allIds);
3727
+ // Receives Oddo AST, extracts deps from Oddo, converts internally
3728
+ transform: (oddoExpr, leftExpr) => {
3729
+ const allIds = collectOddoIdentifiersOnly(oddoExpr);
3730
+ const identifiers = allIds.filter((id) => isReactive(id));
3731
+ const savedScope = currentScope;
3732
+ currentScope = Object.create(currentScope);
3733
+ currentScope[reactiveScope] = false;
3734
+ const valueExpr = convertExpression2(oddoExpr);
3735
+ currentScope = savedScope;
3795
3736
  const params = identifiers.map((id) => t.identifier(id));
3796
3737
  const deps = identifiers.map((id) => t.identifier(id));
3797
3738
  const arrowFunc = t.arrowFunctionExpression(params, valueExpr);
@@ -3808,28 +3749,6 @@ var MODIFIER_TRANSFORMATIONS = {
3808
3749
  return t.expressionStatement(computedCall);
3809
3750
  }
3810
3751
  },
3811
- react: {
3812
- needsImport: true,
3813
- // @react sum = x + y -> const sum = _react((x, y) => x() + y(), [x, y])
3814
- transform: (valueExpr, leftExpr) => {
3815
- const allIds = extractIdentifiers(valueExpr);
3816
- const identifiers = getReactiveDeps(allIds);
3817
- const params = identifiers.map((id) => t.identifier(id));
3818
- const deps = identifiers.map((id) => t.identifier(id));
3819
- const arrowFunc = t.arrowFunctionExpression(params, valueExpr);
3820
- wrapDependenciesWithCalls(arrowFunc, identifiers);
3821
- const reactCall = t.callExpression(
3822
- t.identifier(modifierAliases["react"]),
3823
- [arrowFunc, t.arrayExpression(deps)]
3824
- );
3825
- if (leftExpr) {
3826
- return t.variableDeclaration("const", [
3827
- t.variableDeclarator(leftExpr, reactCall)
3828
- ]);
3829
- }
3830
- return t.expressionStatement(reactCall);
3831
- }
3832
- },
3833
3752
  mutate: {
3834
3753
  needsImport: true,
3835
3754
  // @mutate x = (arg1, arg2) => { x1 := value1; x2 := value2 }
@@ -3896,6 +3815,9 @@ var MODIFIER_TRANSFORMATIONS = {
3896
3815
  ...stateContainerNames,
3897
3816
  ...outerDepsArray.filter((id) => !mutableVariables.has(id))
3898
3817
  ]);
3818
+ const savedScopeMutate = currentScope;
3819
+ currentScope = Object.create(currentScope);
3820
+ currentScope[reactiveScope] = false;
3899
3821
  for (const assignment of assignments) {
3900
3822
  const rightBabel = convertExpression2(assignment.rightOddo);
3901
3823
  const tempFile = t.file(t.program([t.expressionStatement(rightBabel)]));
@@ -3948,6 +3870,7 @@ var MODIFIER_TRANSFORMATIONS = {
3948
3870
  );
3949
3871
  }
3950
3872
  }
3873
+ currentScope = savedScopeMutate;
3951
3874
  if (stateContainerNames.length > 0) {
3952
3875
  mutateBodyStmts.push(
3953
3876
  t.expressionStatement(
@@ -4001,6 +3924,7 @@ var MODIFIER_TRANSFORMATIONS = {
4001
3924
  const deps = identifiers.map((id) => t.identifier(id));
4002
3925
  const savedScope = currentScope;
4003
3926
  currentScope = Object.create(currentScope);
3927
+ currentScope[reactiveScope] = false;
4004
3928
  for (const id of identifiers) {
4005
3929
  currentScope[id] = { type: "param", reactive: false };
4006
3930
  }
@@ -4028,16 +3952,61 @@ var MODIFIER_TRANSFORMATIONS = {
4028
3952
  needsImport: false,
4029
3953
  // @mutable x = 3 -> let x = 3;
4030
3954
  // @mutable x = y + 1 (y is @state) -> let x = _lift((y) => y() + 1, [y])
4031
- transform: (valueExpr, leftExpr) => {
3955
+ // Receives Oddo AST, extracts deps from Oddo, converts internally
3956
+ transform: (oddoExpr, leftExpr) => {
4032
3957
  if (leftExpr && t.isIdentifier(leftExpr)) {
4033
3958
  mutableVariables.add(leftExpr.name);
4034
- const identifiers = extractIdentifiers(valueExpr);
3959
+ const identifiers = collectOddoIdentifiersOnly(oddoExpr);
3960
+ const reactiveDeps = getReactiveDeps(identifiers);
3961
+ const savedScope = currentScope;
3962
+ if (reactiveDeps.length > 0) {
3963
+ currentScope = Object.create(currentScope);
3964
+ currentScope[reactiveScope] = false;
3965
+ }
3966
+ const valueExpr = convertExpression2(oddoExpr);
3967
+ if (reactiveDeps.length > 0) {
3968
+ currentScope = savedScope;
3969
+ }
4035
3970
  const liftedExpr = createLiftedExpr(valueExpr, identifiers);
4036
3971
  return t.variableDeclaration("let", [
4037
3972
  t.variableDeclarator(leftExpr, liftedExpr || valueExpr)
4038
3973
  ]);
4039
3974
  }
4040
- return t.expressionStatement(valueExpr);
3975
+ return t.expressionStatement(convertExpression2(oddoExpr));
3976
+ }
3977
+ },
3978
+ component: {
3979
+ needsImport: false,
3980
+ // @component Counter = (props) => { ... } -> const Counter = function(props) { ... }
3981
+ // Parameters are treated as reactive, no _liftFn wrapping, compiles to regular function
3982
+ transform: (oddoExpr, leftExpr) => {
3983
+ if (oddoExpr.type !== "arrowFunction") {
3984
+ throw new Error("@component modifier must be applied to an arrow function");
3985
+ }
3986
+ const funcExpr = convertReactiveContainer(oddoExpr);
3987
+ if (leftExpr && t.isIdentifier(leftExpr)) {
3988
+ return t.variableDeclaration("const", [
3989
+ t.variableDeclarator(leftExpr, funcExpr)
3990
+ ]);
3991
+ }
3992
+ return t.expressionStatement(funcExpr);
3993
+ }
3994
+ },
3995
+ hook: {
3996
+ needsImport: false,
3997
+ // @hook useCounter = (initial) => { ... } -> const useCounter = function(initial) { ... }
3998
+ // Parameters are treated as reactive, no _liftFn wrapping, compiles to regular function
3999
+ transform: (oddoExpr, leftExpr) => {
4000
+ if (oddoExpr.type !== "arrowFunction") {
4001
+ throw new Error("@hook modifier must be applied to an arrow function");
4002
+ }
4003
+ const funcExpr = convertReactiveContainer(oddoExpr);
4004
+ if (leftExpr && t.isIdentifier(leftExpr)) {
4005
+ return t.variableDeclaration("const", [
4006
+ t.variableDeclarator(leftExpr, funcExpr)
4007
+ ]);
4008
+ }
4009
+ return t.expressionStatement(funcExpr);
4041
4010
  }
4042
4011
  }
4043
4012
  };
@@ -4048,6 +4017,7 @@ var stateSetterMap = /* @__PURE__ */ new Map();
4048
4017
  var mutableVariables = /* @__PURE__ */ new Set();
4049
4018
  var moduleScope = null;
4050
4019
  var currentScope = null;
4020
+ var reactiveScope = /* @__PURE__ */ Symbol("reactive-scope");
4051
4021
  function declareVariable(name, type) {
4052
4022
  const reactive = type === "state" || type === "computed" || type === "param" || type === "import-oddo";
4053
4023
  currentScope[name] = { type, reactive };
@@ -4108,6 +4078,7 @@ function collectOddoIdentifiers(node, names = /* @__PURE__ */ new Set()) {
4108
4078
  if (!node || typeof node !== "object") return names;
4109
4079
  if (node.type === "program") {
4110
4080
  moduleScope = /* @__PURE__ */ Object.create(null);
4081
+ moduleScope[reactiveScope] = true;
4111
4082
  currentScope = moduleScope;
4112
4083
  }
4113
4084
  if (node.type === "identifier") {
@@ -4197,7 +4168,7 @@ function compileToJS(ast, config = {}) {
4197
4168
  moduleScope = null;
4198
4169
  currentScope = null;
4199
4170
  usedNames = collectOddoIdentifiers(ast);
4200
- const allImports = ["state", "computed", "react", "mutate", "effect", "stateProxy", "lift", "liftFn", "e", "c", "x", "f"];
4171
+ const allImports = ["state", "computed", "mutate", "effect", "stateProxy", "lift", "liftFn", "e", "c", "x", "f"];
4201
4172
  for (const name of allImports) {
4202
4173
  modifierAliases[name] = `__ODDO_IMPORT_${name}__`;
4203
4174
  }
@@ -4297,13 +4268,13 @@ function convertExpressionStatement2(stmt) {
4297
4268
  let leftExpr = null;
4298
4269
  if (stmt.expression.type === "variableDeclaration" || stmt.expression.type === "assignment") {
4299
4270
  leftExpr = convertExpression2(stmt.expression.left);
4300
- if (stmt.modifier === "mutate" || stmt.modifier === "effect") {
4271
+ if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook") {
4301
4272
  valueExpr = stmt.expression.right;
4302
4273
  } else {
4303
4274
  valueExpr = convertExpression2(stmt.expression.right);
4304
4275
  }
4305
4276
  } else {
4306
- if (stmt.modifier === "mutate" || stmt.modifier === "effect") {
4277
+ if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook") {
4307
4278
  valueExpr = stmt.expression;
4308
4279
  } else {
4309
4280
  valueExpr = convertExpression2(stmt.expression);
@@ -4324,13 +4295,13 @@ function convertExpressionStatement2(stmt) {
4324
4295
  let leftExpr = null;
4325
4296
  if (blockStmt.expression.type === "variableDeclaration" || blockStmt.expression.type === "assignment") {
4326
4297
  leftExpr = convertExpression2(blockStmt.expression.left);
4327
- if (stmt.modifier === "mutate" || stmt.modifier === "effect") {
4298
+ if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook") {
4328
4299
  valueExpr = blockStmt.expression.right;
4329
4300
  } else {
4330
4301
  valueExpr = convertExpression2(blockStmt.expression.right);
4331
4302
  }
4332
4303
  } else {
4333
- if (stmt.modifier === "mutate" || stmt.modifier === "effect") {
4304
+ if (stmt.modifier === "mutate" || stmt.modifier === "effect" || stmt.modifier === "computed" || stmt.modifier === "mutable" || stmt.modifier === "component" || stmt.modifier === "hook") {
4334
4305
  valueExpr = blockStmt.expression;
4335
4306
  } else {
4336
4307
  valueExpr = convertExpression2(blockStmt.expression);
@@ -4349,11 +4320,27 @@ function convertExpressionStatement2(stmt) {
4349
4320
  }
4350
4321
  if (stmt.expression && stmt.expression.type === "variableDeclaration") {
4351
4322
  const left = convertExpression2(stmt.expression.left);
4352
- const right = convertExpression2(stmt.expression.right);
4353
- const identifiers = extractIdentifiers(right);
4354
- const liftedExpr = createLiftedExpr(right, identifiers);
4323
+ const oddoRight = stmt.expression.right;
4324
+ let finalExpr;
4325
+ if (oddoRight.type !== "arrowFunction") {
4326
+ const identifiers = collectOddoIdentifiersOnly(oddoRight);
4327
+ const reactiveDeps = getReactiveDeps(identifiers);
4328
+ const savedScope = currentScope;
4329
+ if (reactiveDeps.length > 0) {
4330
+ currentScope = Object.create(currentScope);
4331
+ currentScope[reactiveScope] = false;
4332
+ }
4333
+ const right = convertExpression2(oddoRight);
4334
+ if (reactiveDeps.length > 0) {
4335
+ currentScope = savedScope;
4336
+ }
4337
+ const liftedExpr = createLiftedExpr(right, identifiers);
4338
+ finalExpr = liftedExpr || right;
4339
+ } else {
4340
+ finalExpr = convertExpression2(oddoRight);
4341
+ }
4355
4342
  return t.variableDeclaration("const", [
4356
- t.variableDeclarator(left, liftedExpr || right)
4343
+ t.variableDeclarator(left, finalExpr)
4357
4344
  ]);
4358
4345
  }
4359
4346
  let expression = null;
@@ -4499,17 +4486,21 @@ function convertArrowFunction2(expr) {
4499
4486
  if (expr._scope) {
4500
4487
  currentScope = expr._scope;
4501
4488
  }
4489
+ const inReactiveScope = (savedScope == null ? void 0 : savedScope[reactiveScope]) !== false;
4502
4490
  const bodyIdentifiers = collectOddoIdentifiersOnly(expr.body);
4503
- const reactiveDepsForBody = bodyIdentifiers.filter((id) => {
4491
+ const reactiveDepsForBody = inReactiveScope ? bodyIdentifiers.filter((id) => {
4504
4492
  var _a;
4505
4493
  const isOwnParam = (_a = expr.parameters) == null ? void 0 : _a.some((p) => p.name === id);
4506
4494
  if (isOwnParam) return false;
4507
4495
  const varInfo = savedScope == null ? void 0 : savedScope[id];
4508
4496
  return (varInfo == null ? void 0 : varInfo.reactive) === true;
4509
- });
4497
+ }) : [];
4510
4498
  for (const dep of reactiveDepsForBody) {
4511
4499
  currentScope[dep] = { type: "param", reactive: false };
4512
4500
  }
4501
+ if (reactiveDepsForBody.length > 0) {
4502
+ currentScope[reactiveScope] = false;
4503
+ }
4513
4504
  const params = expr.parameters.map((param) => {
4514
4505
  if (param.type === "restElement") {
4515
4506
  return t.restElement(convertExpression2(param.argument));
@@ -4540,7 +4531,7 @@ function convertArrowFunction2(expr) {
4540
4531
  body = null;
4541
4532
  }
4542
4533
  currentScope = savedScope;
4543
- if (reactiveDepsForBody.length > 0 || params.length > 0) {
4534
+ if (reactiveDepsForBody.length > 0 || params.length > 0 && inReactiveScope) {
4544
4535
  usedModifiers.add("liftFn");
4545
4536
  const depParams = reactiveDepsForBody.map((id) => t.identifier(id));
4546
4537
  const allParams = [...depParams, ...params];
@@ -4553,6 +4544,58 @@ function convertArrowFunction2(expr) {
4553
4544
  }
4554
4545
  return t.arrowFunctionExpression(params, body);
4555
4546
  }
4547
+ function convertReactiveContainer(expr) {
4548
+ var _a;
4549
+ const savedScope = currentScope;
4550
+ if (expr._scope) {
4551
+ currentScope = expr._scope;
4552
+ } else {
4553
+ currentScope = Object.create(savedScope);
4554
+ }
4555
+ for (const param of expr.parameters || []) {
4556
+ if (param.name) {
4557
+ currentScope[param.name] = { type: "param", reactive: true };
4558
+ } else if (param.type === "destructuringPattern") {
4559
+ const boundNames = extractBoundNames(param.pattern);
4560
+ for (const name of boundNames) {
4561
+ currentScope[name] = { type: "param", reactive: true };
4562
+ }
4563
+ } else if (param.type === "restElement" && ((_a = param.argument) == null ? void 0 : _a.name)) {
4564
+ currentScope[param.argument.name] = { type: "param", reactive: true };
4565
+ }
4566
+ }
4567
+ const params = (expr.parameters || []).map((param) => {
4568
+ if (param.type === "restElement") {
4569
+ return t.restElement(convertExpression2(param.argument));
4570
+ }
4571
+ if (param.type === "destructuringPattern") {
4572
+ const pattern = convertExpression2(param.pattern);
4573
+ if (param.default) {
4574
+ return t.assignmentPattern(pattern, convertExpression2(param.default));
4575
+ }
4576
+ return pattern;
4577
+ }
4578
+ if (param.type === "parameter") {
4579
+ const paramId = t.identifier(param.name);
4580
+ if (param.default) {
4581
+ return t.assignmentPattern(paramId, convertExpression2(param.default));
4582
+ }
4583
+ return paramId;
4584
+ }
4585
+ return convertExpression2(param);
4586
+ });
4587
+ let body;
4588
+ if (expr.body && expr.body.type === "blockStatement") {
4589
+ const statements = expr.body.body.map((stmt) => convertStatement2(stmt));
4590
+ body = t.blockStatement(statements);
4591
+ } else if (expr.body) {
4592
+ body = t.blockStatement([t.returnStatement(convertExpression2(expr.body))]);
4593
+ } else {
4594
+ body = t.blockStatement([]);
4595
+ }
4596
+ currentScope = savedScope;
4597
+ return t.functionExpression(null, params, body);
4598
+ }
4556
4599
  function collectOddoIdentifiersOnly(node, names = /* @__PURE__ */ new Set()) {
4557
4600
  if (!node || typeof node !== "object") return Array.from(names);
4558
4601
  if (node.type === "identifier") {
@@ -4811,8 +4854,12 @@ function convertJSXChild2(child) {
4811
4854
  if (!text) return null;
4812
4855
  return t.stringLiteral(text);
4813
4856
  } else if (child.type === "jsxExpression") {
4857
+ const savedScope = currentScope;
4858
+ currentScope = Object.create(currentScope);
4859
+ currentScope[reactiveScope] = false;
4814
4860
  const innerExpr = convertExpression2(child.expression);
4815
- return createReactiveExpr(innerExpr);
4861
+ currentScope = savedScope;
4862
+ return createReactiveExpr(child.expression, innerExpr);
4816
4863
  } else if (child.type === "jsxElement") {
4817
4864
  return convertJSXElement2(child);
4818
4865
  } else if (child.type === "jsxFragment") {
@@ -4828,10 +4875,15 @@ function convertJSXElement2(expr) {
4828
4875
  const hasSpread = expr.attributes.some((attr) => attr.type === "jsxSpread");
4829
4876
  let propsArg;
4830
4877
  if (hasSpread) {
4878
+ const savedScopeSpread = currentScope;
4879
+ currentScope = Object.create(currentScope);
4880
+ currentScope[reactiveScope] = false;
4831
4881
  const properties = [];
4882
+ const oddoExprs = [];
4832
4883
  for (const attr of expr.attributes) {
4833
4884
  if (attr.type === "jsxSpread") {
4834
4885
  properties.push(t.spreadElement(convertExpression2(attr.expression)));
4886
+ oddoExprs.push(attr.expression);
4835
4887
  } else {
4836
4888
  const key = isValidJSIdentifier(attr.name) ? t.identifier(attr.name) : t.stringLiteral(attr.name);
4837
4889
  let value;
@@ -4841,14 +4893,18 @@ function convertJSXElement2(expr) {
4841
4893
  value = t.stringLiteral(attr.value.value);
4842
4894
  } else if (attr.value.type === "expression") {
4843
4895
  value = convertExpression2(attr.value.value);
4896
+ oddoExprs.push(attr.value.value);
4844
4897
  } else {
4845
4898
  value = convertExpression2(attr.value);
4899
+ oddoExprs.push(attr.value);
4846
4900
  }
4847
4901
  properties.push(t.objectProperty(key, value));
4848
4902
  }
4849
4903
  }
4904
+ currentScope = savedScopeSpread;
4850
4905
  const propsObj = t.objectExpression(properties);
4851
- propsArg = createReactiveExpr(propsObj, true);
4906
+ const syntheticOddo = { type: "array", elements: oddoExprs };
4907
+ propsArg = createReactiveExpr(syntheticOddo, propsObj, true);
4852
4908
  } else if (expr.attributes.length === 0) {
4853
4909
  propsArg = t.nullLiteral();
4854
4910
  } else {
@@ -4861,11 +4917,19 @@ function convertJSXElement2(expr) {
4861
4917
  } else if (attr.value.type === "string") {
4862
4918
  value = t.stringLiteral(attr.value.value);
4863
4919
  } else if (attr.value.type === "expression") {
4920
+ const savedScopeAttr = currentScope;
4921
+ currentScope = Object.create(currentScope);
4922
+ currentScope[reactiveScope] = false;
4864
4923
  const innerExpr = convertExpression2(attr.value.value);
4865
- value = createReactiveExpr(innerExpr, true);
4924
+ currentScope = savedScopeAttr;
4925
+ value = createReactiveExpr(attr.value.value, innerExpr, true);
4866
4926
  } else {
4927
+ const savedScopeAttr = currentScope;
4928
+ currentScope = Object.create(currentScope);
4929
+ currentScope[reactiveScope] = false;
4867
4930
  const innerExpr = convertExpression2(attr.value);
4868
- value = createReactiveExpr(innerExpr, true);
4931
+ currentScope = savedScopeAttr;
4932
+ value = createReactiveExpr(attr.value, innerExpr, true);
4869
4933
  }
4870
4934
  properties.push(t.objectProperty(key, value));
4871
4935
  }