@barefootjs/rust 0.31.10 → 0.33.0

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.
@@ -89,8 +89,11 @@ export interface JinjaMemoContext {
89
89
  /**
90
90
  * Lower a JS expression to its Jinja form (the core recursive entry). See
91
91
  * `JinjaSpreadContext.convertExpressionToJinja` for the `preParsed` contract.
92
+ * `pos` (default `'rendered'`) must be `'value'` for a derived-seed RHS —
93
+ * an assignment, not a render — so the internal support gate matches the
94
+ * `isSupportedValue` classification the seed plan already used.
92
95
  */
93
- convertExpressionToJinja(expr: string, preParsed?: ParsedExpr): string;
96
+ convertExpressionToJinja(expr: string, preParsed?: ParsedExpr, pos?: 'rendered' | 'value'): string;
94
97
  /**
95
98
  * Per-compile diagnostic list `convertExpressionToJinja` appends to on an
96
99
  * unsupported shape (`_recordExprBF101`). `memo/seed.ts`'s
@@ -1 +1 @@
1
- {"version":3,"file":"emit-context.d.ts","sourceRoot":"","sources":["../../src/adapter/emit-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5E,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAEzC;;;OAGG;IACH,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEtD,oFAAoF;IACpF,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEjD;;;OAGG;IACH,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAE3E,wDAAwD;IACxD,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAExD,yEAAyE;IACzE,4BAA4B,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAE9B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;IAEhC,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAErD,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAExC;;;;;;;;OAQG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAEtE;;;;;;OAMG;IACH,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAEtE;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;CACjC"}
1
+ {"version":3,"file":"emit-context.d.ts","sourceRoot":"","sources":["../../src/adapter/emit-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5E,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAEzC;;;OAGG;IACH,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEtD,oFAAoF;IACpF,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAEjD;;;OAGG;IACH,2BAA2B,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAE3E,wDAAwD;IACxD,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAExD,yEAAyE;IACzE,4BAA4B,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAE9B,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;IAEhC,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAErD,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAExC;;;;;;;;OAQG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAEtE;;;;;;OAMG;IACH,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;CACtE;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,MAAM,CAAA;IAElG;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,EAAE,aAAa,EAAE,CAAA;CACjC"}
@@ -138,6 +138,6 @@ export declare class JinjaTopLevelEmitter implements ParsedExprEmitter {
138
138
  arrow(_params: string[], _body: ParsedExpr): string;
139
139
  regex(_raw: string): string;
140
140
  unsupported(_raw: string, _reason: string): string;
141
- objectLiteral(properties: ObjectLiteralProperty[], _raw: string, _emit: (e: ParsedExpr) => string): string;
141
+ objectLiteral(properties: ObjectLiteralProperty[], raw: string, emit: (e: ParsedExpr) => string): string;
142
142
  }
143
143
  //# sourceMappingURL=emitters.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"emitters.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/emitters.ts"],"names":[],"mappings":"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"}
@@ -187297,6 +187297,7 @@ import {
187297
187297
  parseProviderObjectLiteral,
187298
187298
  parseStyleObjectEntries,
187299
187299
  isSupported,
187300
+ isSupportedValue,
187300
187301
  emitParsedExpr,
187301
187302
  emitIRNode,
187302
187303
  emitAttrValue,
@@ -188050,8 +188051,22 @@ class JinjaTopLevelEmitter {
188050
188051
  unsupported(_raw, _reason) {
188051
188052
  return "''";
188052
188053
  }
188053
- objectLiteral(properties, _raw, _emit) {
188054
- return properties.length === 0 ? "{}" : "''";
188054
+ objectLiteral(properties, raw, emit) {
188055
+ if (properties.length === 0)
188056
+ return "{}";
188057
+ if (!properties.some((p) => p.kind === "spread")) {
188058
+ return `{${properties.map((p) => p.kind === "prop" ? `${minijinjaHashKey(p.key)}: ${emit(p.value)}` : "").join(", ")}}`;
188059
+ }
188060
+ const [first, ...rest] = properties;
188061
+ const kwargSafe = (p) => p.keyKind !== "numeric" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(p.key) && !RESERVED_WORDS.has(p.key);
188062
+ const shapeOk = first.kind === "spread" && rest.every((p) => p.kind === "prop" && kwargSafe(p));
188063
+ if (!shapeOk) {
188064
+ this.ctx._recordExprBF101(`Object-literal spread '${raw}' isn't expressible in minijinja — a spread must be the FIRST entry, followed only by plain properties with bareword-identifier keys (minijinja's 'dict(value, **kwargs)' has no '**expr' unpack for a dynamic override)`, `Reorder so the spread comes first with only simple identifier keys after it, or precompute the merged object and move this position to a '/* @client */' boundary.`);
188065
+ return "''";
188066
+ }
188067
+ const kwargs = rest.map((p) => `${p.key}=${emit(p.value)}`);
188068
+ const base = emit(first.expr);
188069
+ return kwargs.length === 0 ? `dict(${base})` : `dict(${base}, ${kwargs.join(", ")})`;
188055
188070
  }
188056
188071
  }
188057
188072
 
