@fictjs/compiler 0.0.9 → 0.0.10

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 (3) hide show
  1. package/dist/index.cjs +109 -59
  2. package/dist/index.js +109 -59
  3. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -18343,7 +18343,8 @@ function lowerNodeWithRegionContext(node, t2, ctx, declaredVars, regionCtx) {
18343
18343
  t2.blockStatement(conseqStmts),
18344
18344
  altStmts ? t2.blockStatement(altStmts) : null
18345
18345
  );
18346
- const shouldWrapEffect = ctx.wrapTrackedExpressions !== false && !ctx.inRegionMemo && expressionUsesTracked(node.test, ctx) && !statementHasEarlyExit(ifStmt, t2);
18346
+ const inNonReactiveScope = !!(ctx.nonReactiveScopeDepth && ctx.nonReactiveScopeDepth > 0);
18347
+ const shouldWrapEffect = ctx.wrapTrackedExpressions !== false && !ctx.inRegionMemo && !inNonReactiveScope && expressionUsesTracked(node.test, ctx) && !statementHasEarlyExit(ifStmt, t2);
18347
18348
  if (shouldWrapEffect) {
18348
18349
  ctx.helpersUsed.add("useEffect");
18349
18350
  ctx.needsCtx = true;
@@ -18571,31 +18572,53 @@ function lowerStructuredNodeForRegion(node, region, t2, ctx, declaredVars, regio
18571
18572
  return stmt ? [stmt] : [];
18572
18573
  }
18573
18574
  case "if": {
18574
- const consequent = lowerStructuredNodeForRegion(
18575
- node.consequent,
18576
- region,
18577
- t2,
18578
- ctx,
18579
- declaredVars,
18580
- regionCtx,
18581
- skipInstructions
18582
- );
18583
- const alternate = node.alternate ? lowerStructuredNodeForRegion(
18584
- node.alternate,
18585
- region,
18586
- t2,
18587
- ctx,
18588
- declaredVars,
18589
- regionCtx,
18590
- skipInstructions
18591
- ) : [];
18575
+ const inNonReactiveScope = !!(ctx.nonReactiveScopeDepth && ctx.nonReactiveScopeDepth > 0);
18576
+ const baseShouldWrapEffect = ctx.wrapTrackedExpressions !== false && !ctx.inRegionMemo && !inNonReactiveScope && expressionUsesTracked(node.test, ctx);
18577
+ const lowerChild = (child, forceNonReactive) => {
18578
+ if (!child) return [];
18579
+ if (!forceNonReactive) {
18580
+ return lowerStructuredNodeForRegion(
18581
+ child,
18582
+ region,
18583
+ t2,
18584
+ ctx,
18585
+ declaredVars,
18586
+ regionCtx,
18587
+ skipInstructions
18588
+ );
18589
+ }
18590
+ const prevDepth = ctx.nonReactiveScopeDepth ?? 0;
18591
+ ctx.nonReactiveScopeDepth = prevDepth + 1;
18592
+ try {
18593
+ return lowerStructuredNodeForRegion(
18594
+ child,
18595
+ region,
18596
+ t2,
18597
+ ctx,
18598
+ declaredVars,
18599
+ regionCtx,
18600
+ skipInstructions
18601
+ );
18602
+ } finally {
18603
+ ctx.nonReactiveScopeDepth = prevDepth;
18604
+ }
18605
+ };
18606
+ let consequent = lowerChild(node.consequent, baseShouldWrapEffect);
18607
+ let alternate = node.alternate ? lowerChild(node.alternate, baseShouldWrapEffect) : [];
18592
18608
  if (consequent.length === 0 && alternate.length === 0) return [];
18593
- const ifStmt = t2.ifStatement(
18609
+ const buildIfStmt = (cons, alt) => t2.ifStatement(
18594
18610
  lowerExpressionWithDeSSA(node.test, ctx),
18595
- t2.blockStatement(consequent),
18596
- alternate.length > 0 ? t2.blockStatement(alternate) : null
18611
+ t2.blockStatement(cons),
18612
+ alt.length > 0 ? t2.blockStatement(alt) : null
18597
18613
  );
18598
- const shouldWrapEffect = ctx.wrapTrackedExpressions !== false && !ctx.inRegionMemo && expressionUsesTracked(node.test, ctx) && !statementHasEarlyExit(ifStmt, t2);
18614
+ let ifStmt = buildIfStmt(consequent, alternate);
18615
+ const shouldWrapEffect = baseShouldWrapEffect && !statementHasEarlyExit(ifStmt, t2);
18616
+ if (!shouldWrapEffect && baseShouldWrapEffect) {
18617
+ consequent = lowerChild(node.consequent, false);
18618
+ alternate = node.alternate ? lowerChild(node.alternate, false) : [];
18619
+ if (consequent.length === 0 && alternate.length === 0) return [];
18620
+ ifStmt = buildIfStmt(consequent, alternate);
18621
+ }
18599
18622
  if (shouldWrapEffect) {
18600
18623
  ctx.helpersUsed.add("useEffect");
18601
18624
  ctx.needsCtx = true;
@@ -19622,7 +19645,8 @@ function instructionToStatement(instr, t2, declaredVars, ctx, _buildMemoCall) {
19622
19645
  (dep) => ctx.trackedVars.has(deSSAVarName(dep))
19623
19646
  );
19624
19647
  const usesTracked = expressionUsesTracked(instr.value, ctx);
19625
- const shouldWrapExpr = ctx.wrapTrackedExpressions !== false && (usesTracked || hasTrackedControlDep);
19648
+ const inNonReactiveScope = !!(ctx.nonReactiveScopeDepth && ctx.nonReactiveScopeDepth > 0);
19649
+ const shouldWrapExpr = ctx.wrapTrackedExpressions !== false && !inNonReactiveScope && (usesTracked || hasTrackedControlDep);
19626
19650
  if (shouldWrapExpr) {
19627
19651
  ctx.helpersUsed.add("useEffect");
19628
19652
  ctx.needsCtx = true;
@@ -21451,7 +21475,7 @@ function lowerExpression(expr, ctx, isAssigned = false) {
21451
21475
  ctx.expressionDepth = depth - 1;
21452
21476
  }
21453
21477
  }
21454
- function lowerExpressionImpl(expr, ctx, isAssigned = false) {
21478
+ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
21455
21479
  const { t: t2 } = ctx;
21456
21480
  const mapParams = (params) => params.map((p) => t2.identifier(deSSAVarName(p.name)));
21457
21481
  const withFunctionScope = (paramNames, fn) => {
@@ -21513,11 +21537,7 @@ function lowerExpressionImpl(expr, ctx, isAssigned = false) {
21513
21537
  };
21514
21538
  const declared = new Set(paramIds.map((p) => p.name));
21515
21539
  return lowerStructuredNodeWithoutRegions(structured, t2, ctx, declared);
21516
- } catch (e) {
21517
- console.log(
21518
- "[DEBUG] Structurization failed, falling back to lowerBlocksToStatements via lowerInstruction",
21519
- e
21520
- );
21540
+ } catch {
21521
21541
  return lowerBlocksToStatements(blocks);
21522
21542
  }
21523
21543
  };
@@ -21696,12 +21716,10 @@ function lowerExpressionImpl(expr, ctx, isAssigned = false) {
21696
21716
  case "ArrowFunction": {
21697
21717
  const paramIds = mapParams(expr.params);
21698
21718
  const shadowed = new Set(expr.params.map((p) => deSSAVarName(p.name)));
21699
- return withFunctionScope(shadowed, () => {
21700
- if (isAssigned) {
21701
- ctx.nonReactiveScopeDepth = (ctx.nonReactiveScopeDepth ?? 0) + 1;
21702
- }
21703
- let fn;
21704
- try {
21719
+ return withNonReactiveScope(
21720
+ ctx,
21721
+ () => withFunctionScope(shadowed, () => {
21722
+ let fn;
21705
21723
  if (expr.isExpression && !Array.isArray(expr.body)) {
21706
21724
  const { result: bodyExpr, cacheDeclarations } = withGetterCache(
21707
21725
  ctx,
@@ -21729,12 +21747,8 @@ function lowerExpressionImpl(expr, ctx, isAssigned = false) {
21729
21747
  }
21730
21748
  fn.async = expr.isAsync ?? false;
21731
21749
  return fn;
21732
- } finally {
21733
- if (isAssigned) {
21734
- ctx.nonReactiveScopeDepth = (ctx.nonReactiveScopeDepth ?? 0) - 1;
21735
- }
21736
- }
21737
- });
21750
+ })
21751
+ );
21738
21752
  }
21739
21753
  case "FunctionExpression": {
21740
21754
  const paramIds = mapParams(expr.params);
@@ -22915,16 +22929,28 @@ function lowerIntrinsicElement(jsx, ctx) {
22915
22929
  t2.expressionStatement(lowerDomExpression(binding.expr, ctx, containingRegion))
22916
22930
  );
22917
22931
  } else if (binding.type === "text" && binding.expr) {
22918
- ctx.helpersUsed.add("bindText");
22919
22932
  const valueExpr = lowerDomExpression(binding.expr, ctx, containingRegion);
22920
- statements.push(
22921
- t2.expressionStatement(
22922
- t2.callExpression(t2.identifier(RUNTIME_ALIASES.bindText), [
22923
- targetId,
22924
- t2.arrowFunctionExpression([], valueExpr)
22925
- ])
22926
- )
22927
- );
22933
+ if (isExpressionReactive(binding.expr, ctx)) {
22934
+ ctx.helpersUsed.add("bindText");
22935
+ statements.push(
22936
+ t2.expressionStatement(
22937
+ t2.callExpression(t2.identifier(RUNTIME_ALIASES.bindText), [
22938
+ targetId,
22939
+ t2.arrowFunctionExpression([], valueExpr)
22940
+ ])
22941
+ )
22942
+ );
22943
+ } else {
22944
+ statements.push(
22945
+ t2.expressionStatement(
22946
+ t2.assignmentExpression(
22947
+ "=",
22948
+ t2.memberExpression(targetId, t2.identifier("data")),
22949
+ t2.callExpression(t2.identifier("String"), [valueExpr])
22950
+ )
22951
+ )
22952
+ );
22953
+ }
22928
22954
  } else if (binding.type === "child" && binding.expr) {
22929
22955
  emitHIRChildBinding(targetId, binding.expr, statements, ctx, containingRegion);
22930
22956
  }
@@ -23238,8 +23264,13 @@ function getTrackedCallIdentifier(expr, ctx, itemParamName) {
23238
23264
  }
23239
23265
  return null;
23240
23266
  }
23241
- function rewriteSelectorExpression(expr, itemParamName, getSelectorId, ctx) {
23267
+ function rewriteSelectorExpression(expr, itemParamName, keyParamName, getSelectorId, ctx) {
23242
23268
  const { t: t2 } = ctx;
23269
+ const usesParamIdentifier = (e) => {
23270
+ if (expressionUsesIdentifier(e, itemParamName, t2)) return true;
23271
+ if (keyParamName && expressionUsesIdentifier(e, keyParamName, t2)) return true;
23272
+ return false;
23273
+ };
23243
23274
  if (t2.isBinaryExpression(expr) && (expr.operator === "===" || expr.operator === "==")) {
23244
23275
  const leftTracked = getTrackedCallIdentifier(
23245
23276
  expr.left,
@@ -23251,7 +23282,7 @@ function rewriteSelectorExpression(expr, itemParamName, getSelectorId, ctx) {
23251
23282
  ctx,
23252
23283
  itemParamName
23253
23284
  );
23254
- if (leftTracked && expressionUsesIdentifier(expr.right, itemParamName, t2)) {
23285
+ if (leftTracked && usesParamIdentifier(expr.right)) {
23255
23286
  return {
23256
23287
  expr: t2.callExpression(getSelectorId(leftTracked), [
23257
23288
  expr.right
@@ -23259,7 +23290,7 @@ function rewriteSelectorExpression(expr, itemParamName, getSelectorId, ctx) {
23259
23290
  changed: true
23260
23291
  };
23261
23292
  }
23262
- if (rightTracked && expressionUsesIdentifier(expr.left, itemParamName, t2)) {
23293
+ if (rightTracked && usesParamIdentifier(expr.left)) {
23263
23294
  return {
23264
23295
  expr: t2.callExpression(getSelectorId(rightTracked), [
23265
23296
  expr.left
@@ -23270,7 +23301,7 @@ function rewriteSelectorExpression(expr, itemParamName, getSelectorId, ctx) {
23270
23301
  }
23271
23302
  let changed = false;
23272
23303
  const rewrite = (node) => {
23273
- const result = rewriteSelectorExpression(node, itemParamName, getSelectorId, ctx);
23304
+ const result = rewriteSelectorExpression(node, itemParamName, keyParamName, getSelectorId, ctx);
23274
23305
  if (result.changed) changed = true;
23275
23306
  return result.expr;
23276
23307
  };
@@ -23331,7 +23362,7 @@ function rewriteSelectorExpression(expr, itemParamName, getSelectorId, ctx) {
23331
23362
  }
23332
23363
  return { expr, changed };
23333
23364
  }
23334
- function applySelectorHoist(callbackExpr, itemParamName, statements, ctx) {
23365
+ function applySelectorHoist(callbackExpr, itemParamName, keyParamName, statements, ctx) {
23335
23366
  const { t: t2 } = ctx;
23336
23367
  if (!itemParamName) return;
23337
23368
  if (!t2.isArrowFunctionExpression(callbackExpr) && !t2.isFunctionExpression(callbackExpr)) return;
@@ -23347,7 +23378,13 @@ function applySelectorHoist(callbackExpr, itemParamName, statements, ctx) {
23347
23378
  if (t2.isBlockStatement(fn.body)) {
23348
23379
  for (const stmt of fn.body.body) {
23349
23380
  if (t2.isReturnStatement(stmt) && stmt.argument && t2.isExpression(stmt.argument)) {
23350
- const result = rewriteSelectorExpression(stmt.argument, itemParamName, getSelectorId, ctx);
23381
+ const result = rewriteSelectorExpression(
23382
+ stmt.argument,
23383
+ itemParamName,
23384
+ keyParamName,
23385
+ getSelectorId,
23386
+ ctx
23387
+ );
23351
23388
  if (result.changed) {
23352
23389
  stmt.argument = result.expr;
23353
23390
  }
@@ -23356,7 +23393,13 @@ function applySelectorHoist(callbackExpr, itemParamName, statements, ctx) {
23356
23393
  return;
23357
23394
  }
23358
23395
  if (t2.isExpression(fn.body)) {
23359
- const result = rewriteSelectorExpression(fn.body, itemParamName, getSelectorId, ctx);
23396
+ const result = rewriteSelectorExpression(
23397
+ fn.body,
23398
+ itemParamName,
23399
+ keyParamName,
23400
+ getSelectorId,
23401
+ ctx
23402
+ );
23360
23403
  if (result.changed) {
23361
23404
  fn.body = result.expr;
23362
23405
  }
@@ -23520,7 +23563,14 @@ function emitListChild(parentId, markerId, expr, statements, ctx) {
23520
23563
  const listId = genTemp(ctx, "list");
23521
23564
  if (isKeyed) {
23522
23565
  const itemParamName = t2.isArrowFunctionExpression(callbackExpr) || t2.isFunctionExpression(callbackExpr) ? t2.isIdentifier(callbackExpr.params[0]) ? callbackExpr.params[0].name : null : null;
23523
- applySelectorHoist(callbackExpr, itemParamName, statements, ctx);
23566
+ const keyParamName = ctx.listKeyParamName ?? null;
23567
+ applySelectorHoist(
23568
+ callbackExpr,
23569
+ itemParamName,
23570
+ keyParamName,
23571
+ statements,
23572
+ ctx
23573
+ );
23524
23574
  }
23525
23575
  if (isKeyed && keyExpr) {
23526
23576
  let keyExprAst = lowerExpression(keyExpr, ctx);
package/dist/index.js CHANGED
@@ -18331,7 +18331,8 @@ function lowerNodeWithRegionContext(node, t2, ctx, declaredVars, regionCtx) {
18331
18331
  t2.blockStatement(conseqStmts),
18332
18332
  altStmts ? t2.blockStatement(altStmts) : null
18333
18333
  );
18334
- const shouldWrapEffect = ctx.wrapTrackedExpressions !== false && !ctx.inRegionMemo && expressionUsesTracked(node.test, ctx) && !statementHasEarlyExit(ifStmt, t2);
18334
+ const inNonReactiveScope = !!(ctx.nonReactiveScopeDepth && ctx.nonReactiveScopeDepth > 0);
18335
+ const shouldWrapEffect = ctx.wrapTrackedExpressions !== false && !ctx.inRegionMemo && !inNonReactiveScope && expressionUsesTracked(node.test, ctx) && !statementHasEarlyExit(ifStmt, t2);
18335
18336
  if (shouldWrapEffect) {
18336
18337
  ctx.helpersUsed.add("useEffect");
18337
18338
  ctx.needsCtx = true;
@@ -18559,31 +18560,53 @@ function lowerStructuredNodeForRegion(node, region, t2, ctx, declaredVars, regio
18559
18560
  return stmt ? [stmt] : [];
18560
18561
  }
18561
18562
  case "if": {
18562
- const consequent = lowerStructuredNodeForRegion(
18563
- node.consequent,
18564
- region,
18565
- t2,
18566
- ctx,
18567
- declaredVars,
18568
- regionCtx,
18569
- skipInstructions
18570
- );
18571
- const alternate = node.alternate ? lowerStructuredNodeForRegion(
18572
- node.alternate,
18573
- region,
18574
- t2,
18575
- ctx,
18576
- declaredVars,
18577
- regionCtx,
18578
- skipInstructions
18579
- ) : [];
18563
+ const inNonReactiveScope = !!(ctx.nonReactiveScopeDepth && ctx.nonReactiveScopeDepth > 0);
18564
+ const baseShouldWrapEffect = ctx.wrapTrackedExpressions !== false && !ctx.inRegionMemo && !inNonReactiveScope && expressionUsesTracked(node.test, ctx);
18565
+ const lowerChild = (child, forceNonReactive) => {
18566
+ if (!child) return [];
18567
+ if (!forceNonReactive) {
18568
+ return lowerStructuredNodeForRegion(
18569
+ child,
18570
+ region,
18571
+ t2,
18572
+ ctx,
18573
+ declaredVars,
18574
+ regionCtx,
18575
+ skipInstructions
18576
+ );
18577
+ }
18578
+ const prevDepth = ctx.nonReactiveScopeDepth ?? 0;
18579
+ ctx.nonReactiveScopeDepth = prevDepth + 1;
18580
+ try {
18581
+ return lowerStructuredNodeForRegion(
18582
+ child,
18583
+ region,
18584
+ t2,
18585
+ ctx,
18586
+ declaredVars,
18587
+ regionCtx,
18588
+ skipInstructions
18589
+ );
18590
+ } finally {
18591
+ ctx.nonReactiveScopeDepth = prevDepth;
18592
+ }
18593
+ };
18594
+ let consequent = lowerChild(node.consequent, baseShouldWrapEffect);
18595
+ let alternate = node.alternate ? lowerChild(node.alternate, baseShouldWrapEffect) : [];
18580
18596
  if (consequent.length === 0 && alternate.length === 0) return [];
18581
- const ifStmt = t2.ifStatement(
18597
+ const buildIfStmt = (cons, alt) => t2.ifStatement(
18582
18598
  lowerExpressionWithDeSSA(node.test, ctx),
18583
- t2.blockStatement(consequent),
18584
- alternate.length > 0 ? t2.blockStatement(alternate) : null
18599
+ t2.blockStatement(cons),
18600
+ alt.length > 0 ? t2.blockStatement(alt) : null
18585
18601
  );
18586
- const shouldWrapEffect = ctx.wrapTrackedExpressions !== false && !ctx.inRegionMemo && expressionUsesTracked(node.test, ctx) && !statementHasEarlyExit(ifStmt, t2);
18602
+ let ifStmt = buildIfStmt(consequent, alternate);
18603
+ const shouldWrapEffect = baseShouldWrapEffect && !statementHasEarlyExit(ifStmt, t2);
18604
+ if (!shouldWrapEffect && baseShouldWrapEffect) {
18605
+ consequent = lowerChild(node.consequent, false);
18606
+ alternate = node.alternate ? lowerChild(node.alternate, false) : [];
18607
+ if (consequent.length === 0 && alternate.length === 0) return [];
18608
+ ifStmt = buildIfStmt(consequent, alternate);
18609
+ }
18587
18610
  if (shouldWrapEffect) {
18588
18611
  ctx.helpersUsed.add("useEffect");
18589
18612
  ctx.needsCtx = true;
@@ -19610,7 +19633,8 @@ function instructionToStatement(instr, t2, declaredVars, ctx, _buildMemoCall) {
19610
19633
  (dep) => ctx.trackedVars.has(deSSAVarName(dep))
19611
19634
  );
19612
19635
  const usesTracked = expressionUsesTracked(instr.value, ctx);
19613
- const shouldWrapExpr = ctx.wrapTrackedExpressions !== false && (usesTracked || hasTrackedControlDep);
19636
+ const inNonReactiveScope = !!(ctx.nonReactiveScopeDepth && ctx.nonReactiveScopeDepth > 0);
19637
+ const shouldWrapExpr = ctx.wrapTrackedExpressions !== false && !inNonReactiveScope && (usesTracked || hasTrackedControlDep);
19614
19638
  if (shouldWrapExpr) {
19615
19639
  ctx.helpersUsed.add("useEffect");
19616
19640
  ctx.needsCtx = true;
@@ -21439,7 +21463,7 @@ function lowerExpression(expr, ctx, isAssigned = false) {
21439
21463
  ctx.expressionDepth = depth - 1;
21440
21464
  }
21441
21465
  }
21442
- function lowerExpressionImpl(expr, ctx, isAssigned = false) {
21466
+ function lowerExpressionImpl(expr, ctx, _isAssigned = false) {
21443
21467
  const { t: t2 } = ctx;
21444
21468
  const mapParams = (params) => params.map((p) => t2.identifier(deSSAVarName(p.name)));
21445
21469
  const withFunctionScope = (paramNames, fn) => {
@@ -21501,11 +21525,7 @@ function lowerExpressionImpl(expr, ctx, isAssigned = false) {
21501
21525
  };
21502
21526
  const declared = new Set(paramIds.map((p) => p.name));
21503
21527
  return lowerStructuredNodeWithoutRegions(structured, t2, ctx, declared);
21504
- } catch (e) {
21505
- console.log(
21506
- "[DEBUG] Structurization failed, falling back to lowerBlocksToStatements via lowerInstruction",
21507
- e
21508
- );
21528
+ } catch {
21509
21529
  return lowerBlocksToStatements(blocks);
21510
21530
  }
21511
21531
  };
@@ -21684,12 +21704,10 @@ function lowerExpressionImpl(expr, ctx, isAssigned = false) {
21684
21704
  case "ArrowFunction": {
21685
21705
  const paramIds = mapParams(expr.params);
21686
21706
  const shadowed = new Set(expr.params.map((p) => deSSAVarName(p.name)));
21687
- return withFunctionScope(shadowed, () => {
21688
- if (isAssigned) {
21689
- ctx.nonReactiveScopeDepth = (ctx.nonReactiveScopeDepth ?? 0) + 1;
21690
- }
21691
- let fn;
21692
- try {
21707
+ return withNonReactiveScope(
21708
+ ctx,
21709
+ () => withFunctionScope(shadowed, () => {
21710
+ let fn;
21693
21711
  if (expr.isExpression && !Array.isArray(expr.body)) {
21694
21712
  const { result: bodyExpr, cacheDeclarations } = withGetterCache(
21695
21713
  ctx,
@@ -21717,12 +21735,8 @@ function lowerExpressionImpl(expr, ctx, isAssigned = false) {
21717
21735
  }
21718
21736
  fn.async = expr.isAsync ?? false;
21719
21737
  return fn;
21720
- } finally {
21721
- if (isAssigned) {
21722
- ctx.nonReactiveScopeDepth = (ctx.nonReactiveScopeDepth ?? 0) - 1;
21723
- }
21724
- }
21725
- });
21738
+ })
21739
+ );
21726
21740
  }
21727
21741
  case "FunctionExpression": {
21728
21742
  const paramIds = mapParams(expr.params);
@@ -22903,16 +22917,28 @@ function lowerIntrinsicElement(jsx, ctx) {
22903
22917
  t2.expressionStatement(lowerDomExpression(binding.expr, ctx, containingRegion))
22904
22918
  );
22905
22919
  } else if (binding.type === "text" && binding.expr) {
22906
- ctx.helpersUsed.add("bindText");
22907
22920
  const valueExpr = lowerDomExpression(binding.expr, ctx, containingRegion);
22908
- statements.push(
22909
- t2.expressionStatement(
22910
- t2.callExpression(t2.identifier(RUNTIME_ALIASES.bindText), [
22911
- targetId,
22912
- t2.arrowFunctionExpression([], valueExpr)
22913
- ])
22914
- )
22915
- );
22921
+ if (isExpressionReactive(binding.expr, ctx)) {
22922
+ ctx.helpersUsed.add("bindText");
22923
+ statements.push(
22924
+ t2.expressionStatement(
22925
+ t2.callExpression(t2.identifier(RUNTIME_ALIASES.bindText), [
22926
+ targetId,
22927
+ t2.arrowFunctionExpression([], valueExpr)
22928
+ ])
22929
+ )
22930
+ );
22931
+ } else {
22932
+ statements.push(
22933
+ t2.expressionStatement(
22934
+ t2.assignmentExpression(
22935
+ "=",
22936
+ t2.memberExpression(targetId, t2.identifier("data")),
22937
+ t2.callExpression(t2.identifier("String"), [valueExpr])
22938
+ )
22939
+ )
22940
+ );
22941
+ }
22916
22942
  } else if (binding.type === "child" && binding.expr) {
22917
22943
  emitHIRChildBinding(targetId, binding.expr, statements, ctx, containingRegion);
22918
22944
  }
@@ -23226,8 +23252,13 @@ function getTrackedCallIdentifier(expr, ctx, itemParamName) {
23226
23252
  }
23227
23253
  return null;
23228
23254
  }
23229
- function rewriteSelectorExpression(expr, itemParamName, getSelectorId, ctx) {
23255
+ function rewriteSelectorExpression(expr, itemParamName, keyParamName, getSelectorId, ctx) {
23230
23256
  const { t: t2 } = ctx;
23257
+ const usesParamIdentifier = (e) => {
23258
+ if (expressionUsesIdentifier(e, itemParamName, t2)) return true;
23259
+ if (keyParamName && expressionUsesIdentifier(e, keyParamName, t2)) return true;
23260
+ return false;
23261
+ };
23231
23262
  if (t2.isBinaryExpression(expr) && (expr.operator === "===" || expr.operator === "==")) {
23232
23263
  const leftTracked = getTrackedCallIdentifier(
23233
23264
  expr.left,
@@ -23239,7 +23270,7 @@ function rewriteSelectorExpression(expr, itemParamName, getSelectorId, ctx) {
23239
23270
  ctx,
23240
23271
  itemParamName
23241
23272
  );
23242
- if (leftTracked && expressionUsesIdentifier(expr.right, itemParamName, t2)) {
23273
+ if (leftTracked && usesParamIdentifier(expr.right)) {
23243
23274
  return {
23244
23275
  expr: t2.callExpression(getSelectorId(leftTracked), [
23245
23276
  expr.right
@@ -23247,7 +23278,7 @@ function rewriteSelectorExpression(expr, itemParamName, getSelectorId, ctx) {
23247
23278
  changed: true
23248
23279
  };
23249
23280
  }
23250
- if (rightTracked && expressionUsesIdentifier(expr.left, itemParamName, t2)) {
23281
+ if (rightTracked && usesParamIdentifier(expr.left)) {
23251
23282
  return {
23252
23283
  expr: t2.callExpression(getSelectorId(rightTracked), [
23253
23284
  expr.left
@@ -23258,7 +23289,7 @@ function rewriteSelectorExpression(expr, itemParamName, getSelectorId, ctx) {
23258
23289
  }
23259
23290
  let changed = false;
23260
23291
  const rewrite = (node) => {
23261
- const result = rewriteSelectorExpression(node, itemParamName, getSelectorId, ctx);
23292
+ const result = rewriteSelectorExpression(node, itemParamName, keyParamName, getSelectorId, ctx);
23262
23293
  if (result.changed) changed = true;
23263
23294
  return result.expr;
23264
23295
  };
@@ -23319,7 +23350,7 @@ function rewriteSelectorExpression(expr, itemParamName, getSelectorId, ctx) {
23319
23350
  }
23320
23351
  return { expr, changed };
23321
23352
  }
23322
- function applySelectorHoist(callbackExpr, itemParamName, statements, ctx) {
23353
+ function applySelectorHoist(callbackExpr, itemParamName, keyParamName, statements, ctx) {
23323
23354
  const { t: t2 } = ctx;
23324
23355
  if (!itemParamName) return;
23325
23356
  if (!t2.isArrowFunctionExpression(callbackExpr) && !t2.isFunctionExpression(callbackExpr)) return;
@@ -23335,7 +23366,13 @@ function applySelectorHoist(callbackExpr, itemParamName, statements, ctx) {
23335
23366
  if (t2.isBlockStatement(fn.body)) {
23336
23367
  for (const stmt of fn.body.body) {
23337
23368
  if (t2.isReturnStatement(stmt) && stmt.argument && t2.isExpression(stmt.argument)) {
23338
- const result = rewriteSelectorExpression(stmt.argument, itemParamName, getSelectorId, ctx);
23369
+ const result = rewriteSelectorExpression(
23370
+ stmt.argument,
23371
+ itemParamName,
23372
+ keyParamName,
23373
+ getSelectorId,
23374
+ ctx
23375
+ );
23339
23376
  if (result.changed) {
23340
23377
  stmt.argument = result.expr;
23341
23378
  }
@@ -23344,7 +23381,13 @@ function applySelectorHoist(callbackExpr, itemParamName, statements, ctx) {
23344
23381
  return;
23345
23382
  }
23346
23383
  if (t2.isExpression(fn.body)) {
23347
- const result = rewriteSelectorExpression(fn.body, itemParamName, getSelectorId, ctx);
23384
+ const result = rewriteSelectorExpression(
23385
+ fn.body,
23386
+ itemParamName,
23387
+ keyParamName,
23388
+ getSelectorId,
23389
+ ctx
23390
+ );
23348
23391
  if (result.changed) {
23349
23392
  fn.body = result.expr;
23350
23393
  }
@@ -23508,7 +23551,14 @@ function emitListChild(parentId, markerId, expr, statements, ctx) {
23508
23551
  const listId = genTemp(ctx, "list");
23509
23552
  if (isKeyed) {
23510
23553
  const itemParamName = t2.isArrowFunctionExpression(callbackExpr) || t2.isFunctionExpression(callbackExpr) ? t2.isIdentifier(callbackExpr.params[0]) ? callbackExpr.params[0].name : null : null;
23511
- applySelectorHoist(callbackExpr, itemParamName, statements, ctx);
23554
+ const keyParamName = ctx.listKeyParamName ?? null;
23555
+ applySelectorHoist(
23556
+ callbackExpr,
23557
+ itemParamName,
23558
+ keyParamName,
23559
+ statements,
23560
+ ctx
23561
+ );
23512
23562
  }
23513
23563
  if (isKeyed && keyExpr) {
23514
23564
  let keyExprAst = lowerExpression(keyExpr, ctx);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fictjs/compiler",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "description": "Babel plugin for Fict Compiler",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -45,7 +45,7 @@
45
45
  "@types/babel__helper-plugin-utils": "^7.10.3",
46
46
  "@types/babel__traverse": "^7.28.0",
47
47
  "tsup": "^8.5.1",
48
- "@fictjs/runtime": "0.0.9"
48
+ "@fictjs/runtime": "0.0.10"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "tsup src/index.ts --format cjs,esm --dts",