@barefootjs/vite 0.31.2 → 0.31.3

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 +131 -36
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -5439,7 +5439,8 @@ function visit(node, ctx, targetComponentName, namedExports) {
5439
5439
  if (!ctx.componentNode) {
5440
5440
  collectAmbientGlobals(node, ctx);
5441
5441
  }
5442
- if (ts9.isVariableStatement(node) && !ctx.componentNode) {
5442
+ const isDeclareStatement = ts9.isVariableStatement(node) && (node.modifiers?.some((m) => m.kind === ts9.SyntaxKind.DeclareKeyword) ?? false);
5443
+ if (ts9.isVariableStatement(node) && !ctx.componentNode && !isDeclareStatement) {
5443
5444
  const isExported = node.modifiers?.some((m) => m.kind === ts9.SyntaxKind.ExportKeyword) ?? false;
5444
5445
  const isLet = (node.declarationList.flags & ts9.NodeFlags.Let) !== 0;
5445
5446
  const isModuleClientDirective = hasLeadingClientDirectiveOnStatement(node, ctx.sourceFile);
@@ -5452,7 +5453,7 @@ function visit(node, ctx, targetComponentName, namedExports) {
5452
5453
  }
5453
5454
  continue;
5454
5455
  }
5455
- if (ts9.isIdentifier(decl.name) && decl.initializer && !isArrowComponentFunction(decl)) {
5456
+ if (ts9.isIdentifier(decl.name) && (decl.initializer || isLet) && !isArrowComponentFunction(decl)) {
5456
5457
  collectConstant(decl, ctx, true, isLet ? "let" : "const", isExported);
5457
5458
  }
5458
5459
  }
@@ -7023,6 +7024,7 @@ function collectConstant(node, ctx, _isModule, declarationKind = "const", isExpo
7023
7024
  value,
7024
7025
  parsed,
7025
7026
  typedValue: typedValue !== value ? typedValue : undefined,
7027
+ typeAnnotation: node.type ? node.type.getText(ctx.sourceFile) : undefined,
7026
7028
  valueBranches,
7027
7029
  declarationKind,
7028
7030
  isExported,
@@ -9427,6 +9429,83 @@ var toLocaleDatePlugin = {
9427
9429
  }
9428
9430
  };
9429
9431
 
9432
+ // ../jsx/src/scope/binding-scope.ts
9433
+ class BindingScope {
9434
+ frames;
9435
+ static EMPTY = new BindingScope([]);
9436
+ constructor(frames) {
9437
+ this.frames = frames;
9438
+ }
9439
+ enterLoopRow(loop) {
9440
+ const bindings = new Map;
9441
+ if (loop.paramBindings && loop.paramBindings.length > 0) {
9442
+ for (const b of loop.paramBindings)
9443
+ bindings.set(b.name, { source: "destructure" });
9444
+ } else {
9445
+ bindings.set(loop.param, { source: "item" });
9446
+ }
9447
+ if (loop.index != null)
9448
+ bindings.set(loop.index, { source: "index" });
9449
+ for (const name of loop.preamble?.declaredNames ?? [])
9450
+ bindings.set(name, { source: "preamble" });
9451
+ const frame = { kind: "loop-row", bindings };
9452
+ return new BindingScope([frame, ...this.frames]);
9453
+ }
9454
+ enterCallback(params) {
9455
+ const bindings = new Map;
9456
+ for (const name of params)
9457
+ bindings.set(name, { source: "param" });
9458
+ const frame = { kind: "callback", bindings };
9459
+ return new BindingScope([frame, ...this.frames]);
9460
+ }
9461
+ isBound(name) {
9462
+ for (const frame of this.frames) {
9463
+ if (frame.bindings.has(name))
9464
+ return true;
9465
+ }
9466
+ return false;
9467
+ }
9468
+ lookup(name) {
9469
+ for (let depth = 0;depth < this.frames.length; depth++) {
9470
+ const frame = this.frames[depth];
9471
+ const binding = frame.bindings.get(name);
9472
+ if (binding)
9473
+ return { depth, frame, binding };
9474
+ }
9475
+ return null;
9476
+ }
9477
+ boundNames() {
9478
+ if (this.boundNamesCache)
9479
+ return this.boundNamesCache;
9480
+ const names = new Set;
9481
+ for (const frame of this.frames) {
9482
+ for (const name of frame.bindings.keys())
9483
+ names.add(name);
9484
+ }
9485
+ this.boundNamesCache = names;
9486
+ return names;
9487
+ }
9488
+ boundNamesCache;
9489
+ valueBoundNamesCache;
9490
+ valueBoundNames() {
9491
+ if (this.valueBoundNamesCache)
9492
+ return this.valueBoundNamesCache;
9493
+ const names = new Set;
9494
+ for (const frame of this.frames) {
9495
+ for (const [name, binding] of frame.bindings) {
9496
+ if (binding.source === "item" || binding.source === "index" || binding.source === "destructure") {
9497
+ names.add(name);
9498
+ }
9499
+ }
9500
+ }
9501
+ this.valueBoundNamesCache = names;
9502
+ return names;
9503
+ }
9504
+ asShadowPredicate() {
9505
+ return (name) => this.isBound(name);
9506
+ }
9507
+ }
9508
+
9430
9509
  // ../jsx/src/jsx-to-ir.ts
9431
9510
  var CLIENT_DIRECTIVE_INTERIOR_RE2 = /^\s*@client\s*$/;
9432
9511
  var BLOCK_COMMENT_RE2 = /\/\*([\s\S]*?)\*\//g;
@@ -9607,8 +9686,9 @@ function rewriteBarePropRefs2(text, expr, ctx) {
9607
9686
  let propNames = getDestructuredPropNames(ctx);
9608
9687
  if (!propNames)
9609
9688
  return dateLowered === text ? undefined : dateLowered;
9610
- if (ctx.loopParams.size > 0) {
9611
- const filtered = new Set([...propNames].filter((n) => !ctx.loopParams.has(n)));
9689
+ const shadowingNames = ctx.scope.boundNames();
9690
+ if (shadowingNames.size > 0) {
9691
+ const filtered = new Set([...propNames].filter((n) => !shadowingNames.has(n)));
9612
9692
  if (filtered.size === 0)
9613
9693
  return dateLowered === text ? undefined : dateLowered;
9614
9694
  propNames = filtered;
@@ -9684,7 +9764,7 @@ function createTransformContext(analyzer) {
9684
9764
  spreadIdCounter: 0,
9685
9765
  isRoot: true,
9686
9766
  insideComponentChildren: false,
9687
- loopParams: new Set,
9767
+ scope: BindingScope.EMPTY,
9688
9768
  loopDepth: 0,
9689
9769
  patterns: {
9690
9770
  signals: analyzer.signals.map((s) => ({
@@ -9761,7 +9841,8 @@ function generateSpreadSlotId(ctx) {
9761
9841
  return `Spread_${ctx.spreadIdCounter++}`;
9762
9842
  }
9763
9843
  function makeBindingEnv(ctx) {
9764
- const loopKey = ctx.loopParams.size === 0 ? "" : Array.from(ctx.loopParams).sort().join("\x00");
9844
+ const boundNames = ctx.scope.valueBoundNames();
9845
+ const loopKey = boundNames.size === 0 ? "" : Array.from(boundNames).sort().join("\x00");
9765
9846
  if (ctx._bindingEnv && ctx._bindingEnvLoopKey === loopKey) {
9766
9847
  return ctx._bindingEnv;
9767
9848
  }
@@ -9776,7 +9857,7 @@ function makeBindingEnv(ctx) {
9776
9857
  localFunctions: a.localFunctions,
9777
9858
  imports: a.imports,
9778
9859
  ambientGlobals: a.ambientGlobals,
9779
- loopParams: new Set(ctx.loopParams),
9860
+ loopParams: boundNames,
9780
9861
  checker: a.checker
9781
9862
  };
9782
9863
  ctx._bindingEnv = env;
@@ -10469,7 +10550,8 @@ function transformExpressionInner(expr, ctx, node, isClientOnly) {
10469
10550
  freeRefs
10470
10551
  };
10471
10552
  const reactive = isReactiveExpression(exprText, ctx, expr) || isReactiveOrigin(origin);
10472
- const refsLoopParam = ctx.loopParams.size > 0 && Array.from(ctx.loopParams).some((p) => new RegExp(`\\b${p}\\b`).test(exprText));
10553
+ const scopeValueNames = ctx.scope.valueBoundNames();
10554
+ const refsLoopParam = scopeValueNames.size > 0 && Array.from(scopeValueNames).some((p) => new RegExp(`\\b${p}\\b`).test(exprText));
10473
10555
  const callsReactive = exprCallsReactiveGetters(expr, ctx);
10474
10556
  const hasCalls = exprHasFunctionCalls(expr);
10475
10557
  const needsSlot = reactive || isClientOnly || refsLoopParam || callsReactive || hasCalls;
@@ -11557,7 +11639,7 @@ function extractItemConditionalKey(cond) {
11557
11639
  return a ?? b;
11558
11640
  }
11559
11641
  function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
11560
- const isNested = ctx.loopParams.size > 0;
11642
+ const isNested = ctx.scope.valueBoundNames().size > 0;
11561
11643
  const diagCountAtEntry = ctx.analyzer.errors.length;
11562
11644
  const depth = ctx.loopDepth;
11563
11645
  const propAccess = node.expression;
@@ -11716,14 +11798,8 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
11716
11798
  indexType = secondParam.type.getText(ctx.sourceFile);
11717
11799
  }
11718
11800
  }
11719
- if (paramBindings) {
11720
- for (const b of paramBindings)
11721
- ctx.loopParams.add(b.name);
11722
- } else {
11723
- ctx.loopParams.add(param);
11724
- }
11725
- if (index)
11726
- ctx.loopParams.add(index);
11801
+ const savedScope = ctx.scope;
11802
+ ctx.scope = ctx.scope.enterLoopRow({ param, index, paramBindings });
11727
11803
  ctx.loopDepth++;
11728
11804
  const tryTransformRenderableBody = (expr) => {
11729
11805
  if (!ts12.isBinaryExpression(expr))
@@ -11784,6 +11860,24 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
11784
11860
  }
11785
11861
  }
11786
11862
  const returnStmt = children.length === 0 ? body.statements.find((s) => ts12.isReturnStatement(s) && s.expression != null) : undefined;
11863
+ let rowScopeBeforePreamble = null;
11864
+ if (returnStmt) {
11865
+ const preambleNames = new Set;
11866
+ for (const stmt of body.statements) {
11867
+ if (stmt === returnStmt)
11868
+ break;
11869
+ collectPreambleDeclaredNames(stmt, preambleNames);
11870
+ }
11871
+ if (preambleNames.size > 0) {
11872
+ rowScopeBeforePreamble = ctx.scope;
11873
+ ctx.scope = savedScope.enterLoopRow({
11874
+ param,
11875
+ index,
11876
+ paramBindings,
11877
+ preamble: { declaredNames: [...preambleNames] }
11878
+ });
11879
+ }
11880
+ }
11787
11881
  if (returnStmt && returnStmt.expression) {
11788
11882
  let returnExpr = returnStmt.expression;
11789
11883
  while (ts12.isParenthesizedExpression(returnExpr)) {
@@ -11853,6 +11947,9 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
11853
11947
  }
11854
11948
  }
11855
11949
  }
11950
+ if (rowScopeBeforePreamble) {
11951
+ ctx.scope = rowScopeBeforePreamble;
11952
+ }
11856
11953
  if (method === "flatMap" && children.length === 0 && !flatMapProjectionCall(body)) {
11857
11954
  flatMapCallback = buildFlatMapCallback(callback, body, ctx);
11858
11955
  }
@@ -11881,14 +11978,7 @@ function transformMapCall(node, ctx, isClientOnly = false, method = "map") {
11881
11978
  }
11882
11979
  }));
11883
11980
  }
11884
- if (paramBindings) {
11885
- for (const b of paramBindings)
11886
- ctx.loopParams.delete(b.name);
11887
- } else {
11888
- ctx.loopParams.delete(param);
11889
- }
11890
- if (index)
11891
- ctx.loopParams.delete(index);
11981
+ ctx.scope = savedScope;
11892
11982
  ctx.loopDepth--;
11893
11983
  }
11894
11984
  if (children.length === 0 && !flatMapCallback) {
@@ -12635,7 +12725,7 @@ function parseTemplateLiteral(expr, ctx) {
12635
12725
  }
12636
12726
  function tryResolveTemplateSpanFromConst(expr, ctx) {
12637
12727
  if (ts12.isIdentifier(expr)) {
12638
- if (ctx.loopParams.has(expr.text))
12728
+ if (ctx.scope.isBound(expr.text))
12639
12729
  return null;
12640
12730
  const constInfo = findLocalConst(expr.text, ctx.analyzer);
12641
12731
  if (!constInfo)
@@ -12651,7 +12741,7 @@ function tryResolveTemplateSpanFromConst(expr, ctx) {
12651
12741
  if (ts12.isElementAccessExpression(expr)) {
12652
12742
  if (!ts12.isIdentifier(expr.expression))
12653
12743
  return null;
12654
- if (ctx.loopParams.has(expr.expression.text))
12744
+ if (ctx.scope.isBound(expr.expression.text))
12655
12745
  return null;
12656
12746
  const constInfo = findLocalConst(expr.expression.text, ctx.analyzer);
12657
12747
  if (!constInfo)
@@ -12730,7 +12820,7 @@ function hasDynamicTagBinding(name, sourceFile) {
12730
12820
  return found;
12731
12821
  }
12732
12822
  function tryResolveIdentifierAsTemplateLiteral(ident, ctx) {
12733
- if (ctx.loopParams.has(ident.text))
12823
+ if (ctx.scope.isBound(ident.text))
12734
12824
  return null;
12735
12825
  const constInfo = findLocalConst(ident.text, ctx.analyzer);
12736
12826
  if (!constInfo)
@@ -13079,9 +13169,10 @@ function isSignalOrMemoArray(array, ctx) {
13079
13169
  return false;
13080
13170
  }
13081
13171
  function referencesLoopParam(expr, ctx) {
13082
- if (ctx.loopParams.size === 0)
13172
+ const boundNames = ctx.scope.valueBoundNames();
13173
+ if (boundNames.size === 0)
13083
13174
  return false;
13084
- for (const p of ctx.loopParams) {
13175
+ for (const p of boundNames) {
13085
13176
  if (new RegExp(`\\b${p}\\b`).test(expr))
13086
13177
  return true;
13087
13178
  }
@@ -13161,8 +13252,9 @@ function hasReactiveAttributes(attrs, ctx) {
13161
13252
  if (isSignalOrMemoReference(valueToCheck, ctx) || isPropsReference(valueToCheck, ctx)) {
13162
13253
  return true;
13163
13254
  }
13164
- if (ctx.loopParams.size > 0) {
13165
- for (const p of ctx.loopParams) {
13255
+ const scopeValueNames = ctx.scope.valueBoundNames();
13256
+ if (scopeValueNames.size > 0) {
13257
+ for (const p of scopeValueNames) {
13166
13258
  if (new RegExp(`\\b${p}\\b`).test(valueToCheck))
13167
13259
  return true;
13168
13260
  }
@@ -23592,7 +23684,7 @@ class JsxAdapter extends BaseAdapter {
23592
23684
  continue;
23593
23685
  const keyword = constant.declarationKind ?? "const";
23594
23686
  if (!constant.value) {
23595
- const typeAnnotation = preserveTypes && constant.type ? `: ${constant.type.raw}` : "";
23687
+ const typeAnnotation = preserveTypes && (constant.typeAnnotation ?? constant.type) ? `: ${constant.typeAnnotation ?? constant.type?.raw}` : "";
23596
23688
  lines.push(` ${keyword} ${constant.name}${typeAnnotation}`);
23597
23689
  continue;
23598
23690
  }
@@ -23602,7 +23694,8 @@ class JsxAdapter extends BaseAdapter {
23602
23694
  if (!reachable.has(constant.name))
23603
23695
  continue;
23604
23696
  const constValue = preserveTypes ? constant.typedValue ?? constant.value : constant.value;
23605
- lines.push(` ${keyword} ${constant.name} = ${constValue}`);
23697
+ const letTypeAnnotation = preserveTypes && keyword === "let" && constant.typeAnnotation ? `: ${constant.typeAnnotation}` : "";
23698
+ lines.push(` ${keyword} ${constant.name}${letTypeAnnotation} = ${constValue}`);
23606
23699
  }
23607
23700
  for (const func of localFunctions) {
23608
23701
  if (moduleScopeNames.has(func.name))
@@ -23709,7 +23802,8 @@ class JsxAdapter extends BaseAdapter {
23709
23802
  const keyword = c.declarationKind ?? "const";
23710
23803
  const exportKw = c.isExported ? "export " : "";
23711
23804
  if (!c.value) {
23712
- entries.push({ line: c.loc.start.line, text: `${exportKw}${keyword} ${c.name}` });
23805
+ const typeAnnotation = preserveTypes && (c.typeAnnotation ?? c.type) ? `: ${c.typeAnnotation ?? c.type?.raw}` : "";
23806
+ entries.push({ line: c.loc.start.line, text: `${exportKw}${keyword} ${c.name}${typeAnnotation}` });
23713
23807
  continue;
23714
23808
  }
23715
23809
  const trimmed = c.value.trim();
@@ -23718,7 +23812,8 @@ class JsxAdapter extends BaseAdapter {
23718
23812
  if (c.isExported && /^createContext\b/.test(trimmed))
23719
23813
  continue;
23720
23814
  const value = preserveTypes ? c.typedValue ?? c.value : c.value;
23721
- entries.push({ line: c.loc.start.line, text: `${exportKw}${keyword} ${c.name} = ${value}` });
23815
+ const letTypeAnnotation = preserveTypes && keyword === "let" && c.typeAnnotation ? `: ${c.typeAnnotation}` : "";
23816
+ entries.push({ line: c.loc.start.line, text: `${exportKw}${keyword} ${c.name}${letTypeAnnotation} = ${value}` });
23722
23817
  }
23723
23818
  for (const f of ir.metadata.localFunctions) {
23724
23819
  if (!f.isModule || !moduleNames.has(f.name))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/vite",
3
- "version": "0.31.2",
3
+ "version": "0.31.3",
4
4
  "description": "Vite plugin for BarefootJS: Vite/Rollup owns bundling, hashing, chunking, tree-shaking and minification of client assets, BarefootJS keeps only the JSX to (template, client JS) compile",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -38,17 +38,17 @@
38
38
  "directory": "packages/vite"
39
39
  },
40
40
  "dependencies": {
41
- "@barefootjs/shared": "0.31.2"
41
+ "@barefootjs/shared": "0.31.3"
42
42
  },
43
43
  "peerDependencies": {
44
44
  "@barefootjs/jsx": ">=0.2.0",
45
45
  "vite": "^6.0.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@barefootjs/client": "0.31.2",
49
- "@barefootjs/go-template": "0.31.2",
50
- "@barefootjs/hono": "0.31.2",
51
- "@barefootjs/jsx": "0.31.2",
48
+ "@barefootjs/client": "0.31.3",
49
+ "@barefootjs/go-template": "0.31.3",
50
+ "@barefootjs/hono": "0.31.3",
51
+ "@barefootjs/jsx": "0.31.3",
52
52
  "typescript": "^5.0.0",
53
53
  "vite": "^6.0.0"
54
54
  }