@@ -188165,6 +188180,8 @@ function objectLiteralExprToJinjaDict(ctx, expr) {
188165
188180
  function objectLiteralToJinjaDict(ctx, obj) {
188166
188181
  const entries = [];
188167
188182
  for (const prop of obj.properties) {
188183
+ if (prop.kind === "spread")
188184
+ return null;
188168
188185
  if (prop.shorthand)
188169
188186
  return null;
188170
188187
  if (prop.keyKind === "numeric")
@@ -188240,7 +188257,7 @@ function generateDerivedMemoSeed(ctx, ir) {
188240
188257
  continue;
188241
188258
  const materialized = materializeGetterCalls(step.parsed, knownGetterNames);
188242
188259
  const errorsBefore = ctx.errors.length;
188243
- const jinja = ctx.convertExpressionToJinja("", materialized);
188260
+ const jinja = ctx.convertExpressionToJinja("", materialized, "value");
188244
188261
  if (ctx.errors.length > errorsBefore) {
188245
188262
  ctx.errors.length = errorsBefore;
188246
188263
  continue;
@@ -189068,11 +189085,11 @@ ${reason}` : "";
189068
189085
  }
189069
189086
  get memoCtx() {
189070
189087
  return {
189071
- convertExpressionToJinja: (e, preParsed) => this.convertExpressionToJinja(e, preParsed),
189088
+ convertExpressionToJinja: (e, preParsed, pos) => this.convertExpressionToJinja(e, preParsed, pos),
189072
189089
  errors: this.errors
189073
189090
  };
189074
189091
  }
189075
- convertExpressionToJinja(expr, preParsed) {
189092
+ convertExpressionToJinja(expr, preParsed, pos = "rendered") {
189076
189093
  let parsed;
189077
189094
  if (preParsed) {
189078
189095
  parsed = preParsed;
@@ -189095,7 +189112,7 @@ ${reason}` : "";
189095
189112
  }
189096
189113
  }
189097
189114
  }
189098
- const support = isSupported(parsed);
189115
+ const support = pos === "value" ? isSupportedValue(parsed) : isSupported(parsed);
189099
189116
  if (!support.supported) {
189100
189117
  this.errors.push({
189101
189118
  code: "BF101",
@@ -52,6 +52,13 @@ export declare function escapeMinijinjaSingleQuoted(s: string): string;
52
52
  * become a variable lookup instead of a string key.
53
53
  */
54
54
  export declare function minijinjaHashKey(name: string): string;
55
+ /**
56
+ * Python reserved words (the plan's list) that must not appear as a bare
57
+ * Jinja identifier — see the file header. Kept as the single source of
58
+ * truth, IDENTICAL to adapter-jinja's set; the Rust runtime's
59
+ * `mangle_ident` mirrors this exact set.
60
+ */
61
+ export declare const RESERVED_WORDS: Set<string>;
55
62
  /**
56
63
  * Mangle a JS identifier (prop name, signal getter, loop param, …) into a
57
64
  * Jinja-safe variable name: reserved words get a trailing `_` suffix,
@@ -1 +1 @@
1
- {"version":3,"file":"minijinja-naming.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/minijinja-naming.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAeD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
1
+ {"version":3,"file":"minijinja-naming.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/minijinja-naming.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,aAKzB,CAAA;AAEF;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD"}
@@ -1 +1 @@
1
- {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../../src/adapter/memo/seed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,EAIrB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAI1D,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAM9D;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAWnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,gBAAgB,EAAE,EAAE,EAAE,WAAW,GAAG,MAAM,CAsBtF"}
1
+ {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../../src/adapter/memo/seed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,EAIrB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAI1D,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAM9D;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAWnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,gBAAgB,EAAE,EAAE,EAAE,WAAW,GAAG,MAAM,CAuBtF"}
@@ -1 +1 @@
1
- {"version":3,"file":"minijinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/minijinja-adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"minijinja-adapter.d.ts","sourceRoot":"","sources":["../../src/adapter/minijinja-adapter.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"spread-codegen.d.ts","sourceRoot":"","sources":["../../../src/adapter/spread/spread-codegen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAG5D;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,UAAU,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAcf;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,UAAU,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAGf;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,kBAAkB,EACvB,GAAG,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC,GACnD,MAAM,GAAG,IAAI,CA0Cf;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAuBhG"}
1
+ {"version":3,"file":"spread-codegen.d.ts","sourceRoot":"","sources":["../../../src/adapter/spread/spread-codegen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAG5D;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,UAAU,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAcf;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,kBAAkB,EACvB,IAAI,EAAE,UAAU,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAGf;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,kBAAkB,EACvB,GAAG,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC,GACnD,MAAM,GAAG,IAAI,CA8Cf;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAuBhG"}
package/dist/index.js CHANGED
@@ -187297,6 +187297,7 @@ import {
187297
187297
  parseProviderObjectLiteral,
187298
187298
  parseStyleObjectEntries,
187299
187299
  isSupported,
187300
+ isSupportedValue,
187300
187301
  emitParsedExpr,
187301
187302
  emitIRNode,
187302
187303
  emitAttrValue,
@@ -188050,8 +188051,22 @@ class JinjaTopLevelEmitter {
188050
188051
  unsupported(_raw, _reason) {
188051
188052
  return "''";
188052
188053
  }
188053
- objectLiteral(properties, _raw, _emit) {
188054
- return properties.length === 0 ? "{}" : "''";
188054
+ objectLiteral(properties, raw, emit) {
188055
+ if (properties.length === 0)
188056
+ return "{}";
188057
+ if (!properties.some((p) => p.kind === "spread")) {
188058
+ return `{${properties.map((p) => p.kind === "prop" ? `${minijinjaHashKey(p.key)}: ${emit(p.value)}` : "").join(", ")}}`;
188059
+ }
188060
+ const [first, ...rest] = properties;
188061
+ const kwargSafe = (p) => p.keyKind !== "numeric" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(p.key) && !RESERVED_WORDS.has(p.key);
188062
+ const shapeOk = first.kind === "spread" && rest.every((p) => p.kind === "prop" && kwargSafe(p));
188063
+ if (!shapeOk) {
188064
+ this.ctx._recordExprBF101(`Object-literal spread '${raw}' isn't expressible in minijinja — a spread must be the FIRST entry, followed only by plain properties with bareword-identifier keys (minijinja's 'dict(value, **kwargs)' has no '**expr' unpack for a dynamic override)`, `Reorder so the spread comes first with only simple identifier keys after it, or precompute the merged object and move this position to a '/* @client */' boundary.`);
188065
+ return "''";
188066
+ }
188067
+ const kwargs = rest.map((p) => `${p.key}=${emit(p.value)}`);
188068
+ const base = emit(first.expr);
188069
+ return kwargs.length === 0 ? `dict(${base})` : `dict(${base}, ${kwargs.join(", ")})`;
188055
188070
  }
188056
188071
  }
188057
188072
 
@@ -188165,6 +188180,8 @@ function objectLiteralExprToJinjaDict(ctx, expr) {
188165
188180
  function objectLiteralToJinjaDict(ctx, obj) {
188166
188181
  const entries = [];
188167
188182
  for (const prop of obj.properties) {
188183
+ if (prop.kind === "spread")
188184
+ return null;
188168
188185
  if (prop.shorthand)
188169
188186
  return null;
188170
188187
  if (prop.keyKind === "numeric")
@@ -188240,7 +188257,7 @@ function generateDerivedMemoSeed(ctx, ir) {
188240
188257
  continue;
188241
188258
  const materialized = materializeGetterCalls(step.parsed, knownGetterNames);
188242
188259
  const errorsBefore = ctx.errors.length;
188243
- const jinja = ctx.convertExpressionToJinja("", materialized);
188260
+ const jinja = ctx.convertExpressionToJinja("", materialized, "value");
188244
188261
  if (ctx.errors.length > errorsBefore) {
188245
188262
  ctx.errors.length = errorsBefore;
188246
188263
  continue;
@@ -189068,11 +189085,11 @@ ${reason}` : "";
189068
189085
  }
189069
189086
  get memoCtx() {
189070
189087
  return {
189071
- convertExpressionToJinja: (e, preParsed) => this.convertExpressionToJinja(e, preParsed),
189088
+ convertExpressionToJinja: (e, preParsed, pos) => this.convertExpressionToJinja(e, preParsed, pos),
189072
189089
  errors: this.errors
189073
189090
  };
189074
189091
  }
189075
- convertExpressionToJinja(expr, preParsed) {
189092
+ convertExpressionToJinja(expr, preParsed, pos = "rendered") {
189076
189093
  let parsed;
189077
189094
  if (preParsed) {
189078
189095
  parsed = preParsed;
@@ -189095,7 +189112,7 @@ ${reason}` : "";
189095
189112
  }
189096
189113
  }
189097
189114
  }
189098
- const support = isSupported(parsed);
189115
+ const support = pos === "value" ? isSupportedValue(parsed) : isSupported(parsed);
189099
189116
  if (!support.supported) {
189100
189117
  this.errors.push({
189101
189118
  code: "BF101",
@@ -1 +1 @@
1
- {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAExD,eAAO,MAAM,iBAAiB,EAAE,iBAC/B,CAAA"}
1
+ {"version":3,"file":"render-divergences.d.ts","sourceRoot":"","sources":["../src/render-divergences.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAQxD,eAAO,MAAM,iBAAiB,EAAE,iBAAsB,CAAA"}
package/dist/vite.js CHANGED
@@ -263,7 +263,7 @@ function convertNode(node, raw) {
263
263
  }
264
264
  if (n === undefined || Number.isNaN(n)) {
265
265
  const parsedDepth = convertNode(depthNode, raw);
266
- if (checkSupport(parsedDepth).supported) {
266
+ if (checkSupport(parsedDepth, "rendered").supported) {
267
267
  depthExpr = parsedDepth;
268
268
  flatDepth = 1;
269
269
  } else {
@@ -357,10 +357,12 @@ function convertNode(node, raw) {
357
357
  const k = objectLiteralKeyName(prop.name);
358
358
  if (k === null)
359
359
  return { kind: "unsupported", raw, reason: `Unsupported syntax: ${ts.SyntaxKind[node.kind]}` };
360
- properties.push({ key: k.key, keyKind: k.keyKind, shorthand: false, value: convertNode(prop.initializer, raw) });
360
+ properties.push({ kind: "prop", key: k.key, keyKind: k.keyKind, shorthand: false, value: convertNode(prop.initializer, raw) });
361
361
  } else if (ts.isShorthandPropertyAssignment(prop)) {
362
362
  const key = prop.name.text;
363
- properties.push({ key, keyKind: "identifier", shorthand: true, value: { kind: "identifier", name: key } });
363
+ properties.push({ kind: "prop", key, keyKind: "identifier", shorthand: true, value: { kind: "identifier", name: key } });
364
+ } else if (ts.isSpreadAssignment(prop)) {
365
+ properties.push({ kind: "spread", expr: convertNode(prop.expression, raw) });
364
366
  } else {
365
367
  return { kind: "unsupported", raw, reason: `Unsupported syntax: ${ts.SyntaxKind[node.kind]}` };
366
368
  }
@@ -1040,14 +1042,26 @@ function getUnaryOperatorString(op) {
1040
1042
  }
1041
1043
  }
1042
1044
  function isSupported(expr) {
1043
- return checkSupport(expr);
1045
+ return checkSupport(expr, "rendered");
1044
1046
  }
1045
- function checkSupport(expr) {
1047
+ function isSupportedValue(expr) {
1048
+ return checkSupport(expr, "value");
1049
+ }
1050
+ function checkSupport(expr, pos) {
1046
1051
  switch (expr.kind) {
1047
1052
  case "unsupported":
1048
1053
  return { supported: false, reason: expr.reason };
1049
- case "object-literal":
1050
- return { supported: false, reason: "Unsupported syntax: ObjectLiteralExpression" };
1054
+ case "object-literal": {
1055
+ if (pos !== "value") {
1056
+ return { supported: false, reason: "Unsupported syntax: ObjectLiteralExpression" };
1057
+ }
1058
+ for (const prop of expr.properties) {
1059
+ const propSupport = checkSupport(prop.kind === "spread" ? prop.expr : prop.value, pos);
1060
+ if (!propSupport.supported)
1061
+ return propSupport;
1062
+ }
1063
+ return { supported: true, level: "L2" };
1064
+ }
1051
1065
  case "identifier":
1052
1066
  return { supported: true, level: "L1" };
1053
1067
  case "literal":
@@ -1057,7 +1071,7 @@ function checkSupport(expr) {
1057
1071
  return { supported: false, reason: "Standalone arrow functions / regex literals are not supported" };
1058
1072
  case "array-literal": {
1059
1073
  for (const el of expr.elements) {
1060
- const elSupport = checkSupport(el);
1074
+ const elSupport = checkSupport(el, pos);
1061
1075
  if (!elSupport.supported)
1062
1076
  return elSupport;
1063
1077
  }
@@ -1070,16 +1084,16 @@ function checkSupport(expr) {
1070
1084
  reason: `String.prototype.${expr.method} supports only a string pattern + string replacement (the regex form is deferred); use a string pattern or wrap the expression in /* @client */`
1071
1085
  };
1072
1086
  }
1073
- const objSupport = checkSupport(expr.object);
1087
+ const objSupport = checkSupport(expr.object, pos);
1074
1088
  if (!objSupport.supported)
1075
1089
  return objSupport;
1076
1090
  for (const arg of expr.args) {
1077
- const argSupport = checkSupport(arg);
1091
+ const argSupport = checkSupport(arg, pos);
1078
1092
  if (!argSupport.supported)
1079
1093
  return argSupport;
1080
1094
  }
1081
1095
  if (expr.method === "flat" && expr.depthExpr) {
1082
- const depthSupport = checkSupport(expr.depthExpr);
1096
+ const depthSupport = checkSupport(expr.depthExpr, pos);
1083
1097
  if (!depthSupport.supported)
1084
1098
  return depthSupport;
1085
1099
  }
@@ -1088,10 +1102,10 @@ function checkSupport(expr) {
1088
1102
  case "call": {
1089
1103
  const cb = asCallbackMethodCall(expr);
1090
1104
  if (cb) {
1091
- const objSupport = checkSupport(cb.object);
1105
+ const objSupport = checkSupport(cb.object, pos);
1092
1106
  if (!objSupport.supported)
1093
1107
  return objSupport;
1094
- const bodySupport = checkSupport(cb.arrow.body);
1108
+ const bodySupport = checkSupport(cb.arrow.body, pos);
1095
1109
  if (!bodySupport.supported) {
1096
1110
  return {
1097
1111
  supported: false,
@@ -1100,13 +1114,13 @@ function checkSupport(expr) {
1100
1114
  };
1101
1115
  }
1102
1116
  for (const rest of cb.args) {
1103
- const restSupport = checkSupport(rest);
1117
+ const restSupport = checkSupport(rest, pos);
1104
1118
  if (!restSupport.supported)
1105
1119
  return restSupport;
1106
1120
  }
1107
1121
  return { supported: true, level: "L5" };
1108
1122
  }
1109
- const calleeSupport = checkSupport(expr.callee);
1123
+ const calleeSupport = checkSupport(expr.callee, pos);
1110
1124
  if (!calleeSupport.supported) {
1111
1125
  return calleeSupport;
1112
1126
  }
@@ -1125,7 +1139,7 @@ function checkSupport(expr) {
1125
1139
  return { supported: true, level: "L1" };
1126
1140
  }
1127
1141
  for (const arg of expr.args) {
1128
- const argSupport = checkSupport(arg);
1142
+ const argSupport = checkSupport(arg, pos);
1129
1143
  if (!argSupport.supported) {
1130
1144
  return argSupport;
1131
1145
  }
@@ -1133,7 +1147,7 @@ function checkSupport(expr) {
1133
1147
  return { supported: true, level: "L2" };
1134
1148
  }
1135
1149
  case "member": {
1136
- const objSupport = checkSupport(expr.object);
1150
+ const objSupport = checkSupport(expr.object, pos);
1137
1151
  if (!objSupport.supported) {
1138
1152
  return objSupport;
1139
1153
  }
@@ -1143,19 +1157,19 @@ function checkSupport(expr) {
1143
1157
  return { supported: true, level: "L2" };
1144
1158
  }
1145
1159
  case "index-access": {
1146
- const objSupport = checkSupport(expr.object);
1160
+ const objSupport = checkSupport(expr.object, pos);
1147
1161
  if (!objSupport.supported)
1148
1162
  return objSupport;
1149
- const indexSupport = checkSupport(expr.index);
1163
+ const indexSupport = checkSupport(expr.index, pos);
1150
1164
  if (!indexSupport.supported)
1151
1165
  return indexSupport;
1152
1166
  return { supported: true, level: "L2" };
1153
1167
  }
1154
1168
  case "binary": {
1155
- const leftSupport = checkSupport(expr.left);
1169
+ const leftSupport = checkSupport(expr.left, pos);
1156
1170
  if (!leftSupport.supported)
1157
1171
  return leftSupport;
1158
- const rightSupport = checkSupport(expr.right);
1172
+ const rightSupport = checkSupport(expr.right, pos);
1159
1173
  if (!rightSupport.supported)
1160
1174
  return rightSupport;
1161
1175
  if (["===", "==", "!==", "!=", ">", "<", ">=", "<="].includes(expr.op)) {
@@ -1167,7 +1181,7 @@ function checkSupport(expr) {
1167
1181
  return { supported: false, reason: `Unknown operator: ${expr.op}` };
1168
1182
  }
1169
1183
  case "unary": {
1170
- const argSupport = checkSupport(expr.argument);
1184
+ const argSupport = checkSupport(expr.argument, pos);
1171
1185
  if (!argSupport.supported)
1172
1186
  return argSupport;
1173
1187
  if (expr.op === "!") {
@@ -1179,25 +1193,25 @@ function checkSupport(expr) {
1179
1193
  return { supported: false, reason: `Unsupported unary operator: ${expr.op}` };
1180
1194
  }
1181
1195
  case "logical": {
1182
- const leftSupport = checkSupport(expr.left);
1196
+ const leftSupport = checkSupport(expr.left, pos);
1183
1197
  if (!leftSupport.supported)
1184
1198
  return leftSupport;
1185
1199
  if (expr.op === "??" && expr.right.kind === "object-literal" && expr.right.properties.length === 0) {
1186
1200
  return { supported: true, level: "L4" };
1187
1201
  }
1188
- const rightSupport = checkSupport(expr.right);
1202
+ const rightSupport = checkSupport(expr.right, pos);
1189
1203
  if (!rightSupport.supported)
1190
1204
  return rightSupport;
1191
1205
  return { supported: true, level: "L4" };
1192
1206
  }
1193
1207
  case "conditional": {
1194
- const testSupport = checkSupport(expr.test);
1208
+ const testSupport = checkSupport(expr.test, pos);
1195
1209
  if (!testSupport.supported)
1196
1210
  return testSupport;
1197
- const consSupport = checkSupport(expr.consequent);
1211
+ const consSupport = checkSupport(expr.consequent, pos);
1198
1212
  if (!consSupport.supported)
1199
1213
  return consSupport;
1200
- const altSupport = checkSupport(expr.alternate);
1214
+ const altSupport = checkSupport(expr.alternate, pos);
1201
1215
  if (!altSupport.supported)
1202
1216
  return altSupport;
1203
1217
  return { supported: true, level: "L4" };
@@ -1205,7 +1219,7 @@ function checkSupport(expr) {
1205
1219
  case "template-literal": {
1206
1220
  for (const part of expr.parts) {
1207
1221
  if (part.type === "expression") {
1208
- const partSupport = checkSupport(part.expr);
1222
+ const partSupport = checkSupport(part.expr, pos);
1209
1223
  if (!partSupport.supported)
1210
1224
  return partSupport;
1211
1225
  }
@@ -1321,7 +1335,7 @@ function isPureInit(e, pureCallNames) {
1321
1335
  case "array-literal":
1322
1336
  return e.elements.every(pure);
1323
1337
  case "object-literal":
1324
- return e.properties.every((p) => pure(p.value));
1338
+ return e.properties.every((p) => pure(p.kind === "spread" ? p.expr : p.value));
1325
1339
  case "call":
1326
1340
  return e.callee.kind === "identifier" && e.args.length === 0 && pureCallNames !== undefined && pureCallNames.has(e.callee.name);
1327
1341
  case "array-method":
@@ -1375,7 +1389,7 @@ function usesPerPath(name, expr) {
1375
1389
  }
1376
1390
  return add(walk(e.object), sum(e.args));
1377
1391
  case "object-literal":
1378
- return sum(e.properties.map((p) => p.value));
1392
+ return sum(e.properties.map((p) => p.kind === "spread" ? p.expr : p.value));
1379
1393
  case "arrow":
1380
1394
  return walk(e.body).max > 0 ? { min: 0, max: Number.POSITIVE_INFINITY } : { min: 0, max: 0 };
1381
1395
  }
@@ -1441,7 +1455,7 @@ function inlineBinding(expr, name, value) {
1441
1455
  case "object-literal":
1442
1456
  return {
1443
1457
  kind: "object-literal",
1444
- properties: e.properties.map((p) => ({ ...p, value: walk(p.value, enclosing) })),
1458
+ properties: e.properties.map((p) => p.kind === "spread" ? { ...p, expr: walk(p.expr, enclosing) } : { ...p, value: walk(p.value, enclosing) }),
1445
1459
  raw: e.raw
1446
1460
  };
1447
1461
  case "literal":
@@ -1651,7 +1665,7 @@ function materializeGetterCalls(expr, names) {
1651
1665
  return {
1652
1666
  kind: "object-literal",
1653
1667
  raw: expr.raw,
1654
- properties: expr.properties.map((p) => ({ ...p, value: rw(p.value) }))
1668
+ properties: expr.properties.map((p) => p.kind === "spread" ? { ...p, expr: rw(p.expr) } : { ...p, value: rw(p.value) })
1655
1669
  };
1656
1670
  case "arrow":
1657
1671
  return { kind: "arrow", params: expr.params, body: rw(expr.body) };
@@ -1709,7 +1723,7 @@ function freeVarsInBody(body, params) {
1709
1723
  return;
1710
1724
  case "object-literal":
1711
1725
  for (const p of e.properties)
1712
- visit(p.value, bound);
1726
+ visit(p.kind === "spread" ? p.expr : p.value, bound);
1713
1727
  return;
1714
1728
  case "array-method":
1715
1729
  if (e.method === "includes" || e.method === "join") {
@@ -1784,7 +1798,7 @@ function freeIdentifiers(expr) {
1784
1798
  return true;
1785
1799
  case "object-literal":
1786
1800
  for (const p of e.properties)
1787
- if (!visit(p.value, bound))
1801
+ if (!visit(p.kind === "spread" ? p.expr : p.value, bound))
1788
1802
  return false;
1789
1803
  return true;
1790
1804
  case "arrow": {
@@ -1931,10 +1945,17 @@ function toEvalNode(e) {
1931
1945
  case "object-literal": {
1932
1946
  const properties = [];
1933
1947
  for (const p of e.properties) {
1948
+ if (p.kind === "spread") {
1949
+ const spreadExpr = toEvalNode(p.expr);
1950
+ if (!spreadExpr)
1951
+ return null;
1952
+ properties.push({ kind: "spread", expr: spreadExpr });
1953
+ continue;
1954
+ }
1934
1955
  const value = toEvalNode(p.value);
1935
1956
  if (!value)
1936
1957
  return null;
1937
- properties.push({ key: p.key, value });
1958
+ properties.push({ kind: "prop", key: p.key, value });
1938
1959
  }
1939
1960
  return { kind: "object-literal", properties };
1940
1961
  }
@@ -2967,6 +2988,8 @@ function matchToLocaleDateStringCall(callee, args, metadata) {
2967
2988
  let tz = null;
2968
2989
  const probeOptions = {};
2969
2990
  for (const prop of options.properties) {
2991
+ if (prop.kind === "spread")
2992
+ return null;
2970
2993
  if (prop.value.kind !== "literal" || prop.value.literalType !== "string")
2971
2994
  return null;
2972
2995
  const value = String(prop.value.value);
@@ -3957,7 +3980,7 @@ function parseRecordIndexAccess(val, localConstants, propsParams, resolveKey) {
3957
3980
 
3958
3981
  // ../jsx/src/ssr-seed-plan.ts
3959
3982
  function classify(name, origin, expr, parsed, available) {
3960
- if (!isSupported(parsed).supported)
3983
+ if (!isSupportedValue(parsed).supported)
3961
3984
  return { kind: "opaque", name, origin };
3962
3985
  const frees = freeIdentifiers(parsed);
3963
3986
  if (frees === null)
@@ -4020,7 +4043,7 @@ function computeSsrSeedPlan(metadata) {
4020
4043
  }
4021
4044
  }
4022
4045
  const expr = signal.initialValue.trim();
4023
- steps.push(expr === "" ? { kind: "opaque", name: signal.getter, origin: "signal" } : classify(signal.getter, "signal", expr, resolveThroughLocalConsts(parseExpression(expr), localConsts), available));
4046
+ steps.push(expr === "" ? { kind: "opaque", name: signal.getter, origin: "signal" } : classify(signal.getter, "signal", expr, resolveThroughLocalConsts(signal.parsed ?? parseExpression(`(${expr})`), localConsts), available));
4024
4047
  available.add(signal.getter);
4025
4048
  }
4026
4049
  for (const memo of metadata.memos) {
@@ -4706,6 +4729,17 @@ function evaluateStaticLiteral(expr, bindings) {
4706
4729
  case "object-literal": {
4707
4730
  const out = {};
4708
4731
  for (const prop of expr.properties) {
4732
+ if (prop.kind === "spread") {
4733
+ const resolved2 = evaluateStaticLiteral(prop.expr, bindings);
4734
+ if (!resolved2)
4735
+ return null;
4736
+ if (resolved2.value === null || resolved2.value === undefined)
4737
+ continue;
4738
+ if (typeof resolved2.value !== "object" || Array.isArray(resolved2.value))
4739
+ return null;
4740
+ Object.assign(out, resolved2.value);
4741
+ continue;
4742
+ }
4709
4743
  const resolved = evaluateStaticLiteral(prop.value, bindings);
4710
4744
  if (!resolved)
4711
4745
  return null;
@@ -4772,6 +4806,8 @@ function matchQueryHrefCall(callee, args, localNames) {
4772
4806
  return null;
4773
4807
  const triples = [];
4774
4808
  for (const p of obj.properties) {
4809
+ if (p.kind === "spread")
4810
+ return null;
4775
4811
  const v = p.value;
4776
4812
  if (v.kind === "conditional" && isOmitBranch(v.alternate)) {
4777
4813
  triples.push({ guard: v.test, key: p.key, value: v.consequent });
@@ -4959,6 +4995,8 @@ function htmlPropValue(parsed) {
4959
4995
  if (parsed.properties.length !== 1)
4960
4996
  return null;
4961
4997
  const [prop] = parsed.properties;
4998
+ if (prop.kind === "spread")
4999
+ return null;
4962
5000
  if (prop.key !== "__html")
4963
5001
  return null;
4964
5002
  return prop.value;
@@ -5860,8 +5898,22 @@ class JinjaTopLevelEmitter {
5860
5898
  unsupported(_raw, _reason) {
5861
5899
  return "''";
5862
5900
  }
5863
- objectLiteral(properties, _raw, _emit) {
5864
- return properties.length === 0 ? "{}" : "''";
5901
+ objectLiteral(properties, raw, emit) {
5902
+ if (properties.length === 0)
5903
+ return "{}";
5904
+ if (!properties.some((p) => p.kind === "spread")) {
5905
+ return `{${properties.map((p) => p.kind === "prop" ? `${minijinjaHashKey(p.key)}: ${emit(p.value)}` : "").join(", ")}}`;
5906
+ }
5907
+ const [first, ...rest] = properties;
5908
+ const kwargSafe = (p) => p.keyKind !== "numeric" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(p.key) && !RESERVED_WORDS2.has(p.key);
5909
+ const shapeOk = first.kind === "spread" && rest.every((p) => p.kind === "prop" && kwargSafe(p));
5910
+ if (!shapeOk) {
5911
+ this.ctx._recordExprBF101(`Object-literal spread '${raw}' isn't expressible in minijinja — a spread must be the FIRST entry, followed only by plain properties with bareword-identifier keys (minijinja's 'dict(value, **kwargs)' has no '**expr' unpack for a dynamic override)`, `Reorder so the spread comes first with only simple identifier keys after it, or precompute the merged object and move this position to a '/* @client */' boundary.`);
5912
+ return "''";
5913
+ }
5914
+ const kwargs = rest.map((p) => `${p.key}=${emit(p.value)}`);
5915
+ const base = emit(first.expr);
5916
+ return kwargs.length === 0 ? `dict(${base})` : `dict(${base}, ${kwargs.join(", ")})`;
5865
5917
  }
5866
5918
  }
5867
5919
 
@@ -5974,6 +6026,8 @@ function objectLiteralExprToJinjaDict(ctx, expr) {
5974
6026
  function objectLiteralToJinjaDict(ctx, obj) {
5975
6027
  const entries = [];
5976
6028
  for (const prop of obj.properties) {
6029
+ if (prop.kind === "spread")
6030
+ return null;
5977
6031
  if (prop.shorthand)
5978
6032
  return null;
5979
6033
  if (prop.keyKind === "numeric")
@@ -6044,7 +6098,7 @@ function generateDerivedMemoSeed(ctx, ir) {
6044
6098
  continue;
6045
6099
  const materialized = materializeGetterCalls(step.parsed, knownGetterNames);
6046
6100
  const errorsBefore = ctx.errors.length;
6047
- const jinja = ctx.convertExpressionToJinja("", materialized);
6101
+ const jinja = ctx.convertExpressionToJinja("", materialized, "value");
6048
6102
  if (ctx.errors.length > errorsBefore) {
6049
6103
  ctx.errors.length = errorsBefore;
6050
6104
  continue;
@@ -6871,11 +6925,11 @@ ${reason}` : "";
6871
6925
  }
6872
6926
  get memoCtx() {
6873
6927
  return {
6874
- convertExpressionToJinja: (e, preParsed) => this.convertExpressionToJinja(e, preParsed),
6928
+ convertExpressionToJinja: (e, preParsed, pos) => this.convertExpressionToJinja(e, preParsed, pos),
6875
6929
  errors: this.errors
6876
6930
  };
6877
6931
  }
6878
- convertExpressionToJinja(expr, preParsed) {
6932
+ convertExpressionToJinja(expr, preParsed, pos = "rendered") {
6879
6933
  let parsed;
6880
6934
  if (preParsed) {
6881
6935
  parsed = preParsed;
@@ -6898,7 +6952,7 @@ ${reason}` : "";
6898
6952
  }
6899
6953
  }
6900
6954
  }
6901
- const support = isSupported(parsed);
6955
+ const support = pos === "value" ? isSupportedValue(parsed) : isSupported(parsed);
6902
6956
  if (!support.supported) {
6903
6957
  this.errors.push({
6904
6958
  code: "BF101",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barefootjs/rust",
3
- "version": "0.31.10",
3
+ "version": "0.33.0",
4
4
  "description": "minijinja (Rust) adapter for BarefootJS — compiles IR to .j2 templates and ships a Rust rendering runtime (packages/adapter-rust/runtime/); runs under any Rust web framework (axum, etc.)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -54,7 +54,7 @@
54
54
  "directory": "packages/adapter-rust"
55
55
  },
56
56
  "dependencies": {
57
- "@barefootjs/shared": "0.31.10"
57
+ "@barefootjs/shared": "0.33.0"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "@barefootjs/jsx": ">=0.2.0",
@@ -71,9 +71,9 @@
71
71
  },
72
72
  "devDependencies": {
73
73
  "@barefootjs/adapter-tests": "0.1.0",
74
- "@barefootjs/jsx": "0.31.10",
75
- "@barefootjs/vite": "0.31.10",
76
- "@barefootjs/client": "0.31.10",
74
+ "@barefootjs/jsx": "0.33.0",
75
+ "@barefootjs/vite": "0.33.0",
76
+ "@barefootjs/client": "0.33.0",
77
77
  "typescript": "^5.0.0",
78
78
  "vite": "^6.0.0"
79
79
  }
@@ -149,9 +149,27 @@ pub fn evaluate(node: &JsonValue, env: &Env) -> JsValue {
149
149
  JsValue::Array(elements)
150
150
  }
151
151
  "object-literal" => {
152
+ // Each entry carries its own "kind" ("prop" | "spread", #2696
153
+ // Step 2) -- the same encoding the Go/Perl/Python/Ruby/PHP
154
+ // evaluators and the raw ParsedExpr shape the eval-vectors.json
155
+ // golden corpus carry. A "spread" evaluates its "expr" and
156
+ // shallow-merges the result's own keys (a non-Object result --
157
+ // including a null/undefined JS spread source -- is a no-op);
158
+ // a "prop" sets one key. Later entries win on a shared key, in
159
+ // source order, matching JS object-spread exactly.
152
160
  let mut out = std::collections::BTreeMap::new();
153
161
  if let Some(props) = node.get("properties").and_then(|v| v.as_array()) {
154
162
  for prop in props {
163
+ let kind = prop.get("kind").and_then(|v| v.as_str()).unwrap_or("");
164
+ if kind == "spread" {
165
+ let spread = evaluate(prop.get("expr").unwrap_or(&JsonValue::Null), env);
166
+ if let JsValue::Object(spread_map) = spread {
167
+ for (k, v) in spread_map {
168
+ out.insert(k, v);
169
+ }
170
+ }
171
+ continue;
172
+ }
155
173
  let key = prop.get("key").and_then(|v| v.as_str()).unwrap_or("").to_string();
156
174
  let value = evaluate(prop.get("value").unwrap_or(&JsonValue::Null), env);
157
175
  out.insert(key, value);
@@ -101,8 +101,11 @@ export interface JinjaMemoContext {
101
101
  /**
102
102
  * Lower a JS expression to its Jinja form (the core recursive entry). See
103
103
  * `JinjaSpreadContext.convertExpressionToJinja` for the `preParsed` contract.
104
+ * `pos` (default `'rendered'`) must be `'value'` for a derived-seed RHS —
105
+ * an assignment, not a render — so the internal support gate matches the
106
+ * `isSupportedValue` classification the seed plan already used.
104
107
  */
105
- convertExpressionToJinja(expr: string, preParsed?: ParsedExpr): string
108
+ convertExpressionToJinja(expr: string, preParsed?: ParsedExpr, pos?: 'rendered' | 'value'): string
106
109
 
107
110
  /**
108
111
  * Per-compile diagnostic list `convertExpressionToJinja` appends to on an
@@ -64,7 +64,7 @@ import { groupBinaryOperand,
64
64
 
65
65
  import type { JinjaEmitContext } from '../emit-context.ts'
66
66
  import { JINJA_TEMPLATE_PRIMITIVES } from '../lib/constants.ts'
67
- import { minijinjaIdent, escapeMinijinjaSingleQuoted } from '../lib/minijinja-naming.ts'
67
+ import { minijinjaIdent, escapeMinijinjaSingleQuoted, minijinjaHashKey, RESERVED_WORDS as MINIJINJA_KWARG_RESERVED } from '../lib/minijinja-naming.ts'
68
68
  import { isBooleanResultParsed } from '../boolean-result.ts'
69
69
  import {
70
70
  renderArrayMethod,
@@ -623,16 +623,44 @@ export class JinjaTopLevelEmitter implements ParsedExprEmitter {
623
623
  return "''"
624
624
  }
625
625
 
626
- objectLiteral(properties: ObjectLiteralProperty[], _raw: string, _emit: (e: ParsedExpr) => string): string {
627
- // The shared `isSupported` gate only ever lets this dispatcher see an
628
- // object literal as the EMPTY (`?? {}`) fallback operand of `??`
629
- // (expression-parser.ts, `logical` case) any other object literal is
630
- // refused before reaching here. Emit minijinja's real empty dict
631
- // literal, matching the `'{}'` convention `objectLiteralToJinjaDict`
632
- // already uses for the zero-property case in the spread path. A
633
- // populated literal is structurally unreachable given the gate, but
634
- // still degrades safely to the pre-existing empty-string sentinel
635
- // rather than silently dropping keys.
636
- return properties.length === 0 ? '{}' : "''"
626
+ objectLiteral(properties: ObjectLiteralProperty[], raw: string, emit: (e: ParsedExpr) => string): string {
627
+ // Reachable here in VALUE position (a `.map()` receiver/callback body, an
628
+ // array-literal element, …) since `isSupportedValue` admits an object
629
+ // literal whose every property value is itself supported
630
+ // (expression-parser.ts, `checkSupport`'s `pos` parameter). Emit a
631
+ // minijinja dict literal, keyed the same way `objectLiteralToJinjaDict`
632
+ // quotes the spread-path literal.
633
+ if (properties.length === 0) return '{}'
634
+ if (!properties.some(p => p.kind === 'spread')) {
635
+ return `{${properties.map(p => (p.kind === 'prop' ? `${minijinjaHashKey(p.key)}: ${emit(p.value)}` : '')).join(', ')}}`
636
+ }
637
+ // Spread (`{ ...t, editing: false }`, #2696 Step 2). minijinja's builtin
638
+ // `dict(value, **kwargs)` (functions.rs) merges kwargs OVER a base value
639
+ // — `None`/undefined bases to an empty map (JS's null/undefined-spread
640
+ // no-op, for free) — but minijinja has NO `**expr` unpack at call sites
641
+ // (`**` lexes only as the power operator), so the override side must be
642
+ // STATIC named kwargs. That expresses exactly ONE shape faithfully: a
643
+ // single spread FIRST, followed only by plain `prop` entries whose keys
644
+ // are valid bareword identifiers (a reserved word can't be a kwarg name
645
+ // either) — the todo-app motivating shape. Any other arrangement (a
646
+ // spread not first, two spreads, or a non-identifier prop key sharing an
647
+ // object with a spread) has no minijinja spelling — self-report BF101
648
+ // rather than silently dropping the unmergeable keys.
649
+ const [first, ...rest] = properties
650
+ const kwargSafe = (p: Extract<ObjectLiteralProperty, { kind: 'prop' }>) =>
651
+ p.keyKind !== 'numeric' && /^[A-Za-z_][A-Za-z0-9_]*$/.test(p.key) && !MINIJINJA_KWARG_RESERVED.has(p.key)
652
+ const shapeOk =
653
+ first.kind === 'spread' &&
654
+ rest.every(p => p.kind === 'prop' && kwargSafe(p))
655
+ if (!shapeOk) {
656
+ this.ctx._recordExprBF101(
657
+ `Object-literal spread '${raw}' isn't expressible in minijinja — a spread must be the FIRST entry, followed only by plain properties with bareword-identifier keys (minijinja's 'dict(value, **kwargs)' has no '**expr' unpack for a dynamic override)`,
658
+ `Reorder so the spread comes first with only simple identifier keys after it, or precompute the merged object and move this position to a '/* @client */' boundary.`,
659
+ )
660
+ return "''"
661
+ }
662
+ const kwargs = (rest as Extract<ObjectLiteralProperty, { kind: 'prop' }>[]).map(p => `${p.key}=${emit(p.value)}`)
663
+ const base = emit(first.expr)
664
+ return kwargs.length === 0 ? `dict(${base})` : `dict(${base}, ${kwargs.join(', ')})`
637
665
  }
638
666
  }
@@ -65,7 +65,7 @@ export function minijinjaHashKey(name: string): string {
65
65
  * truth, IDENTICAL to adapter-jinja's set; the Rust runtime's
66
66
  * `mangle_ident` mirrors this exact set.
67
67
  */
68
- const RESERVED_WORDS = new Set([
68
+ export const RESERVED_WORDS = new Set([
69
69
  'if', 'else', 'for', 'in', 'is', 'not', 'and', 'or', 'none', 'true', 'false',
70
70
  'import', 'from', 'class', 'def', 'pass', 'del', 'return', 'lambda', 'global',
71
71
  'with', 'as', 'raise', 'try', 'except', 'finally', 'while', 'break',
@@ -123,7 +123,8 @@ export function generateDerivedMemoSeed(ctx: JinjaMemoContext, ir: ComponentIR):
123
123
  if (step.kind !== 'derived') continue
124
124
  const materialized = materializeGetterCalls(step.parsed, knownGetterNames)
125
125
  const errorsBefore = ctx.errors.length
126
- const jinja = ctx.convertExpressionToJinja('', materialized)
126
+ // `'value'` this RHS is an assignment, not a render (#2696 review).
127
+ const jinja = ctx.convertExpressionToJinja('', materialized, 'value')
127
128
  if (ctx.errors.length > errorsBefore) {
128
129
  ctx.errors.length = errorsBefore
129
130
  continue
@@ -149,6 +149,7 @@ import {
149
149
  parseProviderObjectLiteral,
150
150
  parseStyleObjectEntries,
151
151
  isSupported,
152
+ isSupportedValue,
152
153
  emitParsedExpr,
153
154
  emitIRNode,
154
155
  emitAttrValue,
@@ -1789,12 +1790,12 @@ export class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitter<Jinja
1789
1790
  /** Build the narrow context the extracted memo seeding depends on. */
1790
1791
  private get memoCtx(): JinjaMemoContext {
1791
1792
  return {
1792
- convertExpressionToJinja: (e, preParsed) => this.convertExpressionToJinja(e, preParsed),
1793
+ convertExpressionToJinja: (e, preParsed, pos) => this.convertExpressionToJinja(e, preParsed, pos),
1793
1794
  errors: this.errors,
1794
1795
  }
1795
1796
  }
1796
1797
 
1797
- private convertExpressionToJinja(expr: string, preParsed?: ParsedExpr): string {
1798
+ private convertExpressionToJinja(expr: string, preParsed?: ParsedExpr, pos: 'rendered' | 'value' = 'rendered'): string {
1798
1799
  // Parse-first lowering — parity with the Xslate adapter's
1799
1800
  // `convertExpressionToKolon`. Parse the JS expression once, gate it on the
1800
1801
  // shared `isSupported`, and render every supported shape through the AST
@@ -1846,7 +1847,11 @@ export class MinijinjaAdapter extends BaseAdapter implements IRNodeEmitter<Jinja
1846
1847
  }
1847
1848
  }
1848
1849
 
1849
- const support = isSupported(parsed)
1850
+ // `pos` distinguishes a derived-seed RHS (an assignment, checked via
1851
+ // `isSupportedValue`) from every other, genuinely rendered call site —
1852
+ // the rendered gate would otherwise re-refuse a tree the seed plan
1853
+ // already classified `derived` at value position (#2696 review).
1854
+ const support = pos === 'value' ? isSupportedValue(parsed) : isSupported(parsed)
1850
1855
  if (!support.supported) {
1851
1856
  this.errors.push({
1852
1857
  code: 'BF101',
@@ -82,6 +82,10 @@ export function objectLiteralToJinjaDict(
82
82
  ): string | null {
83
83
  const entries: string[] = []
84
84
  for (const prop of obj.properties) {
85
+ // A spread (`{ ...t }`, #2696 Step 2) isn't a per-key entry this
86
+ // conditional-spread inline lowering can express — bail, same as any
87
+ // other unsupported shape (the caller falls back to the generic path).
88
+ if (prop.kind === 'spread') return null
85
89
  // Shorthand `{ a }` was a `ShorthandPropertyAssignment` (not a
86
90
  // `PropertyAssignment`), so the former parser rejected it — keep refusing.
87
91
  if (prop.shorthand) return null
@@ -11,5 +11,10 @@
11
11
 
12
12
  import type { RenderDivergences } from '@barefootjs/jsx'
13
13
 
14
- export const renderDivergences: RenderDivergences = {
15
- }
14
+ // #2696 graduated: `todo-app` / `todo-app-ssr` seeded `todos` opaque
15
+ // because their `.map(t => ({ ...t, editing: false }))` callback body's
16
+ // object-literal SPREAD refused (`checkSupport`). Step 2 admits a spread
17
+ // at value position and the runtime evaluator's `object-literal` case
18
+ // now merges it, so the seed classifies `derived` and SSRs identically
19
+ // to Hono.
20
+ export const renderDivergences: RenderDivergences = {}
@@ -28,7 +28,7 @@
28
28
  * that closes that gap.
29
29
  */
30
30
 
31
- import { compileJSX, extractSsrDefaults, deriveStashFromDefaults, importsSearchParams, evaluateSignalInit } from '@barefootjs/jsx'
31
+ import { compileJSX, extractSsrDefaults, deriveStashFromDefaults, importsSearchParams } from '@barefootjs/jsx'
32
32
  import type { ComponentIR, SsrDefault } from '@barefootjs/jsx'
33
33
  import { mkdir, rm } from 'node:fs/promises'
34
34
  import { resolve } from 'node:path'
@@ -501,30 +501,22 @@ function buildVars(
501
501
  }
502
502
  }
503
503
 
504
- // Signal values evaluated from props (after user props).
504
+ // No initializer re-evaluation against raw props production's
505
+ // before_render seeds only from `deriveStashFromDefaults` (#2696).
505
506
  for (const signal of ir.metadata.signals) {
506
507
  // Env signals (#2057) are bound below via `search_params`, not from a
507
508
  // static initial value.
508
509
  if (signal.envReader) continue
509
- // #2669: a self-derivation collision already got the correct RAW-prop
510
- // seed above via `derivedProps` — `extractSsrDefaults` marks that with
511
- // a `propName`-carrying entry (see its docstring's invariant). Skip
512
- // re-seeding here or this harness's own `evaluateSignalInit` recompute
513
- // clobbers the correctly-derived caller value.
514
- if (rootSsrDefaults[signal.getter]?.propName !== undefined) continue
515
- const value = evaluateSignalInit(signal.initialValue.trim(), props)
516
- if (value !== null) {
517
- vars[signal.getter] = value
510
+ if (Object.prototype.hasOwnProperty.call(derivedProps, signal.getter)) {
511
+ vars[signal.getter] = derivedProps[signal.getter]
518
512
  }
519
513
  }
520
514
 
521
- // Memo values seeded from the statically-evaluated ssrDefaults, same
522
- // as the production plugin's before_render hook.
515
+ // No `?? 0` for entries the manifest lacks — production seeds nothing there (#2696).
523
516
  for (const memo of ir.metadata.memos) {
524
- // #2669: same self-derivation skip as the signal loop above.
525
- if (rootSsrDefaults[memo.name]?.propName !== undefined) continue
526
- const entry = rootSsrDefaults[memo.name]
527
- vars[memo.name] = entry ? (entry.value ?? 0) : 0
517
+ if (Object.prototype.hasOwnProperty.call(derivedProps, memo.name)) {
518
+ vars[memo.name] = derivedProps[memo.name]
519
+ }
528
520
  }
529
521
 
530
522
  return vars