@barefootjs/xslate 0.17.0 → 0.18.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.
@@ -52,6 +52,16 @@ export declare function renderPredicateEval(funcName: string, recv: string, pred
52
52
  * projection is outside the evaluator surface (→ caller refuses with BF101).
53
53
  */
54
54
  export declare function renderFlatMapEval(recv: string, body: ParsedExpr, param: string, emit: (e: ParsedExpr) => string): string | null;
55
+ /**
56
+ * Emit a value-producing `.map(cb)` via the runtime evaluator (#2073): the
57
+ * projection body serializes to JSON and `$bf.map_eval` projects each element,
58
+ * one result per element (no flatten — the JS `.map` contract). Composes
59
+ * through the array-method chain (`.map(cb).join(' ')`). Returns null when
60
+ * the projection is outside the evaluator surface (→ caller refuses with
61
+ * BF101). The JSX-returning `.map` is an IRLoop upstream and never reaches
62
+ * this emit.
63
+ */
64
+ export declare function renderMapEval(recv: string, body: ParsedExpr, param: string, emit: (e: ParsedExpr) => string): string | null;
55
65
  /**
56
66
  * Shared Kolon emit for `.sort(cmp)` / `.toSorted(cmp)`. Used by both the
57
67
  * filter-context emitter and the top-level emitter, plus the loop-array
@@ -59,5 +69,7 @@ export declare function renderFlatMapEval(recv: string, body: ParsedExpr, param:
59
69
  * returns a fresh array ref.
60
70
  */
61
71
  export declare function renderSortMethod(recv: string, c: SortComparator): string;
62
- export declare function renderFlatMethod(recv: string, depth: FlatDepth): string;
72
+ export declare function renderFlatMethod(recv: string, depth: FlatDepth | {
73
+ expr: ParsedExpr;
74
+ }, emit: (e: ParsedExpr) => string): string;
63
75
  //# sourceMappingURL=array-method.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-method.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/array-method.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACV,MAAM,iBAAiB,CAAA;AAExB,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CA4HR;AA6BD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAUf;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAkBf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,EAC/B,OAAO,CAAC,EAAE,OAAO,GAChB,MAAM,GAAG,IAAI,CAMf;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,MAAM,CASxE;AAGD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAGvE"}
1
+ {"version":3,"file":"array-method.d.ts","sourceRoot":"","sources":["../../../src/adapter/expr/array-method.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACV,MAAM,iBAAiB,CAAA;AAExB,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAAE,EAClB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CA4HR;AA6BD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAUf;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,GAAG,OAAO,EAC3B,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAkBf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,EAC/B,OAAO,CAAC,EAAE,OAAO,GAChB,MAAM,GAAG,IAAI,CAMf;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,GAAG,IAAI,CAKf;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,GAAG,MAAM,CASxE;AAGD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,EACvC,IAAI,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAC9B,MAAM,CAoBR"}
@@ -18,18 +18,17 @@ import type { XslateEmitContext } from '../emit-context.ts';
18
18
  * filters. Higher-order predicates are emitted using Kolon's own scalar
19
19
  * comparison operators (which delegate to Perl semantics).
20
20
  *
21
- * NOTE: Kolon has no `grep { } @{...}` form, so nested higher-order chains
22
- * (`x.tags.filter(...).length`) inside a predicate route through the
23
- * top-level emitter's `$bf`-helper higher-order lowering. This emitter keeps
24
- * the scalar-comparison surface the predicates the adapter accepts actually
25
- * use; richer nested shapes fall back to the helper or surface as BF101 via
26
- * the top-level emitter.
21
+ * NOTE: Kolon has no `grep { } @{...}` form, so a nested higher-order call
22
+ * (`x.tags.filter(...)`, `other.some(...)`) inside a predicate has no faithful
23
+ * scalar lowering here. Such predicates surface BF101 via `onUnsupported`
24
+ * (#2038) instead of silently degrading to the callback's receiver.
27
25
  */
28
26
  export declare class XslateFilterEmitter implements ParsedExprEmitter {
29
27
  private readonly param;
30
28
  private readonly localVarMap;
31
29
  private readonly isStringName;
32
- constructor(param: string, localVarMap: Map<string, string>, isStringName?: (n: string) => boolean);
30
+ private readonly onUnsupported?;
31
+ constructor(param: string, localVarMap: Map<string, string>, isStringName?: (n: string) => boolean, onUnsupported?: ((message: string, reason?: string) => void) | undefined);
33
32
  identifier(name: string): string;
34
33
  literal(value: string | number | boolean | null, literalType: LiteralType): string;
35
34
  member(object: ParsedExpr, property: string, _computed: boolean, emit: (e: ParsedExpr) => string): string;
@@ -43,7 +42,9 @@ export declare class XslateFilterEmitter implements ParsedExprEmitter {
43
42
  }>, _restArgs: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
44
43
  arrayLiteral(elements: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
45
44
  arrayMethod(method: ArrayMethod, object: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
46
- flatMethod(object: ParsedExpr, depth: FlatDepth, emit: (e: ParsedExpr) => string): string;
45
+ flatMethod(object: ParsedExpr, depth: FlatDepth | {
46
+ expr: ParsedExpr;
47
+ }, emit: (e: ParsedExpr) => string): string;
47
48
  conditional(_test: ParsedExpr, _consequent: ParsedExpr, _alternate: ParsedExpr): string;
48
49
  templateLiteral(_parts: TemplatePart[]): string;
49
50
  arrow(_params: string[], _body: ParsedExpr): string;
@@ -86,12 +87,14 @@ export declare class XslateTopLevelEmitter implements ParsedExprEmitter {
86
87
  private _emitPredicateCallback;
87
88
  arrayLiteral(elements: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
88
89
  arrayMethod(method: ArrayMethod, object: ParsedExpr, args: ParsedExpr[], emit: (e: ParsedExpr) => string): string;
89
- flatMethod(object: ParsedExpr, depth: FlatDepth, emit: (e: ParsedExpr) => string): string;
90
+ flatMethod(object: ParsedExpr, depth: FlatDepth | {
91
+ expr: ParsedExpr;
92
+ }, emit: (e: ParsedExpr) => string): string;
90
93
  conditional(test: ParsedExpr, consequent: ParsedExpr, alternate: ParsedExpr, emit: (e: ParsedExpr) => string): string;
91
94
  templateLiteral(parts: TemplatePart[], emit: (e: ParsedExpr) => string): string;
92
95
  arrow(_params: string[], _body: ParsedExpr): string;
93
96
  regex(_raw: string): string;
94
97
  unsupported(_raw: string, _reason: string): string;
95
- objectLiteral(_properties: ObjectLiteralProperty[], _raw: string, _emit: (e: ParsedExpr) => string): string;
98
+ objectLiteral(properties: ObjectLiteralProperty[], _raw: string, _emit: (e: ParsedExpr) => string): string;
96
99
  }
97
100
  //# 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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"}
@@ -187291,23 +187291,24 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
187291
187291
  import {
187292
187292
  BaseAdapter,
187293
187293
  isBooleanAttr,
187294
- parseExpression as parseExpression3,
187294
+ parseExpression as parseExpression2,
187295
187295
  stringifyParsedExpr as stringifyParsedExpr2,
187296
187296
  exprToString,
187297
187297
  parseProviderObjectLiteral,
187298
187298
  parseStyleObjectEntries,
187299
- isSupported as isSupported2,
187299
+ isSupported,
187300
187300
  emitParsedExpr,
187301
187301
  emitIRNode,
187302
187302
  emitAttrValue,
187303
187303
  augmentInheritedPropAccesses,
187304
187304
  collectModuleStringConsts,
187305
- isLowerableObjectRestDestructure,
187306
187305
  lookupStaticRecordLiteral,
187307
187306
  searchParamsLocalNames,
187308
187307
  prepareLoweringMatchers,
187309
187308
  queryHrefArgs,
187310
- sortComparatorFromArrow as sortComparatorFromArrow2
187309
+ isValidHelperId,
187310
+ sortComparatorFromArrow as sortComparatorFromArrow2,
187311
+ isLowerableLoopDestructure
187311
187312
  } from "@barefootjs/jsx";
187312
187313
 
187313
187314
  // src/adapter/boolean-result.ts
@@ -187417,13 +187418,6 @@ function collectRootScopeNodes(node) {
187417
187418
  visit(node);
187418
187419
  return out;
187419
187420
  }
187420
- function referencedVarsAreAvailable(expr, available) {
187421
- for (const m of expr.matchAll(/\$([A-Za-z_]\w*)/g)) {
187422
- if (!available.has(m[1]))
187423
- return false;
187424
- }
187425
- return true;
187426
- }
187427
187421
 
187428
187422
  // src/adapter/expr/array-method.ts
187429
187423
  import {
@@ -187593,6 +187587,13 @@ function renderFlatMapEval(recv, body, param, emit) {
187593
187587
  const env = emitEvalEnvArg(body, [param], emit);
187594
187588
  return `$bf.flat_map_eval(${recv}, '${escapePerlSingleQuote(json)}', '${param}', ${env})`;
187595
187589
  }
187590
+ function renderMapEval(recv, body, param, emit) {
187591
+ const json = serializeParsedExpr(body);
187592
+ if (json === null)
187593
+ return null;
187594
+ const env = emitEvalEnvArg(body, [param], emit);
187595
+ return `$bf.map_eval(${recv}, '${escapePerlSingleQuote(json)}', '${param}', ${env})`;
187596
+ }
187596
187597
  function renderSortMethod(recv, c) {
187597
187598
  const keyHashes = c.keys.map((k) => {
187598
187599
  const keyEntry = k.key.kind === "self" ? `key_kind => 'self'` : `key_kind => 'field', key => '${k.key.field}'`;
@@ -187600,7 +187601,10 @@ function renderSortMethod(recv, c) {
187600
187601
  });
187601
187602
  return `$bf.sort(${recv}, { keys => [${keyHashes.join(", ")}] })`;
187602
187603
  }
187603
- function renderFlatMethod(recv, depth) {
187604
+ function renderFlatMethod(recv, depth, emit) {
187605
+ if (typeof depth === "object") {
187606
+ return `$bf.flat_dynamic(${recv}, ${emit(depth.expr)})`;
187607
+ }
187604
187608
  const d = depth === "infinity" ? -1 : depth;
187605
187609
  return `$bf.flat(${recv}, ${d})`;
187606
187610
  }
@@ -187625,10 +187629,12 @@ class XslateFilterEmitter {
187625
187629
  param;
187626
187630
  localVarMap;
187627
187631
  isStringName;
187628
- constructor(param, localVarMap, isStringName = () => false) {
187632
+ onUnsupported;
187633
+ constructor(param, localVarMap, isStringName = () => false, onUnsupported) {
187629
187634
  this.param = param;
187630
187635
  this.localVarMap = localVarMap;
187631
187636
  this.isStringName = isStringName;
187637
+ this.onUnsupported = onUnsupported;
187632
187638
  }
187633
187639
  identifier(name) {
187634
187640
  if (name === this.param)
@@ -187699,6 +187705,7 @@ class XslateFilterEmitter {
187699
187705
  return `(${l} // ${r})`;
187700
187706
  }
187701
187707
  callbackMethod(method, object, _arrow, _restArgs, emit) {
187708
+ this.onUnsupported?.(`Filter predicate contains a nested '.${method}(...)' callback, which has no Kolon scalar form`, `Rewrite the predicate without a nested callback method, or add /* @client */ for client-only evaluation (no SSR).`);
187702
187709
  return emit(object);
187703
187710
  }
187704
187711
  arrayLiteral(elements, emit) {
@@ -187708,7 +187715,7 @@ class XslateFilterEmitter {
187708
187715
  return renderArrayMethod(method, object, args, emit);
187709
187716
  }
187710
187717
  flatMethod(object, depth, emit) {
187711
- return renderFlatMethod(emit(object), depth);
187718
+ return renderFlatMethod(emit(object), depth, emit);
187712
187719
  }
187713
187720
  conditional(_test, _consequent, _alternate) {
187714
187721
  return "1";
@@ -187859,6 +187866,13 @@ class XslateTopLevelEmitter {
187859
187866
  this.ctx._recordExprBF101(`'.flatMap(...)' projection is outside the Xslate adapter's evaluable surface`, `Pre-compute the projected array, or move this position to a '/* @client */' boundary.`);
187860
187867
  return "''";
187861
187868
  }
187869
+ if (method === "map") {
187870
+ const evalForm = renderMapEval(recv, body, params[0], emit);
187871
+ if (evalForm !== null)
187872
+ return evalForm;
187873
+ this.ctx._recordExprBF101(`'.map(...)' projection is outside the Xslate adapter's evaluable surface`, `Pre-compute the projected array, or move this position to a '/* @client */' boundary.`);
187874
+ return "''";
187875
+ }
187862
187876
  return recv;
187863
187877
  }
187864
187878
  _emitPredicateCallback(call, arrayExpr, emit) {
@@ -187901,7 +187915,7 @@ class XslateTopLevelEmitter {
187901
187915
  return renderArrayMethod(method, object, args, emit);
187902
187916
  }
187903
187917
  flatMethod(object, depth, emit) {
187904
- return renderFlatMethod(emit(object), depth);
187918
+ return renderFlatMethod(emit(object), depth, emit);
187905
187919
  }
187906
187920
  conditional(test, consequent, alternate, emit) {
187907
187921
  return `(${emit(test)} ? ${emit(consequent)} : ${emit(alternate)})`;
@@ -187932,8 +187946,8 @@ class XslateTopLevelEmitter {
187932
187946
  unsupported(_raw, _reason) {
187933
187947
  return "''";
187934
187948
  }
187935
- objectLiteral(_properties, _raw, _emit) {
187936
- return "''";
187949
+ objectLiteral(properties, _raw, _emit) {
187950
+ return properties.length === 0 ? "{}" : "''";
187937
187951
  }
187938
187952
  }
187939
187953
 
@@ -188092,9 +188106,7 @@ function recordIndexAccessToKolon(ctx, val) {
188092
188106
  // src/adapter/memo/seed.ts
188093
188107
  import {
188094
188108
  collectContextConsumers,
188095
- extractArrowBodyExpression,
188096
- isSupported,
188097
- parseExpression as parseExpression2
188109
+ computeSsrSeedPlan
188098
188110
  } from "@barefootjs/jsx";
188099
188111
  function contextDefaultKolon(c) {
188100
188112
  const d = c.defaultValue;
@@ -188115,44 +188127,22 @@ function generateContextConsumerSeed(ir) {
188115
188127
  `;
188116
188128
  }
188117
188129
  function generateDerivedMemoSeed(ctx, ir) {
188118
- const memos = ir.metadata.memos ?? [];
188119
- const signals = ir.metadata.signals ?? [];
188120
- if (memos.length === 0 && signals.length === 0)
188121
- return "";
188122
- const available = new Set(ir.metadata.propsParams.map((p) => p.name));
188130
+ const plan = ir.metadata.ssrSeedPlan ?? computeSsrSeedPlan(ir.metadata);
188123
188131
  const lines = [];
188124
- for (const signal of signals) {
188125
- const kolon = tryLowerToKolon(ctx, signal.initialValue, available);
188126
- const refsSelf = kolon !== null && new RegExp(`\\$${signal.getter}\\b`).test(kolon);
188127
- if (kolon !== null && !refsSelf)
188128
- lines.push(`: my $${signal.getter} = ${kolon};`);
188129
- available.add(signal.getter);
188130
- }
188131
- for (const memo of memos) {
188132
- const body = extractArrowBodyExpression(memo.computation);
188133
- if (body !== null) {
188134
- const kolon = tryLowerToKolon(ctx, body, available);
188135
- const refsSelf = kolon !== null && new RegExp(`\\$${memo.name}\\b`).test(kolon);
188136
- if (kolon !== null && !refsSelf)
188137
- lines.push(`: my $${memo.name} = ${kolon};`);
188138
- }
188139
- available.add(memo.name);
188132
+ for (const step of plan.steps) {
188133
+ if (step.kind !== "derived")
188134
+ continue;
188135
+ const kolon = ctx.convertExpressionToKolon(step.expr, step.parsed);
188136
+ if (kolon === "" || !/\$[A-Za-z_]\w*/.test(kolon))
188137
+ continue;
188138
+ if (new RegExp(`\\$${step.name}\\b`).test(kolon))
188139
+ continue;
188140
+ lines.push(`: my $${step.name} = ${kolon};`);
188140
188141
  }
188141
188142
  return lines.length > 0 ? lines.join(`
188142
188143
  `) + `
188143
188144
  ` : "";
188144
188145
  }
188145
- function tryLowerToKolon(ctx, expr, available) {
188146
- const trimmed = expr.trim();
188147
- if (!trimmed)
188148
- return null;
188149
- if (!isSupported(parseExpression2(trimmed)).supported)
188150
- return null;
188151
- const kolon = ctx.convertExpressionToKolon(trimmed);
188152
- if (kolon === "" || !/\$[A-Za-z_]\w*/.test(kolon))
188153
- return null;
188154
- return referencedVarsAreAvailable(kolon, available) ? kolon : null;
188155
- }
188156
188146
 
188157
188147
  // src/adapter/value/parsed-literal.ts
188158
188148
  import { evalStringArrayJoin } from "@barefootjs/jsx";
@@ -188188,6 +188178,17 @@ function collectStringValueNames(ir) {
188188
188178
  }
188189
188179
 
188190
188180
  // src/adapter/xslate-adapter.ts
188181
+ function kolonSegmentAccessor(base, segments) {
188182
+ let expr = base;
188183
+ for (const seg of segments) {
188184
+ expr += seg.kind === "field" ? seg.isIdent ? `.${seg.key}` : `[${kolonHashKey(seg.key)}]` : `[${seg.index}]`;
188185
+ }
188186
+ return expr;
188187
+ }
188188
+ function kolonStringLiteral(s) {
188189
+ return `'${escapeKolonSingleQuoted(s)}'`;
188190
+ }
188191
+
188191
188192
  class XslateAdapter extends BaseAdapter {
188192
188193
  name = "xslate";
188193
188194
  extension = ".tx";
@@ -188452,24 +188453,41 @@ ${whenTrue}
188452
188453
  return `<: $bf.comment("cond-start:${condId}") | mark_raw :>${content}<: $bf.comment("cond-end:${condId}") | mark_raw :>`;
188453
188454
  }
188454
188455
  renderLoop(loop) {
188455
- if (loop.clientOnly)
188456
- return "";
188456
+ if (loop.clientOnly) {
188457
+ return `<: $bf.comment("loop:${loop.markerId}") | mark_raw :><: $bf.comment("/loop:${loop.markerId}") | mark_raw :>`;
188458
+ }
188457
188459
  const destructure = !!(loop.paramBindings && loop.paramBindings.length > 0);
188458
- const supportableDestructure = destructure && isLowerableObjectRestDestructure(loop);
188460
+ const supportableDestructure = destructure && isLowerableLoopDestructure(loop);
188459
188461
  if (destructure && !supportableDestructure) {
188460
188462
  this.errors.push({
188461
188463
  code: "BF104",
188462
188464
  severity: "error",
188463
- message: `Loop callback uses an array/object destructure pattern (\`${loop.param}\`) that the Xslate adapter cannot lower — Kolon \`for LIST -> $item\` binds a single scalar and can't unpack a tuple.`,
188465
+ message: `Loop callback uses a destructure pattern (\`${loop.param}\`) that the Xslate adapter cannot lower — see the diagnostic detail for the specific shape.`,
188464
188466
  loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
188465
188467
  suggestion: {
188466
188468
  message: `Options:
188467
- ` + ` 1. Rename the parameter to a single name and access tuple elements with index syntax in the body (e.g. \`entry => entry[0]\` instead of \`([k, v]) => ...\`).
188468
- ` + ` 2. Mark the loop position as @client-only so the destructure runs in JS on the client.
188469
- ` + ` 3. Move the loop into a primitive that the adapter registers explicitly.`
188469
+ ` + ` 1. If this is an object-rest binding (\`{ ...rest }\`), only reading \`rest.field\` or spreading \`{...rest}\` onto an intrinsic element lowers — other uses (passing \`rest\` to a function, rendering it as text) need the client runtime.
188470
+ ` + ` 2. If this is chained \`.filter().map(({ ... }) => ...)\`, hoist the destructure into a variable inside the callback body instead.
188471
+ ` + ` 3. Mark the loop position as @client-only so the destructure runs in JS on the client.
188472
+ ` + ` 4. Move the loop into a primitive that the adapter registers explicitly.`
188470
188473
  }
188471
188474
  });
188472
188475
  }
188476
+ const arrayName = loop.array.trim();
188477
+ if (/^[A-Za-z_$][\w$]*$/.test(arrayName)) {
188478
+ const arrayConst = (this.localConstants ?? []).find((c) => c.name === arrayName);
188479
+ if (arrayConst && !arrayConst.isModule && this._resolveLiteralConst(arrayName) === null) {
188480
+ this.errors.push({
188481
+ code: "BF101",
188482
+ severity: "error",
188483
+ message: `Loop array \`${arrayName}\` is a local computed value (\`${arrayConst.value}\`) that the Xslate adapter cannot bind as a template variable — only numeric/string-literal locals inline at their use site.`,
188484
+ loc: loop.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
188485
+ suggestion: {
188486
+ message: "Pre-compute the array server-side and pass it as a prop, or mark the loop position as @client-only so it runs in JS on the client."
188487
+ }
188488
+ });
188489
+ }
188490
+ }
188473
188491
  const rawArray = this.convertExpressionToKolon(loop.array);
188474
188492
  let array = rawArray;
188475
188493
  if (loop.sortComparator) {
@@ -188491,7 +188509,15 @@ ${whenTrue}
188491
188509
  }
188492
188510
  if (supportableDestructure) {
188493
188511
  for (const b of loop.paramBindings ?? []) {
188494
- indexLocalLines.push(b.rest ? `: my $${b.name} = $${loopVar};` : `: my $${b.name} = $${loopVar}${b.path};`);
188512
+ const parent = kolonSegmentAccessor(`$${loopVar}`, b.segments ?? []);
188513
+ if (b.rest?.kind === "object") {
188514
+ const exclude = b.rest.exclude.map((k) => kolonStringLiteral(k.key)).join(", ");
188515
+ indexLocalLines.push(`: my $${b.name} = $bf.omit(${parent}, [${exclude}]);`);
188516
+ } else if (b.rest?.kind === "array") {
188517
+ indexLocalLines.push(`: my $${b.name} = $bf.slice(${parent}, ${b.rest.from}, nil);`);
188518
+ } else {
188519
+ indexLocalLines.push(`: my $${b.name} = ${kolonSegmentAccessor(`$${loopVar}`, b.segments ?? [])};`);
188520
+ }
188495
188521
  }
188496
188522
  }
188497
188523
  const prevInLoop = this.inLoop;
@@ -188547,8 +188573,32 @@ ${childrenUnderLoop}` : childrenUnderLoop;
188547
188573
  emitBooleanShorthand: (_value, name) => `${kolonHashKey(name)} => 1`,
188548
188574
  emitJsxChildren: () => ""
188549
188575
  };
188576
+ componentPropSegmentEntries(segments) {
188577
+ const last = segments[segments.length - 1];
188578
+ if (last && last.kind === "entries")
188579
+ return last.parts;
188580
+ const seg = { kind: "entries", parts: [] };
188581
+ segments.push(seg);
188582
+ return seg.parts;
188583
+ }
188584
+ combineComponentPropSegments(segments) {
188585
+ let acc = null;
188586
+ for (const seg of segments) {
188587
+ if (seg.kind === "entries") {
188588
+ if (seg.parts.length === 0)
188589
+ continue;
188590
+ const text = `{ ${seg.parts.join(", ")} }`;
188591
+ acc = acc === null ? text : `${acc}.merge(${text})`;
188592
+ } else {
188593
+ const text = `(${seg.expr} // {})`;
188594
+ acc = acc === null ? text : `${acc}.merge(${text})`;
188595
+ }
188596
+ }
188597
+ return acc ?? "{}";
188598
+ }
188550
188599
  renderComponent(comp) {
188551
- const propParts = [];
188600
+ const segments = [{ kind: "entries", parts: [] }];
188601
+ const currentEntries = () => this.componentPropSegmentEntries(segments);
188552
188602
  for (const p of comp.props) {
188553
188603
  if ((p.name.match(/^on[A-Z]/) || p.name === "ref") && p.value.kind === "expression")
188554
188604
  continue;
@@ -188556,27 +188606,19 @@ ${childrenUnderLoop}` : childrenUnderLoop;
188556
188606
  const trimmed = p.value.expr.trim();
188557
188607
  if (this.propsObjectName && this.propsObjectName === trimmed) {
188558
188608
  for (const pp of this.propsParams) {
188559
- propParts.push(`${pp.name} => $${pp.name}`);
188609
+ currentEntries().push(`${pp.name} => $${pp.name}`);
188560
188610
  }
188561
188611
  continue;
188562
188612
  }
188563
- this.errors.push({
188564
- code: "BF101",
188565
- severity: "error",
188566
- message: `Spread props (\`{...${trimmed}}\`) on a child component cannot be lowered to Kolon — Kolon hashref method args can't splat a runtime hash into named entries.`,
188567
- loc: comp.loc ?? { file: this.componentName + ".tsx", start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
188568
- suggestion: {
188569
- message: "Pass the child component its props explicitly rather than spreading a runtime object."
188570
- }
188571
- });
188613
+ segments.push({ kind: "spread", expr: this.convertExpressionToKolon(p.value.expr) });
188572
188614
  continue;
188573
188615
  }
188574
188616
  const lowered = emitAttrValue(p.value, this.componentPropEmitter, p.name);
188575
188617
  if (lowered)
188576
- propParts.push(lowered);
188618
+ currentEntries().push(lowered);
188577
188619
  }
188578
188620
  if (comp.slotId && !this.inLoop) {
188579
- propParts.push(`_bf_slot => '${comp.slotId}'`);
188621
+ currentEntries().push(`_bf_slot => '${comp.slotId}'`);
188580
188622
  }
188581
188623
  const tplName = this.toTemplateName(comp.name);
188582
188624
  const effectiveChildren = comp.children.length > 0 ? comp.children : resolveJsxChildrenProp(comp.props);
@@ -188586,11 +188628,12 @@ ${childrenUnderLoop}` : childrenUnderLoop;
188586
188628
  const childrenBody = this.renderChildren(effectiveChildren);
188587
188629
  this.inLoop = prevInLoop;
188588
188630
  const macroName = `bf_children_${comp.slotId ?? "c" + this.childrenCaptureCounter++}`;
188589
- const childrenEntry = `children => ${macroName}()`;
188590
- const allParts = [...propParts, childrenEntry];
188591
- return `<: macro ${macroName} -> () { :>${childrenBody}<: } :><: $bf.render_child('${tplName}', { ${allParts.join(", ")} }) | mark_raw :>`;
188631
+ currentEntries().push(`children => ${macroName}()`);
188632
+ const dict = this.combineComponentPropSegments(segments);
188633
+ return `<: macro ${macroName} -> () { :>${childrenBody}<: } :><: $bf.render_child('${tplName}', ${dict}) | mark_raw :>`;
188592
188634
  }
188593
- const hashEntries = propParts.length > 0 ? `, { ${propParts.join(", ")} }` : "";
188635
+ const isEmpty = segments.every((s) => s.kind === "entries" && s.parts.length === 0);
188636
+ const hashEntries = isEmpty ? "" : `, ${this.combineComponentPropSegments(segments)}`;
188594
188637
  return `<: $bf.render_child('${tplName}'${hashEntries}) | mark_raw :>`;
188595
188638
  }
188596
188639
  childrenCaptureCounter = 0;
@@ -188709,7 +188752,7 @@ ${name}="<: ${val} :>"
188709
188752
  if (localConst?.value !== undefined) {
188710
188753
  const initTrimmed = localConst.value.trim();
188711
188754
  if (!/^[A-Za-z_$][\w$]*$/.test(initTrimmed)) {
188712
- const resolved = conditionalSpreadToKolon(this.spreadCtx, parseExpression3(initTrimmed));
188755
+ const resolved = conditionalSpreadToKolon(this.spreadCtx, parseExpression2(initTrimmed));
188713
188756
  if (resolved !== null) {
188714
188757
  return `<: $bf.spread_attrs(${resolved}) | mark_raw :>`;
188715
188758
  }
@@ -188727,7 +188770,7 @@ ${name}="<: ${val} :>"
188727
188770
  if (!entries)
188728
188771
  return null;
188729
188772
  for (const e of entries) {
188730
- if (e.kind === "expr" && !isSupported2(parseExpression3(e.expr)).supported)
188773
+ if (e.kind === "expr" && !isSupported(parseExpression2(e.expr)).supported)
188731
188774
  return null;
188732
188775
  }
188733
188776
  return entries.map((e) => e.kind === "literal" ? `${this.escapeAttrText(e.cssKey)}:${this.escapeAttrText(e.value)}` : `${this.escapeAttrText(e.cssKey)}:<: ${this.convertExpressionToKolon(e.expr)} :>`).join(";");
@@ -188763,7 +188806,7 @@ ${name}="<: ${val} :>"
188763
188806
  return `${BF_COND}="${condId}"`;
188764
188807
  }
188765
188808
  renderKolonFilterExpr(expr, param, localVarMap = new Map) {
188766
- return emitParsedExpr(expr, new XslateFilterEmitter(param, localVarMap, (n) => this._isStringValueName(n)));
188809
+ return emitParsedExpr(expr, new XslateFilterEmitter(param, localVarMap, (n) => this._isStringValueName(n), (message, reason) => this._recordExprBF101(message, reason)));
188767
188810
  }
188768
188811
  convertTemplateLiteralPartsToKolon(literalParts) {
188769
188812
  const parts = [];
@@ -188808,8 +188851,8 @@ ${name}="<: ${val} :>"
188808
188851
  const hasTaggedTemplate = /[A-Za-z_$][\w$]*\s*`/.test(probe);
188809
188852
  if (!startsAsObjectLiteral && !hasTaggedTemplate)
188810
188853
  return false;
188811
- const parsed = parseExpression3(expr.trim());
188812
- const support = isSupported2(parsed);
188854
+ const parsed = parseExpression2(expr.trim());
188855
+ const support = isSupported(parsed);
188813
188856
  if (parsed.kind !== "unsupported" && support.supported)
188814
188857
  return false;
188815
188858
  const reason = support.reason ?? (parsed.kind === "unsupported" ? parsed.reason : undefined);
@@ -188856,7 +188899,7 @@ ${reason}` : "";
188856
188899
  const trimmed = expr.trim();
188857
188900
  if (trimmed === "")
188858
188901
  return "''";
188859
- parsed = parseExpression3(trimmed);
188902
+ parsed = parseExpression2(trimmed);
188860
188903
  }
188861
188904
  if (parsed.kind === "call") {
188862
188905
  for (const matcher of this._loweringMatchers) {
@@ -188865,9 +188908,13 @@ ${reason}` : "";
188865
188908
  const qArgs = queryHrefArgs(node, (n) => this.renderParsedExprToKolon(n));
188866
188909
  return `$bf.query(${qArgs.join(", ")})`;
188867
188910
  }
188911
+ if (node?.kind === "helper-call" && isValidHelperId(node.helper)) {
188912
+ const argsX = node.args.map((a) => this.renderParsedExprToKolon(a));
188913
+ return `$bf.${node.helper}(${argsX.join(", ")})`;
188914
+ }
188868
188915
  }
188869
188916
  }
188870
- const support = isSupported2(parsed);
188917
+ const support = isSupported(parsed);
188871
188918
  if (!support.supported) {
188872
188919
  this.errors.push({
188873
188920
  code: "BF101",
@@ -188895,7 +188942,7 @@ Options:
188895
188942
  return this.stringValueNames.has(name);
188896
188943
  }
188897
188944
  parseUndefinedAlternateTernary(expr) {
188898
- const parsed = parseExpression3(expr.trim());
188945
+ const parsed = parseExpression2(expr.trim());
188899
188946
  if (parsed?.kind !== "conditional")
188900
188947
  return null;
188901
188948
  const alt = parsed.alternate;
@@ -26,9 +26,4 @@ export declare function resolveJsxChildrenProp(props: readonly IRProp[]): IRNode
26
26
  * runtime. (#1297)
27
27
  */
28
28
  export declare function collectRootScopeNodes(node: IRNode): Set<IRNode>;
29
- /**
30
- * True when every `$var` the lowered Kolon expression references is already in
31
- * scope — guards in-template memo seeding against an out-of-scope binding. (#1297)
32
- */
33
- export declare function referencedVarsAreAvailable(expr: string, available: ReadonlySet<string>): boolean;
34
29
  //# sourceMappingURL=ir-scope.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ir-scope.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/ir-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAA6B,MAAM,iBAAiB,CAAA;AAEhF;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAKzE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAiB/D;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAKhG"}
1
+ {"version":3,"file":"ir-scope.d.ts","sourceRoot":"","sources":["../../../src/adapter/lib/ir-scope.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAA6B,MAAM,iBAAiB,CAAA;AAEhF;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAKzE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAiB/D"}
@@ -19,20 +19,20 @@ export declare function contextDefaultKolon(c: ContextConsumer): string;
19
19
  */
20
20
  export declare function generateContextConsumerSeed(ir: ComponentIR): string;
21
21
  /**
22
- * Seed memos whose SSR default is `null` (not statically evaluable) by
23
- * computing them in-template from the already-seeded prop / signal vars
24
- * (`createMemo(() => props.value * 10)` → `: my $x = $value * 10;`). Without
25
- * this the memo's `$x` renders empty the reason
26
- * `props-reactivity-comparison` was skipped. Only emitted when every var the
27
- * lowering references is already in scope. (#1297)
22
+ * Emit `: my $<name> = <kolon>;` line-statements for every `derived` step of
23
+ * the backend-neutral SSR seed plan the scope/availability/ordering
24
+ * analysis lives in `computeSsrSeedPlan` (packages/jsx/src/ssr-seed-plan.ts);
25
+ * this only lowers each step's expression to Kolon and applies the
26
+ * backend-specific emit guards: skip an empty lowering, skip a lowering that
27
+ * references no `$var` at all (a constant init/body — e.g. a `derived` step
28
+ * with empty `frees` — keeps the existing static ssr-defaults seed instead),
29
+ * and skip a self-referencing lowering (Kolon's `my` shadows the RHS, so
30
+ * `: my $x = … $x …` would read the just-declared undefined lexical rather
31
+ * than the render var — the plan rules out SOURCE-level self-refs, but a
32
+ * lowered canonical name could still collide, so this stays as the cheap
33
+ * defense it always was). `env-reader` and `opaque` steps emit nothing (the
34
+ * runtime supplies the reader, or the adapter's ssr-defaults path already
35
+ * covers it). (#1297, #2075)
28
36
  */
29
37
  export declare function generateDerivedMemoSeed(ctx: XslateMemoContext, ir: ComponentIR): string;
30
- /**
31
- * Lower a signal init / memo body to Kolon for an in-template SSR seed, or
32
- * `null` when it shouldn't be seeded this way: not a supported shape
33
- * (`isSupported` pre-check, so object/array literals don't fail the build),
34
- * references no in-scope var (a constant — keep ssr-defaults seeding), or
35
- * references an out-of-scope binding. (#1297)
36
- */
37
- export declare function tryLowerToKolon(ctx: XslateMemoContext, expr: string, available: ReadonlySet<string>): string | null;
38
38
  //# sourceMappingURL=seed.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../../src/adapter/memo/seed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,EAKrB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAG3D,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAM9D;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAWnE;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,iBAAiB,EAAE,EAAE,EAAE,WAAW,GAAG,MAAM,CA8CvF;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,iBAAiB,EACtB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,GAC7B,MAAM,GAAG,IAAI,CAOf"}
1
+ {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../../src/adapter/memo/seed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,EAGrB,MAAM,iBAAiB,CAAA;AAExB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAE3D,sEAAsE;AACtE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAM9D;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,EAAE,WAAW,GAAG,MAAM,CAWnE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,iBAAiB,EAAE,EAAE,EAAE,WAAW,GAAG,MAAM,CAcvF"}