nudojs 1.3.11 → 1.3.13

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 +1262 -728
  2. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -21662,12 +21662,16 @@ function nullishGuardOf(test) {
21662
21662
  if (t?.type === "UnaryExpression" && t.operator === "!") {
21663
21663
  const m = memberGuardTarget(t.argument);
21664
21664
  if (m) return { name: m.name, arm: "alt", grain: "nullish", memberKey: m.key };
21665
+ const a = assignGuardTarget(t.argument);
21666
+ if (a) return { name: a, arm: "alt", grain: "nullish" };
21665
21667
  }
21666
21668
  if (t?.type === "Identifier" && t.name) {
21667
21669
  return { name: t.name, arm: "cons", grain: "nullish" };
21668
21670
  }
21669
21671
  const bare = memberGuardTarget(t);
21670
21672
  if (bare) return { name: bare.name, arm: "cons", grain: "nullish", memberKey: bare.key };
21673
+ const bareAssign = assignGuardTarget(t);
21674
+ if (bareAssign) return { name: bareAssign, arm: "cons", grain: "nullish" };
21671
21675
  if (t?.type !== "BinaryExpression") return void 0;
21672
21676
  const op = t.operator;
21673
21677
  if (op !== "===" && op !== "!==" && op !== "==" && op !== "!=") return void 0;
@@ -21699,6 +21703,20 @@ function nullishGuardOf(test) {
21699
21703
  const grain = litGrain(l);
21700
21704
  if (grain !== void 0) return { name: r.name, arm: truthyArm, grain };
21701
21705
  }
21706
+ if (op === "==" || op === "!=") {
21707
+ const nullishLit = (n) => {
21708
+ const ln = n;
21709
+ return ln?.type === "NullLiteral" || ln?.name === "undefined";
21710
+ };
21711
+ const lm = memberGuardTarget(t.left);
21712
+ const rm = memberGuardTarget(t.right);
21713
+ if (lm && nullishLit(t.right)) {
21714
+ return { name: lm.name, arm: truthyArm, grain: "nullish", memberKey: lm.key };
21715
+ }
21716
+ if (rm && nullishLit(t.left)) {
21717
+ return { name: rm.name, arm: truthyArm, grain: "nullish", memberKey: rm.key };
21718
+ }
21719
+ }
21702
21720
  return void 0;
21703
21721
  }
21704
21722
  function compositeNullishGuardOf(test) {
@@ -21719,6 +21737,31 @@ function compositeNullishGuardOf(test) {
21719
21737
  }
21720
21738
  return lg ?? rg;
21721
21739
  }
21740
+ function mergeGuardInto(list, g) {
21741
+ const prev = list.find((x) => x.name === g.name);
21742
+ if (!prev) {
21743
+ list.push(g);
21744
+ return;
21745
+ }
21746
+ const grainA = prev.grain ?? "nullish";
21747
+ const grainB = g.grain ?? "nullish";
21748
+ if (grainA !== grainB) prev.grain = "nullish";
21749
+ if (prev.memberKey === void 0 && g.memberKey !== void 0) prev.memberKey = g.memberKey;
21750
+ }
21751
+ function nullishGuardsOf(test) {
21752
+ const t = test;
21753
+ if (t?.type === "LogicalExpression" && (t.operator === "||" || t.operator === "&&")) {
21754
+ const wantArm = t.operator === "||" ? "alt" : "cons";
21755
+ const out = [];
21756
+ for (const g2 of [...nullishGuardsOf(t.left), ...nullishGuardsOf(t.right)]) {
21757
+ if (g2.arm !== wantArm) continue;
21758
+ mergeGuardInto(out, g2);
21759
+ }
21760
+ return out;
21761
+ }
21762
+ const g = nullishGuardOf(test);
21763
+ return g ? [g] : [];
21764
+ }
21722
21765
  function typeGuardOf(test) {
21723
21766
  const t = test;
21724
21767
  if (t?.type !== "BinaryExpression") return void 0;
@@ -21740,11 +21783,15 @@ function nullishRemoveCallOf(guard) {
21740
21783
  if (guard.grain === "null") return `$removeNull(${guard.name})`;
21741
21784
  return `$removeNullish(${guard.name})`;
21742
21785
  }
21743
- function narrowNullishArmThunk(thunk, guard, arm, forkBindingNames) {
21744
- if (!guard || guard.arm !== arm) return thunk;
21786
+ function narrowNullishArmThunks(thunk, guards, arm, forkBindingNames) {
21787
+ if (!guards || guards.length === 0) return thunk;
21788
+ const matching = guards.filter((g) => g.arm === arm);
21789
+ if (matching.length === 0) return thunk;
21745
21790
  const names2 = forkBindingNames instanceof Set ? forkBindingNames : new Set(forkBindingNames);
21746
- if (names2.has(guard.name)) return thunk;
21747
- return `((${guard.name}) => ${thunk})(${nullishRemoveCallOf(guard)})`;
21791
+ if (matching.some((g) => names2.has(g.name))) return thunk;
21792
+ const params = matching.map((g) => g.name).join(", ");
21793
+ const args = matching.map((g) => nullishRemoveCallOf(g)).join(", ");
21794
+ return `((${params}) => ${thunk})(${args})`;
21748
21795
  }
21749
21796
  function narrowTypeArmThunk(thunk, guard, arm, forkBindingNames) {
21750
21797
  if (!guard) return thunk;
@@ -21753,7 +21800,58 @@ function narrowTypeArmThunk(thunk, guard, arm, forkBindingNames) {
21753
21800
  const keep = arm === guard.arm;
21754
21801
  return `((${guard.name}) => ${thunk})($narrowTypeOf(${guard.name}, ${JSON.stringify(guard.typeOf)}, ${keep}))`;
21755
21802
  }
21756
- var TYPEOF_NAMES2, isStrLitNode, typeofArgName, memberGuardTarget;
21803
+ function discriminantGuardOf(test) {
21804
+ const t = test;
21805
+ if (t?.type !== "BinaryExpression") return void 0;
21806
+ if (t.operator !== "===" && t.operator !== "!==") return void 0;
21807
+ const lm = memberGuardTarget(t.left);
21808
+ const rm = memberGuardTarget(t.right);
21809
+ const m = lm !== void 0 && isPrimLitNode(t.right) ? { target: lm, lit: t.right } : rm !== void 0 && isPrimLitNode(t.left) ? { target: rm, lit: t.left } : void 0;
21810
+ if (!m) return void 0;
21811
+ return {
21812
+ name: m.target.name,
21813
+ key: m.target.key,
21814
+ value: m.lit.value,
21815
+ arm: t.operator === "===" ? "cons" : "alt"
21816
+ };
21817
+ }
21818
+ function discriminantGuardsOf(test) {
21819
+ const t = test;
21820
+ if (t?.type === "LogicalExpression" && (t.operator === "&&" || t.operator === "||")) {
21821
+ const wantArm = t.operator === "&&" ? "cons" : "alt";
21822
+ const out = [];
21823
+ for (const g2 of [...discriminantGuardsOf(t.left), ...discriminantGuardsOf(t.right)]) {
21824
+ if (g2.arm !== wantArm) continue;
21825
+ if (out.some((x) => x.name === g2.name && x.key === g2.key && x.value === g2.value)) continue;
21826
+ out.push(g2);
21827
+ }
21828
+ return out;
21829
+ }
21830
+ const g = discriminantGuardOf(test);
21831
+ return g ? [g] : [];
21832
+ }
21833
+ function narrowDiscriminantArmThunks(thunk, guards, arm, forkBindingNames) {
21834
+ if (!guards || guards.length === 0) return thunk;
21835
+ const matching = guards.filter((g) => g.arm === arm);
21836
+ if (matching.length === 0) return thunk;
21837
+ const names2 = forkBindingNames instanceof Set ? forkBindingNames : new Set(forkBindingNames);
21838
+ if (matching.some((g) => names2.has(g.name))) return thunk;
21839
+ const byName = /* @__PURE__ */ new Map();
21840
+ for (const g of matching) {
21841
+ const list = byName.get(g.name) ?? [];
21842
+ if (!list.some((x) => x.key === g.key && x.value === g.value)) list.push(g);
21843
+ byName.set(g.name, list);
21844
+ }
21845
+ const params = [...byName.keys()].join(", ");
21846
+ const args = [...byName.entries()].map(
21847
+ ([name, gs]) => gs.reduce(
21848
+ (acc, g) => `$narrowMemberEq(${acc}, ${JSON.stringify(g.key)}, ${JSON.stringify(g.value)}, true)`,
21849
+ name
21850
+ )
21851
+ ).join(", ");
21852
+ return `((${params}) => ${thunk})(${args})`;
21853
+ }
21854
+ var TYPEOF_NAMES2, isStrLitNode, typeofArgName, memberGuardTarget, assignGuardTarget, isPrimLitNode;
21757
21855
  var init_stmt_predicates = __esm({
21758
21856
  "../core/src/algebra/exec/transpile/stmt-predicates.ts"() {
21759
21857
  "use strict";
@@ -21790,6 +21888,20 @@ var init_stmt_predicates = __esm({
21790
21888
  if (key === void 0) return void 0;
21791
21889
  return { name: m.object.name, key };
21792
21890
  };
21891
+ assignGuardTarget = (n) => {
21892
+ const t = n;
21893
+ if (t?.type === "AssignmentExpression" && t.operator === "=" && t.left?.type === "Identifier" && t.left.name) {
21894
+ return t.left.name;
21895
+ }
21896
+ return void 0;
21897
+ };
21898
+ isPrimLitNode = (n) => {
21899
+ const t = n;
21900
+ if (t?.type === "StringLiteral") return typeof t.value === "string";
21901
+ if (t?.type === "NumericLiteral") return typeof t.value === "number";
21902
+ if (t?.type === "BooleanLiteral") return typeof t.value === "boolean";
21903
+ return false;
21904
+ };
21793
21905
  }
21794
21906
  });
21795
21907
 
@@ -21885,16 +21997,22 @@ function transpileFnBodyStmts(stmtsIn, depth, opts, varScope) {
21885
21997
  };
21886
21998
  const testRecvs = collectArrMutatorReceivers(stmt.test);
21887
21999
  const testRebinds = testRecvs.size ? emitArrMutatorRebinds(stmt.test, scopedOpts, pad) : [];
21888
- const earlyGuard = nullishGuardOf(stmt.test);
22000
+ const earlyGuards = nullishGuardsOf(stmt.test);
21889
22001
  const earlyTGuard = typeGuardOf(stmt.test);
21890
- const consNarrowed = narrowTypeArmThunk(
21891
- narrowNullishArmThunk(
21892
- transpileBlockAsThunk(stmt.consequent, depth, scopedOpts),
21893
- earlyGuard,
22002
+ const earlyDGuards = discriminantGuardsOf(stmt.test);
22003
+ const consNarrowed = narrowDiscriminantArmThunks(
22004
+ narrowTypeArmThunk(
22005
+ narrowNullishArmThunks(
22006
+ transpileBlockAsThunk(stmt.consequent, depth, scopedOpts),
22007
+ earlyGuards,
22008
+ "cons",
22009
+ recvSet
22010
+ ),
22011
+ earlyTGuard,
21894
22012
  "cons",
21895
22013
  recvSet
21896
22014
  ),
21897
- earlyTGuard,
22015
+ earlyDGuards,
21898
22016
  "cons",
21899
22017
  recvSet
21900
22018
  );
@@ -21903,9 +22021,14 @@ function transpileFnBodyStmts(stmtsIn, depth, opts, varScope) {
21903
22021
  const altThunk = `() => {
21904
22022
  ${altBody}
21905
22023
  ${pad}}`;
21906
- const altNarrowed = narrowTypeArmThunk(
21907
- narrowNullishArmThunk(altThunk, earlyGuard, "alt", recvSet),
21908
- earlyTGuard,
22024
+ const altNarrowed = narrowDiscriminantArmThunks(
22025
+ narrowTypeArmThunk(
22026
+ narrowNullishArmThunks(altThunk, earlyGuards, "alt", recvSet),
22027
+ earlyTGuard,
22028
+ "alt",
22029
+ recvSet
22030
+ ),
22031
+ earlyDGuards,
21909
22032
  "alt",
21910
22033
  recvSet
21911
22034
  );
@@ -22234,17 +22357,28 @@ ${pad}export default ${name};`;
22234
22357
  ...opts,
22235
22358
  conditionalFlow: (opts.conditionalFlow ?? 0) + 1
22236
22359
  }) : null;
22237
- const guard = nullishGuardOf(stmt.test);
22360
+ const guards = nullishGuardsOf(stmt.test);
22238
22361
  const tguard = typeGuardOf(stmt.test);
22239
- const consNarrowed = narrowTypeArmThunk(
22240
- narrowNullishArmThunk(consRaw, guard, "cons", recvSet),
22241
- tguard,
22362
+ const dguards = discriminantGuardsOf(stmt.test);
22363
+ const consNarrowed = narrowDiscriminantArmThunks(
22364
+ narrowTypeArmThunk(
22365
+ narrowNullishArmThunks(consRaw, guards, "cons", recvSet),
22366
+ tguard,
22367
+ "cons",
22368
+ recvSet
22369
+ ),
22370
+ dguards,
22242
22371
  "cons",
22243
22372
  recvSet
22244
22373
  );
22245
- const altNarrowed = altRaw === null ? null : narrowTypeArmThunk(
22246
- narrowNullishArmThunk(altRaw, guard, "alt", recvSet),
22247
- tguard,
22374
+ const altNarrowed = altRaw === null ? null : narrowDiscriminantArmThunks(
22375
+ narrowTypeArmThunk(
22376
+ narrowNullishArmThunks(altRaw, guards, "alt", recvSet),
22377
+ tguard,
22378
+ "alt",
22379
+ recvSet
22380
+ ),
22381
+ dguards,
22248
22382
  "alt",
22249
22383
  recvSet
22250
22384
  );
@@ -22691,13 +22825,24 @@ ${indent(depth + 1)}]${dflt})`;
22691
22825
  collectAssignedIds(stmt.test, assigned);
22692
22826
  const bodyLocalDecls = /* @__PURE__ */ new Set();
22693
22827
  collectLoopBodyTopLevelDeclNames(stmt.body, bodyLocalDecls);
22828
+ const bodyWrites = /* @__PURE__ */ new Set();
22829
+ collectAssignedIds(stmt.body, bodyWrites);
22830
+ collectArrMutatorReceivers(stmt.body, bodyWrites);
22831
+ const loopGuards = nullishGuardsOf(stmt.test).filter(
22832
+ (g) => g.arm === "cons" && !bodyWrites.has(g.name) && !bodyLocalDecls.has(g.name)
22833
+ );
22834
+ const bodyNarrowed = loopGuards.length === 0 ? body : [
22835
+ `${indent(depth + 1)}((${loopGuards.map((g) => g.name).join(", ")}) => {`,
22836
+ body,
22837
+ `${indent(depth + 1)}})(${loopGuards.map((g) => nullishRemoveCallOf(g)).join(", ")});`
22838
+ ].join("\n");
22694
22839
  const names2 = [...assigned].filter((n) => !HOST_INTRINSIC_SET.has(n) && !bodyLocalDecls.has(n));
22695
22840
  const loopOpts = opts.loopLabel ? `label: ${JSON.stringify(opts.loopLabel)}` : "";
22696
22841
  if (names2.length === 0) {
22697
22842
  return [
22698
22843
  `${pad}// while \u2192 $whileSeq (bounded, max=${max})`,
22699
22844
  `${pad}$whileSeq(() => ${test}, () => {`,
22700
- body,
22845
+ bodyNarrowed,
22701
22846
  `${pad}}, ${max}${loopOpts ? `, { ${loopOpts} }` : ""});`
22702
22847
  ].join("\n");
22703
22848
  }
@@ -22706,7 +22851,7 @@ ${indent(depth + 1)}]${dflt})`;
22706
22851
  return [
22707
22852
  `${pad}// while \u2192 $whileSeq (instrumented bindings: ${names2.join(", ")})`,
22708
22853
  `${pad}$whileSeq(() => ${test}, () => {`,
22709
- body,
22854
+ bodyNarrowed,
22710
22855
  `${pad}}, ${max}, { pack: () => ${packSrc}, unpack: ${unpackSrc}${loopOpts ? `, ${loopOpts}` : ""} });`
22711
22856
  ].join("\n");
22712
22857
  }
@@ -22725,6 +22870,17 @@ ${indent(depth + 1)}]${dflt})`;
22725
22870
  collectArrMutatorReceivers(stmt.body, assigned);
22726
22871
  const bodyLocalDecls = /* @__PURE__ */ new Set();
22727
22872
  collectLoopBodyTopLevelDeclNames(stmt.body, bodyLocalDecls);
22873
+ const bodyWrites = /* @__PURE__ */ new Set();
22874
+ collectAssignedIds(stmt.body, bodyWrites);
22875
+ collectArrMutatorReceivers(stmt.body, bodyWrites);
22876
+ const loopGuards = nullishGuardsOf(stmt.test).filter(
22877
+ (g) => g.arm === "cons" && !bodyWrites.has(g.name) && !bodyLocalDecls.has(g.name)
22878
+ );
22879
+ const innerBody = loopGuards.length === 0 ? bodyStmts : [
22880
+ `${indent(depth + 1)}((${loopGuards.map((g) => g.name).join(", ")}) => {`,
22881
+ bodyStmts,
22882
+ `${indent(depth + 1)}})(${loopGuards.map((g) => nullishRemoveCallOf(g)).join(", ")});`
22883
+ ].join("\n");
22728
22884
  const names2 = [...assigned].filter((n) => !HOST_INTRINSIC_SET.has(n) && !bodyLocalDecls.has(n));
22729
22885
  const packSrc = names2.length === 0 ? null : `$obj({ ${names2.map((n) => `${JSON.stringify(n)}: $copy(${n})`).join(", ")} })`;
22730
22886
  const unpackSrc = names2.length === 0 ? null : `(__lp) => { ${names2.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }`;
@@ -22735,7 +22891,7 @@ ${indent(depth + 1)}]${dflt})`;
22735
22891
  `{`,
22736
22892
  bodyStmts,
22737
22893
  `${indent(depth + 1)}$whileSeq(() => ${test}, () => {`,
22738
- bodyStmts,
22894
+ innerBody,
22739
22895
  `${indent(depth + 1)}}, ${max}${optsSrc});`,
22740
22896
  `${pad}}`
22741
22897
  ].join("\n");
@@ -23156,27 +23312,42 @@ function transpileShortCircuitExpr(opts, parts) {
23156
23312
  const forkTest2 = parts.testSrc ?? parts.alwaysSrc;
23157
23313
  let consExpr = parts.consSrc === "__test" ? parts.alwaysSrc : parts.consSrc;
23158
23314
  let altExpr = parts.altSrc === "__test" ? parts.alwaysSrc : parts.altSrc;
23159
- if (parts.narrowGuard) {
23160
- if (parts.narrowGuard.arm === "cons") {
23161
- consExpr = `((${parts.narrowGuard.name}) => (${consExpr}))(${nullishRemoveCallOf(parts.narrowGuard)})`;
23162
- } else {
23163
- altExpr = `((${parts.narrowGuard.name}) => (${altExpr}))(${nullishRemoveCallOf(parts.narrowGuard)})`;
23164
- }
23165
- }
23315
+ const applyGuards = (src, arm) => {
23316
+ const gs = (parts.narrowGuards ?? []).filter((g) => g.arm === arm);
23317
+ if (gs.length === 0) return src;
23318
+ const params = gs.map((g) => g.name).join(", ");
23319
+ const args = gs.map((g) => nullishRemoveCallOf(g)).join(", ");
23320
+ return `((${params}) => (${src}))(${args})`;
23321
+ };
23322
+ consExpr = applyGuards(consExpr, "cons");
23323
+ altExpr = applyGuards(altExpr, "alt");
23166
23324
  if (parts.typeGuard) {
23167
23325
  const g = parts.typeGuard;
23168
23326
  const apply = (src, arm) => `((${g.name}) => (${src}))($narrowTypeOf(${g.name}, ${JSON.stringify(g.typeOf)}, ${arm === g.arm}))`;
23169
23327
  consExpr = apply(consExpr, "cons");
23170
23328
  altExpr = apply(altExpr, "alt");
23171
23329
  }
23330
+ const applyDisc = (src, arm) => narrowDiscriminantArmThunks(src, parts.discGuards, arm, []);
23331
+ consExpr = applyDisc(consExpr, "cons");
23332
+ altExpr = applyDisc(altExpr, "alt");
23172
23333
  return `$fork(${forkTest2}, () => ${consExpr}, () => ${altExpr})`;
23173
23334
  }
23174
23335
  const consLines = parts.consSrc === "__test" ? [`return __test;`] : consRebinds.length === 0 ? [`return (${parts.consSrc});`] : [`const __v = (${parts.consSrc});`, ...consRebinds, `return __v;`];
23175
23336
  const altLines = parts.altSrc === "__test" ? [`return __test;`] : altRebinds.length === 0 ? [`return (${parts.altSrc});`] : [`const __v = (${parts.altSrc});`, ...altRebinds, `return __v;`];
23176
23337
  const forkTest = parts.testSrc ?? "__test";
23177
- const guard = parts.narrowGuard;
23178
- const consFinal = narrowNullishArmThunk(forkArmThunk(consLines, "fk1_", names2), guard, "cons", names2);
23179
- const altFinal = narrowNullishArmThunk(forkArmThunk(altLines, "fk2_", names2), guard, "alt", names2);
23338
+ const guards = parts.narrowGuards;
23339
+ const consFinal = narrowDiscriminantArmThunks(
23340
+ narrowNullishArmThunks(forkArmThunk(consLines, "fk1_", names2), guards, "cons", names2),
23341
+ parts.discGuards,
23342
+ "cons",
23343
+ names2
23344
+ );
23345
+ const altFinal = narrowDiscriminantArmThunks(
23346
+ narrowNullishArmThunks(forkArmThunk(altLines, "fk2_", names2), guards, "alt", names2),
23347
+ parts.discGuards,
23348
+ "alt",
23349
+ names2
23350
+ );
23180
23351
  return [
23181
23352
  `(() => {`,
23182
23353
  ` const __test = (${parts.alwaysSrc});`,
@@ -23398,8 +23569,9 @@ ${inner}
23398
23569
  testSrc: `$nullishTest(${l})`
23399
23570
  });
23400
23571
  }
23401
- const andGuard = nullishGuardOf(expr.left);
23572
+ const leftGuards = nullishGuardsOf(expr.left);
23402
23573
  const andTypeGuard = typeGuardOf(expr.left);
23574
+ const leftDiscGuards = discriminantGuardsOf(expr.left);
23403
23575
  return op === "&&" ? transpileShortCircuitExpr(opts, {
23404
23576
  alwaysNodes: [lNode],
23405
23577
  alwaysSrc: l,
@@ -23407,8 +23579,9 @@ ${inner}
23407
23579
  consNodes: [rNode],
23408
23580
  altSrc: "__test",
23409
23581
  altNodes: [],
23410
- narrowGuard: andGuard?.arm === "cons" ? andGuard : void 0,
23411
- typeGuard: andTypeGuard
23582
+ narrowGuards: leftGuards.filter((g) => g.arm === "cons"),
23583
+ typeGuard: andTypeGuard,
23584
+ discGuards: leftDiscGuards.filter((g) => g.arm === "cons")
23412
23585
  }) : transpileShortCircuitExpr(opts, {
23413
23586
  alwaysNodes: [lNode],
23414
23587
  alwaysSrc: l,
@@ -23416,8 +23589,9 @@ ${inner}
23416
23589
  consNodes: [],
23417
23590
  altSrc: r,
23418
23591
  altNodes: [rNode],
23419
- narrowGuard: andGuard?.arm === "alt" ? andGuard : void 0,
23420
- typeGuard: andTypeGuard
23592
+ narrowGuards: leftGuards.filter((g) => g.arm === "alt"),
23593
+ typeGuard: andTypeGuard,
23594
+ discGuards: leftDiscGuards.filter((g) => g.arm === "alt")
23421
23595
  });
23422
23596
  }
23423
23597
  case "ConditionalExpression": {
@@ -23435,9 +23609,12 @@ ${inner}
23435
23609
  altSrc: a,
23436
23610
  altNodes: [altNode],
23437
23611
  // 三元的 nullish/typeof 守卫臂收窄(issue #97:`p === null ? -1 : p.major`;
23438
- // Bug 23:`typeof v === "string" ? v + "!" : 0`)
23439
- narrowGuard: nullishGuardOf(expr.test),
23440
- typeGuard: typeGuardOf(expr.test)
23612
+ // Bug 23:`typeof v === "string" ? v + "!" : 0`;#118 v3/#120:多名复合
23613
+ // `obj == null || node.p == null ? … : node.p.name` 一臂多事实);
23614
+ // 判别等值守卫(issue #126):`node.type === 'TL' ? node.quasis[0] : null`
23615
+ narrowGuards: nullishGuardsOf(expr.test),
23616
+ typeGuard: typeGuardOf(expr.test),
23617
+ discGuards: discriminantGuardsOf(expr.test)
23441
23618
  });
23442
23619
  }
23443
23620
  case "RegExpLiteral": {
@@ -24194,7 +24371,7 @@ function transpileSource(source, opts = {}) {
24194
24371
  return transpileFile(file, { ...opts, source: opts.source ?? source });
24195
24372
  }
24196
24373
  function runtimeImportOf(runtime) {
24197
- return `import { $absVal, $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $objAccessorKey, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $invokeSuperObj, $invokeSuperKey, $getSuper, $getSuperObj, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $iterCheck, $catchVal, $switch, $staticInvoke, $setKey, $gen, $newTarget, $staticInit, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $removeNullish, $removeNull, $removeUndefined, $removeMemberNullish, $narrowTypeOf, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo, $yieldStar, $tpl } from ${JSON.stringify(runtime)};`;
24374
+ return `import { $absVal, $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $objAccessorKey, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $invokeSuperObj, $invokeSuperKey, $getSuper, $getSuperObj, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $iterCheck, $catchVal, $switch, $staticInvoke, $setKey, $gen, $newTarget, $staticInit, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $removeNullish, $removeNull, $removeUndefined, $removeMemberNullish, $narrowMemberEq, $narrowTypeOf, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo, $yieldStar, $tpl } from ${JSON.stringify(runtime)};`;
24198
24375
  }
24199
24376
  function transpileFile(file, opts = {}) {
24200
24377
  const runtime = opts.runtimeImport ?? "@nudojs/core/exec";
@@ -24215,7 +24392,7 @@ function transpileFile(file, opts = {}) {
24215
24392
  };
24216
24393
  const lines = [
24217
24394
  `// nudo evaluator transpile \u2014 values are Abs; operators are overloaded calls`,
24218
- `import { $absVal, $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $objAccessorKey, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $invokeSuperObj, $invokeSuperKey, $getSuper, $getSuperObj, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $iterCheck, $catchVal, $switch, $staticInvoke, $setKey, $gen, $newTarget, $staticInit, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $removeNullish, $removeNull, $removeUndefined, $removeMemberNullish, $narrowTypeOf, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo, $yieldStar, $tpl } from ${JSON.stringify(runtime)};`,
24395
+ `import { $absVal, $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $objAccessorKey, $neg, $typeof, $not, $eq, $ne, $eqLoose, $neLoose, $lt, $le, $gt, $ge, $join, $lit, $fork, $for, $forIter, $obj, $get, $set, $setProto, $while, $whileSeq, $arr, $arrWithHoles, $arrMutContainer, $idx, $idxSet, $len, $call, $throw, $loopReturn, $loopBreak, $loopContinue, $class, $new, $invoke, $invokeSuper, $invokeSuperObj, $invokeSuperKey, $getSuper, $getSuperObj, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $iterCheck, $catchVal, $switch, $staticInvoke, $setKey, $gen, $newTarget, $staticInit, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $removeNullish, $removeNull, $removeUndefined, $removeMemberNullish, $narrowMemberEq, $narrowTypeOf, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo, $yieldStar, $tpl } from ${JSON.stringify(runtime)};`,
24219
24396
  ``
24220
24397
  ];
24221
24398
  if (varHoistLine) lines.push(varHoistLine);
@@ -25685,6 +25862,8 @@ function $copy(a) {
25685
25862
  open: s.open
25686
25863
  });
25687
25864
  next.conf = a.conf;
25865
+ next.term = a.term;
25866
+ next.pred = a.pred;
25688
25867
  migrateAccessors(a, next);
25689
25868
  migrateInvariants(a, next);
25690
25869
  migrateNullProto(a, next);
@@ -28243,6 +28422,58 @@ function $narrowTypeOf(a, typeOf2, keep) {
28243
28422
  if (kept.length === 0) return a;
28244
28423
  return kept.length === 1 ? kept[0] : { ...a, shape: { k: "sum", members: kept } };
28245
28424
  }
28425
+ function litRefutesEq(other, v2) {
28426
+ return other !== v2;
28427
+ }
28428
+ function memberEqClass(m, key, litAbs, value) {
28429
+ const sh = m.shape;
28430
+ if (sh.k === "obj") {
28431
+ const slots = sh.slots;
28432
+ if (!Object.prototype.hasOwnProperty.call(slots, key)) {
28433
+ return sh.open ? "may" : "never";
28434
+ }
28435
+ const slotValue = slots[key].value;
28436
+ if (slotValue.shape.k === "any" || slotValue.shape.k === "unknown") return "may";
28437
+ const shapeOnly = (s) => abs(s, void 0, void 0, "exact");
28438
+ if (!leqAbs(shapeOnly(litAbs.shape), shapeOnly(slotValue.shape)).ok) return "never";
28439
+ const t = slotValue.term;
28440
+ const p = slotValue.pred;
28441
+ if (!t || !p || p.op === "true") return "may";
28442
+ const litTerm = lit(value);
28443
+ if (implies(p, { op: "eq", a: t, b: litTerm })) return "only";
28444
+ if (implies(p, { op: "ne", a: t, b: litTerm })) return "never";
28445
+ const conjuncts = [];
28446
+ const visit2 = (c) => {
28447
+ if (c.op === "and") {
28448
+ c.args.forEach(visit2);
28449
+ return;
28450
+ }
28451
+ conjuncts.push(c);
28452
+ };
28453
+ visit2(p);
28454
+ for (const c of conjuncts) {
28455
+ if (c.op !== "eq") continue;
28456
+ const other = termEquals(c.a, t) && c.b.op === "lit" ? c.b.value : termEquals(c.b, t) && c.a.op === "lit" ? c.a.value : void 0;
28457
+ if (other !== void 0 && litRefutesEq(other, value)) return "never";
28458
+ }
28459
+ return "may";
28460
+ }
28461
+ if (m.term?.op === "lit") return "never";
28462
+ return "may";
28463
+ }
28464
+ function $narrowMemberEq(a, key, value, keep) {
28465
+ if (!a || typeof a !== "object" || !("shape" in a)) return a;
28466
+ if (a.shape.k !== "sum") return a;
28467
+ const litAbs = typeof value === "string" ? strLit(value) : typeof value === "number" ? numLit(value) : boolLit(value);
28468
+ const members = a.shape.members;
28469
+ const kept = members.filter((m) => {
28470
+ const c = memberEqClass(m, key, litAbs, value);
28471
+ return keep ? c !== "never" : c !== "only";
28472
+ });
28473
+ if (kept.length === members.length) return a;
28474
+ if (kept.length === 0) return a;
28475
+ return kept.length === 1 ? kept[0] : { ...a, shape: { k: "sum", members: kept } };
28476
+ }
28246
28477
  function primShapeOfTypeOf(typeOf2) {
28247
28478
  switch (typeOf2) {
28248
28479
  case "string":
@@ -28267,7 +28498,10 @@ var init_async = __esm({
28267
28498
  "../core/src/algebra/exec/runtime/async.ts"() {
28268
28499
  "use strict";
28269
28500
  init_abs();
28501
+ init_term();
28502
+ init_pred();
28270
28503
  init_objects();
28504
+ init_leq();
28271
28505
  init_abs_fn();
28272
28506
  init_surface();
28273
28507
  init_state();
@@ -28337,6 +28571,7 @@ __export(runtime_exports, {
28337
28571
  $lt: () => $lt,
28338
28572
  $mod: () => $mod,
28339
28573
  $mul: () => $mul,
28574
+ $narrowMemberEq: () => $narrowMemberEq,
28340
28575
  $narrowTypeOf: () => $narrowTypeOf,
28341
28576
  $ne: () => $ne,
28342
28577
  $neLoose: () => $neLoose,
@@ -28489,6 +28724,800 @@ var init_lru_map = __esm({
28489
28724
  }
28490
28725
  });
28491
28726
 
28727
+ // ../core/src/algebra/constraint.ts
28728
+ function selfTerm() {
28729
+ return v(SELF);
28730
+ }
28731
+ function getTerm(obj2, key) {
28732
+ return app("get", [obj2, lit(key)]);
28733
+ }
28734
+ function lenTerm(t) {
28735
+ return app("length", [t]);
28736
+ }
28737
+ function isConstraint(x) {
28738
+ return !!x && typeof x === "object" && x.__nudoConstraint === true;
28739
+ }
28740
+ function isNudoConstraint(x) {
28741
+ return isConstraint(x);
28742
+ }
28743
+ function isIntFlag(c) {
28744
+ return c.int === true || intFlaggedBuilders.has(c);
28745
+ }
28746
+ function makeBuilder(prim2, preds, extra) {
28747
+ const fields = extra?.fields;
28748
+ const element = extra?.element;
28749
+ const isInt = extra?.int;
28750
+ const optional = extra?.optional;
28751
+ const members = extra?.members;
28752
+ const fnSlot = extra?.fn;
28753
+ const lazySlot = extra?.lazy;
28754
+ const base = {
28755
+ __nudoConstraint: true,
28756
+ ...prim2 ? { prim: prim2 } : {},
28757
+ preds: [...preds],
28758
+ ...fields ? { fields } : {},
28759
+ ...element ? { element } : {},
28760
+ ...optional ? { isOptional: true } : {},
28761
+ ...members ? { members } : {},
28762
+ ...fnSlot ? { fn: fnSlot } : {},
28763
+ ...lazySlot ? { lazy: lazySlot } : {}
28764
+ };
28765
+ const add2 = (p) => makeBuilder(prim2, [...preds, p], extra);
28766
+ const builder = Object.assign(
28767
+ /* @__PURE__ */ Object.create(null),
28768
+ base,
28769
+ {
28770
+ gt: (n) => add2(gt(selfTerm(), lit(n))),
28771
+ ge: (n) => add2(ge(selfTerm(), lit(n))),
28772
+ lt: (n) => add2(lt(selfTerm(), lit(n))),
28773
+ le: (n) => add2(le(selfTerm(), lit(n))),
28774
+ int: () => makeBuilder(prim2 ?? "number", preds, { ...extra, int: true }),
28775
+ min: (n) => add2(ge(lenTerm(selfTerm()), lit(n))),
28776
+ max: (n) => add2(le(lenTerm(selfTerm()), lit(n))),
28777
+ length: (n) => add2(and(ge(lenTerm(selfTerm()), lit(n)), le(lenTerm(selfTerm()), lit(n)))),
28778
+ shift: (n) => {
28779
+ if (!Number.isFinite(n))
28780
+ throw new Error("nudo shift(): offset must be a finite number");
28781
+ if (fields || element || members || fnSlot || lazySlot)
28782
+ throw new Error("nudo shift(): only numeric scalar constraint chains are allowed (shape/array/union/fn are not supported)");
28783
+ if (prim2 !== void 0 && prim2 !== "number")
28784
+ throw new Error(`nudo shift(): only numeric chains are allowed (prim=${prim2})`);
28785
+ return makeBuilder(prim2, shiftBoundPreds(preds, n), extra);
28786
+ },
28787
+ optional: () => makeBuilder(prim2, preds, { ...extra, optional: true })
28788
+ }
28789
+ );
28790
+ if (isInt) intFlaggedBuilders.add(builder);
28791
+ return builder;
28792
+ }
28793
+ function shiftBoundPreds(preds, n) {
28794
+ return preds.map((p) => {
28795
+ if (p.op !== "gt" && p.op !== "ge" && p.op !== "lt" && p.op !== "le")
28796
+ throw new Error(`nudo shift(): predicate ${p.op} is not supported (only gt/ge/lt/le constant bounds)`);
28797
+ const { a, b } = p;
28798
+ if (b.op !== "lit" || typeof b.value !== "number")
28799
+ throw new Error("nudo shift(): the right-hand side of a constant bound must be a numeric literal");
28800
+ if (termHasApp(a, "length") || termHasApp(b, "length"))
28801
+ throw new Error("nudo shift(): length(...) bounds are not supported");
28802
+ return { op: p.op, a, b: lit(b.value + n) };
28803
+ });
28804
+ }
28805
+ function termHasApp(t, fn2) {
28806
+ if (t.op !== "app") return false;
28807
+ if (t.fn === fn2) return true;
28808
+ return t.args.some((x) => termHasApp(x, fn2));
28809
+ }
28810
+ function number() {
28811
+ return makeBuilder("number", []);
28812
+ }
28813
+ function string() {
28814
+ return makeBuilder("string", []);
28815
+ }
28816
+ function boolean() {
28817
+ return makeBuilder("boolean", []);
28818
+ }
28819
+ function any() {
28820
+ return makeBuilder(void 0, []);
28821
+ }
28822
+ function array(item) {
28823
+ return makeBuilder(void 0, [], {
28824
+ element: asNestedConstraint(item, "array(item)")
28825
+ });
28826
+ }
28827
+ function shape(fields) {
28828
+ const mapped = {};
28829
+ for (const [k, v2] of Object.entries(fields)) {
28830
+ const constraint = asNestedConstraint(v2, `shape \u5B57\u6BB5 '${k}'`);
28831
+ mapped[k] = {
28832
+ constraint,
28833
+ ...constraint.isOptional ? { optional: true } : {}
28834
+ };
28835
+ }
28836
+ return makeBuilder(void 0, [], { fields: mapped });
28837
+ }
28838
+ function toPlainConstraint(c) {
28839
+ if (!isConstraint(c))
28840
+ throw new Error("nudo: expected a constraint value (number()/string()/\u2026 or a combinator)");
28841
+ return {
28842
+ __nudoConstraint: true,
28843
+ ...c.prim ? { prim: c.prim } : {},
28844
+ preds: [...c.preds],
28845
+ ...c.fields ? { fields: c.fields } : {},
28846
+ ...c.element ? { element: c.element } : {},
28847
+ // isIntFlag 统一读取:builder(int 是方法)查 WeakSet,纯数据看 === true
28848
+ ...isIntFlag(c) ? { int: true } : {},
28849
+ ...c.isOptional ? { isOptional: true } : {},
28850
+ ...c.members ? { members: c.members } : {},
28851
+ ...c.fn ? { fn: c.fn } : {},
28852
+ ...c.lazy ? { lazy: c.lazy } : {}
28853
+ };
28854
+ }
28855
+ function litC(v2) {
28856
+ const prim2 = typeof v2 === "number" ? "number" : typeof v2 === "string" ? "string" : typeof v2 === "boolean" ? "boolean" : void 0;
28857
+ return makeBuilder(prim2, [eq(selfTerm(), lit(v2))]);
28858
+ }
28859
+ function asNestedConstraint(x, ctx2) {
28860
+ if (isConstraint(x)) return toPlainConstraint(x);
28861
+ if (x === null || x === void 0 || typeof x === "number" || typeof x === "string" || typeof x === "boolean") {
28862
+ return toPlainConstraint(litC(x));
28863
+ }
28864
+ throw new Error(
28865
+ `nudo: ${ctx2} expects a constraint value (number()/string()/\u2026) or a concrete literal; received a non-constraint`
28866
+ );
28867
+ }
28868
+ function union(...cs) {
28869
+ if (cs.length === 0)
28870
+ throw new Error("nudo union(): at least one member constraint is required");
28871
+ return makeBuilder(void 0, [], {
28872
+ members: cs.map((c) => asNestedConstraint(c, "union member"))
28873
+ });
28874
+ }
28875
+ function nullable(c) {
28876
+ return makeBuilder(void 0, [], {
28877
+ members: [
28878
+ asNestedConstraint(c, "nullable()"),
28879
+ toPlainConstraint(litC(null)),
28880
+ toPlainConstraint(litC(void 0))
28881
+ ]
28882
+ });
28883
+ }
28884
+ function lazy(thunk) {
28885
+ if (typeof thunk !== "function")
28886
+ throw new Error("nudo lazy(): expects a thunk function () => constraint");
28887
+ return makeBuilder(void 0, [], { lazy: thunk });
28888
+ }
28889
+ function derefConstraint(c) {
28890
+ const thunk = c.lazy;
28891
+ if (!thunk) return c;
28892
+ const memoized = lazyDerefMemo.get(thunk);
28893
+ if (memoized) return memoized;
28894
+ const out = thunk();
28895
+ if (!isConstraint(out))
28896
+ throw new Error(
28897
+ "nudo lazy(): the thunk must return a constraint (number()/string()/shape()/\u2026)"
28898
+ );
28899
+ const normalized = toPlainConstraint(out);
28900
+ lazyDerefMemo.set(thunk, normalized);
28901
+ return normalized;
28902
+ }
28903
+ function constraintAdmitsNullish(c, seen) {
28904
+ if (c.lazy) {
28905
+ const s = seen ?? /* @__PURE__ */ new Set();
28906
+ if (s.has(c.lazy)) return false;
28907
+ s.add(c.lazy);
28908
+ return constraintAdmitsNullish(derefConstraint(c), s);
28909
+ }
28910
+ if (c.members)
28911
+ return c.members.some((m) => constraintAdmitsNullish(m, seen));
28912
+ if (!c.prim && c.preds.length === 0 && !c.fields && !c.element && !c.fn) return true;
28913
+ for (const p of c.preds) {
28914
+ for (const flat of p.op === "and" ? p.args : [p]) {
28915
+ if (flat.op !== "eq") continue;
28916
+ for (const side of [flat.a, flat.b]) {
28917
+ if (side.op === "lit" && (side.value === null || side.value === void 0)) return true;
28918
+ }
28919
+ }
28920
+ }
28921
+ return false;
28922
+ }
28923
+ function fn(params, returns, opts) {
28924
+ const normalized = {};
28925
+ for (const [k, v2] of Object.entries(params)) {
28926
+ normalized[k] = asNestedConstraint(v2, `fn param '${k}'`);
28927
+ }
28928
+ return makeBuilder(void 0, [], {
28929
+ fn: {
28930
+ params: normalized,
28931
+ ...returns !== void 0 ? { returns: asNestedConstraint(returns, "fn return value") } : {},
28932
+ ...opts?.throws !== void 0 ? { throws: asNestedConstraint(opts.throws, "fn throws") } : {}
28933
+ }
28934
+ });
28935
+ }
28936
+ function andC(...cs) {
28937
+ if (cs.length === 0)
28938
+ throw new Error("nudo and(): at least one constraint is required");
28939
+ let prim2;
28940
+ let isInt = false;
28941
+ let allOptional = true;
28942
+ const preds = [];
28943
+ for (const c0 of cs) {
28944
+ if (!isConstraint(c0))
28945
+ throw new Error("nudo: expected a constraint value (number()/string()/\u2026 or a combinator)");
28946
+ const c = derefConstraint(c0);
28947
+ if (c.fields || c.element || c.members || c.fn)
28948
+ throw new Error("nudo and(): Phase 1 supports scalar constraint conjunction only (shape/array/union/fn are not supported)");
28949
+ if (c.prim) {
28950
+ if (prim2 !== void 0 && prim2 !== c.prim)
28951
+ throw new Error(`nudo and(): inconsistent prim (${prim2} vs ${c.prim})`);
28952
+ prim2 = c.prim;
28953
+ }
28954
+ preds.push(...c.preds);
28955
+ if (isIntFlag(c)) isInt = true;
28956
+ if (!c.isOptional) allOptional = false;
28957
+ }
28958
+ return makeBuilder(prim2, preds, {
28959
+ ...isInt ? { int: true } : {},
28960
+ ...allOptional ? { optional: true } : {}
28961
+ });
28962
+ }
28963
+ function partial(c) {
28964
+ if (!isConstraint(c))
28965
+ throw new Error("nudo partial(): only shape(...) constraints are accepted");
28966
+ const d = derefConstraint(c);
28967
+ if (!d.fields)
28968
+ throw new Error("nudo partial(): only shape(...) constraints are accepted");
28969
+ const fields = {};
28970
+ for (const [k, f] of Object.entries(d.fields)) {
28971
+ fields[k] = {
28972
+ constraint: { ...toPlainConstraint(f.constraint), isOptional: true },
28973
+ optional: true
28974
+ };
28975
+ }
28976
+ return makeBuilder(d.prim, d.preds, { fields });
28977
+ }
28978
+ function pick(c, keys) {
28979
+ if (!isConstraint(c))
28980
+ throw new Error("nudo pick(): only shape(...) constraints are accepted");
28981
+ const d = derefConstraint(c);
28982
+ if (!d.fields)
28983
+ throw new Error("nudo pick(): only shape(...) constraints are accepted");
28984
+ const fields = {};
28985
+ for (const k of keys) {
28986
+ const f = d.fields[k];
28987
+ if (f) fields[k] = f;
28988
+ }
28989
+ return makeBuilder(d.prim, d.preds, { fields });
28990
+ }
28991
+ function omit(c, keys) {
28992
+ if (!isConstraint(c))
28993
+ throw new Error("nudo omit(): only shape(...) constraints are accepted");
28994
+ const d = derefConstraint(c);
28995
+ if (!d.fields)
28996
+ throw new Error("nudo omit(): only shape(...) constraints are accepted");
28997
+ const drop = new Set(keys);
28998
+ const fields = {};
28999
+ for (const [k, f] of Object.entries(d.fields)) {
29000
+ if (!drop.has(k)) fields[k] = f;
29001
+ }
29002
+ return makeBuilder(d.prim, d.preds, { fields });
29003
+ }
29004
+ function substTerm(t, paramName2) {
29005
+ if (t.op === "var" && t.id === SELF) return v(paramName2);
29006
+ if (t.op === "app" && t.fn === "get" && t.args.length === 2) {
29007
+ return getTerm(substTerm(t.args[0], paramName2), String(
29008
+ t.args[1].op === "lit" ? t.args[1].value : ""
29009
+ ));
29010
+ }
29011
+ return t;
29012
+ }
29013
+ function substPred2(p, paramName2) {
29014
+ switch (p.op) {
29015
+ case "gt":
29016
+ case "ge":
29017
+ case "lt":
29018
+ case "le":
29019
+ case "eq":
29020
+ case "ne": {
29021
+ return { op: p.op, a: substTerm(p.a, paramName2), b: substTerm(p.b, paramName2) };
29022
+ }
29023
+ case "typeof": {
29024
+ return { op: "typeof", t: substTerm(p.t, paramName2), type: p.type };
29025
+ }
29026
+ case "and":
29027
+ return and(...p.args.map((x) => substPred2(x, paramName2)));
29028
+ default:
29029
+ return p;
29030
+ }
29031
+ }
29032
+ function instantiateConstraint(c, paramName2, depth = LAZY_TEMPLATE_DEPTH) {
29033
+ if (c.lazy) {
29034
+ if (depth <= 0) return pTrue;
29035
+ return instantiateConstraint(derefConstraint(c), paramName2, depth - 1);
29036
+ }
29037
+ if (c.fields) {
29038
+ const parts = [];
29039
+ for (const [key, field] of Object.entries(c.fields)) {
29040
+ if (field.optional || field.constraint.isOptional) continue;
29041
+ const fieldTerm = getTerm(v(paramName2), key);
29042
+ parts.push(instantiateOnTerm(field.constraint, fieldTerm, depth));
29043
+ }
29044
+ if (c.prim) parts.push(ptypeof(v(paramName2), primToTypeof(c.prim)));
29045
+ if (parts.length === 0) return { op: "true" };
29046
+ return parts.length === 1 ? parts[0] : and(...parts);
29047
+ }
29048
+ if (c.members) {
29049
+ const disj = or(
29050
+ ...c.members.map((m) => instantiateOnTerm(m, v(paramName2), depth))
29051
+ );
29052
+ const own = c.preds.map((p) => substPred2(p, paramName2));
29053
+ return own.length === 0 ? disj : and(...own, disj);
29054
+ }
29055
+ if (c.fn) {
29056
+ const own = c.preds.map((p) => substPred2(p, paramName2));
29057
+ return own.length === 0 ? pTrue : and(...own);
29058
+ }
29059
+ const preds = c.preds.map((p) => substPred2(p, paramName2));
29060
+ if (c.prim && c.preds.length === 0) {
29061
+ return ptypeof(v(paramName2), primToTypeof(c.prim));
29062
+ }
29063
+ return preds.length === 0 ? { op: "true" } : preds.length === 1 ? preds[0] : and(...preds);
29064
+ }
29065
+ function instantiateOnTerm(c, t, depth = LAZY_TEMPLATE_DEPTH) {
29066
+ if (c.lazy) {
29067
+ if (depth <= 0) return pTrue;
29068
+ return instantiateOnTerm(derefConstraint(c), t, depth - 1);
29069
+ }
29070
+ const subst = (p) => {
29071
+ switch (p.op) {
29072
+ case "gt":
29073
+ case "ge":
29074
+ case "lt":
29075
+ case "le":
29076
+ case "eq":
29077
+ case "ne": {
29078
+ const a = p.a.op === "var" && p.a.id === SELF ? t : p.a;
29079
+ const b = p.b.op === "var" && p.b.id === SELF ? t : p.b;
29080
+ return { op: p.op, a, b };
29081
+ }
29082
+ case "typeof": {
29083
+ const tt2 = p.t.op === "var" && p.t.id === SELF ? t : p.t;
29084
+ return { op: "typeof", t: tt2, type: p.type };
29085
+ }
29086
+ case "and":
29087
+ return and(...p.args.map(subst));
29088
+ default:
29089
+ return p;
29090
+ }
29091
+ };
29092
+ if (c.fields) {
29093
+ const parts = [];
29094
+ for (const [key, field] of Object.entries(c.fields)) {
29095
+ if (field.optional || field.constraint.isOptional) continue;
29096
+ parts.push(instantiateOnTerm(field.constraint, getTerm(t, key), depth));
29097
+ }
29098
+ if (parts.length === 0) return { op: "true" };
29099
+ return parts.length === 1 ? parts[0] : and(...parts);
29100
+ }
29101
+ if (c.members) {
29102
+ const disj = or(...c.members.map((m) => instantiateOnTerm(m, t, depth)));
29103
+ const own = c.preds.map(subst);
29104
+ return own.length === 0 ? disj : and(...own, disj);
29105
+ }
29106
+ if (c.fn) {
29107
+ const own = c.preds.map(subst);
29108
+ return own.length === 0 ? pTrue : and(...own);
29109
+ }
29110
+ const preds = c.preds.map(subst);
29111
+ if (c.prim && c.preds.length === 0) return ptypeof(t, primToTypeof(c.prim));
29112
+ return preds.length === 0 ? { op: "true" } : preds.length === 1 ? preds[0] : and(...preds);
29113
+ }
29114
+ function constraintToEntryAbs(c, paramName2, depth = LAZY_TEMPLATE_DEPTH) {
29115
+ const t = v(paramName2);
29116
+ if (c.fields) {
29117
+ const slots = {};
29118
+ for (const [key, field] of Object.entries(c.fields)) {
29119
+ if (field.constraint.lazy && depth <= 0) continue;
29120
+ const fieldTerm = getTerm(t, key);
29121
+ slots[key] = {
29122
+ value: constraintOnTermAbs(field.constraint, fieldTerm, depth),
29123
+ ...field.optional || field.constraint.isOptional ? { optional: true } : {}
29124
+ };
29125
+ }
29126
+ return abs({ k: "obj", slots }, t, void 0, "path");
29127
+ }
29128
+ return constraintOnTermAbs(c, t, depth);
29129
+ }
29130
+ function memberLitValue(m) {
29131
+ const leaves = [];
29132
+ const visit2 = (p2) => {
29133
+ if (p2.op === "and") {
29134
+ p2.args.forEach(visit2);
29135
+ return;
29136
+ }
29137
+ leaves.push(p2);
29138
+ };
29139
+ m.preds.forEach(visit2);
29140
+ if (leaves.length !== 1) return { ok: false };
29141
+ const p = leaves[0];
29142
+ if (p.op !== "eq") return { ok: false };
29143
+ if (p.a.op === "var" && p.b.op === "lit") {
29144
+ return { ok: true, v: p.b.value };
29145
+ }
29146
+ if (p.b.op === "var" && p.a.op === "lit") {
29147
+ return { ok: true, v: p.a.value };
29148
+ }
29149
+ return { ok: false };
29150
+ }
29151
+ function samePrimLiteralUnionAbs(members, t) {
29152
+ if (members.length === 0) return void 0;
29153
+ const values = [];
29154
+ let prim2;
29155
+ for (const m of members) {
29156
+ const mk = memberLitValue(m);
29157
+ if (!mk.ok) return void 0;
29158
+ const v2 = mk.v;
29159
+ if (v2 === void 0 || v2 === null) return void 0;
29160
+ const mp = m.prim ?? (typeof v2 === "number" ? "number" : typeof v2 === "string" ? "string" : "boolean");
29161
+ if (prim2 === void 0) prim2 = mp;
29162
+ else if (prim2 !== mp) return void 0;
29163
+ values.push(v2);
29164
+ }
29165
+ if (prim2 === void 0) return void 0;
29166
+ const uniq = [];
29167
+ for (const v2 of values) {
29168
+ if (!uniq.some((u) => Object.is(u, v2))) uniq.push(v2);
29169
+ }
29170
+ const disj = or(
29171
+ ...uniq.map((v2) => eq(t, lit(v2)))
29172
+ );
29173
+ return abs({ k: "prim", type: prim2 }, t, disj, "path");
29174
+ }
29175
+ function constraintOnTermAbs(c, t, depth) {
29176
+ if (c.lazy) {
29177
+ if (depth <= 0) return abs({ k: "any" }, t, void 0, "path");
29178
+ return constraintOnTermAbs(derefConstraint(c), t, depth - 1);
29179
+ }
29180
+ if (c.fields) {
29181
+ const slots = {};
29182
+ for (const [key, field] of Object.entries(c.fields)) {
29183
+ if (field.constraint.lazy && depth <= 0) continue;
29184
+ slots[key] = {
29185
+ value: constraintOnTermAbs(field.constraint, getTerm(t, key), depth),
29186
+ ...field.optional || field.constraint.isOptional ? { optional: true } : {}
29187
+ };
29188
+ }
29189
+ return abs({ k: "obj", slots }, t, void 0, "path");
29190
+ }
29191
+ if (c.members) {
29192
+ const litUnion = samePrimLiteralUnionAbs(c.members, t);
29193
+ if (litUnion) return litUnion;
29194
+ const joined = c.members.map((m) => constraintOnTermAbs(m, t, depth)).reduce((a, b) => joinAbs(a, b));
29195
+ if (joined.shape.k === "prim" && joined.pred === void 0 && c.members.every((m) => m.prim === joined.shape.type)) {
29196
+ const type = joined.shape.type;
29197
+ return abs({ k: "prim", type }, t, ptypeof(t, primToTypeof(type)), "path");
29198
+ }
29199
+ return joined;
29200
+ }
29201
+ if (c.fn) {
29202
+ const paramNames = Object.keys(c.fn.params);
29203
+ const paramTypes = paramNames.map(
29204
+ (p, i) => constraintOnTermAbs(c.fn.params[p], v(`x${i}`), depth)
29205
+ );
29206
+ const returnType = c.fn.returns ? constraintOnTermAbs(c.fn.returns, v("ret"), depth) : unknown;
29207
+ return abs(
29208
+ { k: "fn", params: paramNames, paramTypes, returnType },
29209
+ t,
29210
+ void 0,
29211
+ "path"
29212
+ );
29213
+ }
29214
+ if (c.element) {
29215
+ const elem = constraintOnTermAbs(c.element, v("x[]"), depth);
29216
+ return abs({ k: "arr", element: elem }, t, void 0, "path");
29217
+ }
29218
+ const pred = instantiateOnTerm(c, t, depth);
29219
+ const predOut = pred.op === "true" ? void 0 : pred;
29220
+ if (c.prim) {
29221
+ return abs({ k: "prim", type: c.prim }, t, predOut, "path");
29222
+ }
29223
+ const allEqNullish = c.preds.length > 0 && c.preds.every(
29224
+ (p) => p.op === "eq" && (p.b.op === "lit" && (p.b.value === null || p.b.value === void 0) || p.a.op === "lit" && (p.a.value === null || p.a.value === void 0))
29225
+ );
29226
+ if (allEqNullish) {
29227
+ let nullish = null;
29228
+ for (const p of c.preds) {
29229
+ if (p.op !== "eq") continue;
29230
+ if (p.b.op === "lit" && (p.b.value === null || p.b.value === void 0)) {
29231
+ nullish = p.b.value;
29232
+ break;
29233
+ }
29234
+ if (p.a.op === "lit" && (p.a.value === null || p.a.value === void 0)) {
29235
+ nullish = p.a.value;
29236
+ break;
29237
+ }
29238
+ }
29239
+ return abs({ k: "unknown" }, lit(nullish), void 0, "path");
29240
+ }
29241
+ if (c.preds.length > 0) {
29242
+ return abs({ k: "prim", type: "number" }, t, predOut, "path");
29243
+ }
29244
+ return abs({ k: "any" }, t, void 0, "path");
29245
+ }
29246
+ function fnConstraintToEntryReqs(c) {
29247
+ if (!c.fn) throw new Error("nudo fnConstraintToEntryReqs(): constraint is not in fn() form");
29248
+ return Object.entries(c.fn.params).map(([param, constraint]) => ({
29249
+ param,
29250
+ constraint
29251
+ }));
29252
+ }
29253
+ function throwConstraintToKinds(c) {
29254
+ if (!c) return void 0;
29255
+ const out = /* @__PURE__ */ new Set();
29256
+ let any2 = false;
29257
+ const seen = /* @__PURE__ */ new Set();
29258
+ const note2 = (s) => {
29259
+ if (s === "*" || s === "any") any2 = true;
29260
+ else if (s) out.add(s);
29261
+ };
29262
+ const walk = (x) => {
29263
+ if (x.lazy) {
29264
+ if (seen.has(x.lazy)) return;
29265
+ seen.add(x.lazy);
29266
+ walk(derefConstraint(x));
29267
+ return;
29268
+ }
29269
+ if (x.members) {
29270
+ for (const m of x.members) walk(m);
29271
+ return;
29272
+ }
29273
+ for (const p of x.preds) {
29274
+ if (p.op !== "eq" && p.op !== "ne") continue;
29275
+ for (const side of [p.a, p.b]) {
29276
+ if (side.op === "lit" && typeof side.value === "string") note2(side.value);
29277
+ }
29278
+ }
29279
+ };
29280
+ walk(c);
29281
+ if (any2) return "*";
29282
+ if (out.size > 0) return [...out];
29283
+ return void 0;
29284
+ }
29285
+ var SELF, intFlaggedBuilders, LAZY_TEMPLATE_DEPTH, lazyDerefMemo, CONSTRAINT_BUILDERS, CONSTRAINT_BUILDER_NAMES, CONSTRAINT_EXPR_RE;
29286
+ var init_constraint = __esm({
29287
+ "../core/src/algebra/constraint.ts"() {
29288
+ "use strict";
29289
+ init_pred();
29290
+ init_term();
29291
+ init_abs();
29292
+ init_objects();
29293
+ SELF = "__nudo_self__";
29294
+ intFlaggedBuilders = /* @__PURE__ */ new WeakSet();
29295
+ LAZY_TEMPLATE_DEPTH = 3;
29296
+ lazyDerefMemo = /* @__PURE__ */ new WeakMap();
29297
+ CONSTRAINT_BUILDERS = {
29298
+ number,
29299
+ string,
29300
+ boolean,
29301
+ any,
29302
+ array,
29303
+ shape,
29304
+ lit: litC,
29305
+ union,
29306
+ nullable,
29307
+ lazy,
29308
+ fn,
29309
+ and: andC,
29310
+ partial,
29311
+ pick,
29312
+ omit
29313
+ };
29314
+ CONSTRAINT_BUILDER_NAMES = Object.keys(
29315
+ CONSTRAINT_BUILDERS
29316
+ );
29317
+ CONSTRAINT_EXPR_RE = new RegExp(
29318
+ `^(${CONSTRAINT_BUILDER_NAMES.join("|")})\\s*\\(`
29319
+ );
29320
+ }
29321
+ });
29322
+
29323
+ // ../core/src/algebra/domain-membership.ts
29324
+ function literalMeetsConstraint(lv, c, seen) {
29325
+ if (c.lazy) {
29326
+ const s = seen ?? /* @__PURE__ */ new Set();
29327
+ if (s.has(c.lazy)) return false;
29328
+ s.add(c.lazy);
29329
+ return literalMeetsConstraint(lv, derefConstraint(c), s);
29330
+ }
29331
+ const ext = c;
29332
+ if (c.fields || c.element) return false;
29333
+ if (ext.fn) return false;
29334
+ if (Array.isArray(ext.members) && ext.members.length > 0) {
29335
+ return ext.members.some((m) => literalMeetsConstraint(lv, m, seen));
29336
+ }
29337
+ if (c.prim === void 0) {
29338
+ return c.preds.every((p) => predHolds(lv, p));
29339
+ }
29340
+ if (!primMatches(c.prim, lv)) return false;
29341
+ if (isIntFlag(c) && c.prim === "number" && !(typeof lv === "number" && Number.isInteger(lv))) {
29342
+ return false;
29343
+ }
29344
+ return c.preds.every((p) => predHolds(lv, p));
29345
+ }
29346
+ function primMatches(prim2, lv) {
29347
+ switch (prim2) {
29348
+ case "number":
29349
+ return typeof lv === "number";
29350
+ case "string":
29351
+ return typeof lv === "string";
29352
+ case "boolean":
29353
+ return typeof lv === "boolean";
29354
+ case "object":
29355
+ return lv === null;
29356
+ case "undefined":
29357
+ return lv === void 0;
29358
+ default:
29359
+ return false;
29360
+ }
29361
+ }
29362
+ function predHolds(lv, p) {
29363
+ switch (p.op) {
29364
+ case "eq": {
29365
+ const litT = isSelfVar(p.a) && p.b.op === "lit" ? p.b : isSelfVar(p.b) && p.a.op === "lit" ? p.a : void 0;
29366
+ if (!litT) return false;
29367
+ return Object.is(lv, litT.value);
29368
+ }
29369
+ case "gt":
29370
+ case "ge":
29371
+ case "lt":
29372
+ case "le":
29373
+ return boundHolds(lv, p);
29374
+ case "typeof":
29375
+ return p.t.op === "var" && p.t.id === SELF && primMatches(p.type, lv);
29376
+ // and 是合取:逐参数按同一规则判定(string().length(n) 的 preds 是
29377
+ // and 包裹的两个长度界,叶子仍是 gt/ge/lt/le,无假阳性风险)
29378
+ case "and":
29379
+ return p.args.every((x) => predHolds(lv, x));
29380
+ // ne / or / not / true / false 等其余形态:保守不满足
29381
+ default:
29382
+ return false;
29383
+ }
29384
+ }
29385
+ function cmpHolds(x, op, n) {
29386
+ switch (op) {
29387
+ case "gt":
29388
+ return x > n;
29389
+ case "ge":
29390
+ return x >= n;
29391
+ case "lt":
29392
+ return x < n;
29393
+ case "le":
29394
+ return x <= n;
29395
+ }
29396
+ }
29397
+ function boundHolds(lv, p) {
29398
+ if (p.b.op !== "lit" || typeof p.b.value !== "number") return false;
29399
+ const n = p.b.value;
29400
+ if (isLengthSelf(p.a)) {
29401
+ return typeof lv === "string" && cmpHolds(lv.length, p.op, n);
29402
+ }
29403
+ if (isSelfVar(p.a)) {
29404
+ return typeof lv === "number" && cmpHolds(lv, p.op, n);
29405
+ }
29406
+ return false;
29407
+ }
29408
+ function isSelfVar(t) {
29409
+ return t.op === "var" && t.id === SELF;
29410
+ }
29411
+ function isLengthSelf(t) {
29412
+ return t.op === "app" && t.fn === "length" && t.args.length === 1 && isSelfVar(t.args[0]);
29413
+ }
29414
+ var init_domain_membership = __esm({
29415
+ "../core/src/algebra/domain-membership.ts"() {
29416
+ "use strict";
29417
+ init_constraint();
29418
+ }
29419
+ });
29420
+
29421
+ // ../core/src/algebra/contract-face.ts
29422
+ function attachContractFaces(fnObj, faces) {
29423
+ facesByFn.set(fnObj, faces);
29424
+ }
29425
+ function contractFacesOf(fnObj) {
29426
+ if (!fnObj || typeof fnObj !== "object" && typeof fnObj !== "function") {
29427
+ return void 0;
29428
+ }
29429
+ return facesByFn.get(fnObj);
29430
+ }
29431
+ function setContractFaceResolver(resolver) {
29432
+ const prev = contractFaceResolverSlot.get();
29433
+ contractFaceResolverSlot.set(resolver);
29434
+ return prev;
29435
+ }
29436
+ function resolveContractFacesByName(fnName) {
29437
+ const resolver = contractFaceResolverSlot.get();
29438
+ return resolver ? resolver(fnName) : void 0;
29439
+ }
29440
+ function argLacksInformation(a) {
29441
+ if (!a || typeof a !== "object" || !("shape" in a)) return false;
29442
+ const k = a.shape?.k;
29443
+ if (k === "any") return true;
29444
+ if (k === "unknown") return a.term?.op !== "lit";
29445
+ return false;
29446
+ }
29447
+ function adoptCallArgsToFaces(args, faces) {
29448
+ const n = Math.min(args.length, faces.paramFaces.length);
29449
+ let changed = false;
29450
+ const out = args.slice();
29451
+ for (let i = 0; i < n; i++) {
29452
+ const face = faces.paramFaces[i];
29453
+ if (!face || !argLacksInformation(args[i])) continue;
29454
+ out[i] = face;
29455
+ changed = true;
29456
+ }
29457
+ return changed ? out : args;
29458
+ }
29459
+ function litMeetsReturnConstraint(r, c) {
29460
+ if (!c) return false;
29461
+ const lv = litValue(r);
29462
+ if (!lv.ok) return false;
29463
+ const v2 = lv.value;
29464
+ if (typeof v2 !== "number" && typeof v2 !== "string" && typeof v2 !== "boolean" && v2 !== null && v2 !== void 0) {
29465
+ return false;
29466
+ }
29467
+ return literalMeetsConstraint(v2, c);
29468
+ }
29469
+ function presentCallResultFace(r, faces) {
29470
+ const face = faces.returns;
29471
+ if (!face || !r || typeof r !== "object" || !r.shape) return r;
29472
+ if (r.shape.k === "never") return r;
29473
+ if (r.conf === "opaque") return r;
29474
+ if (litMeetsReturnConstraint(r, faces.returnsConstraint)) return r;
29475
+ if (leqAbs(r, face).ok) return r;
29476
+ return face;
29477
+ }
29478
+ function contractFacesFromEffectiveInterface(eff, paramNames) {
29479
+ if (eff.source !== "handwritten") return void 0;
29480
+ const conflictParams = eff.conflict?.params ?? [];
29481
+ const paramFaces = [];
29482
+ let hasFace = false;
29483
+ for (const e of eff.params) {
29484
+ const idx = paramNames.indexOf(e.param);
29485
+ if (idx < 0 || conflictParams.includes(e.param)) continue;
29486
+ paramFaces[idx] = constraintToEntryAbs(e.constraint, e.param);
29487
+ hasFace = true;
29488
+ }
29489
+ let returns;
29490
+ let returnsConstraint;
29491
+ if (eff.returns && !eff.conflict?.returns) {
29492
+ returns = constraintToEntryAbs(eff.returns.constraint, "return");
29493
+ returnsConstraint = eff.returns.constraint;
29494
+ hasFace = true;
29495
+ }
29496
+ return hasFace ? {
29497
+ paramFaces,
29498
+ ...returns !== void 0 ? { returns } : {},
29499
+ ...returnsConstraint !== void 0 ? { returnsConstraint } : {}
29500
+ } : void 0;
29501
+ }
29502
+ var facesByFn, contractFaceResolverSlot;
29503
+ var init_contract_face = __esm({
29504
+ "../core/src/algebra/contract-face.ts"() {
29505
+ "use strict";
29506
+ init_abs();
29507
+ init_leq();
29508
+ init_constraint();
29509
+ init_domain_membership();
29510
+ init_collector_scope();
29511
+ facesByFn = /* @__PURE__ */ new WeakMap();
29512
+ contractFaceResolverSlot = createScopedSlot(
29513
+ () => null
29514
+ );
29515
+ registerCollectorScopeParticipant(
29516
+ (body) => contractFaceResolverSlot.runScoped(body)
29517
+ );
29518
+ }
29519
+ });
29520
+
28492
29521
  // ../core/src/algebra/exec/calls.ts
28493
29522
  var calls_exports = {};
28494
29523
  __export(calls_exports, {
@@ -28697,12 +29726,18 @@ function evalExitCall() {
28697
29726
  if (evalActiveCallKeys.length > 0) evalActiveCallKeys.pop();
28698
29727
  }
28699
29728
  function $callNamed(name, fn2, args, loc, argLocs) {
28700
- const pureName = pureFnNameOf(fn2);
29729
+ const faces = resolveContractFacesByName(name) ?? contractFacesOf(fn2);
28701
29730
  const fnObj = fn2 && (typeof fn2 === "object" || typeof fn2 === "function") ? fn2 : void 0;
28702
- const pk = pureName && fnObj ? callBudgetKey("pure", "", args) : void 0;
29731
+ if (faces && fnObj) attachContractFaces(fnObj, faces);
29732
+ const execArgs = faces ? adoptCallArgsToFaces(args, faces) : args;
29733
+ const pureName = pureFnNameOf(fn2);
29734
+ const pk = pureName && fnObj ? callBudgetKey("pure", "", execArgs) : void 0;
28703
29735
  if (fnObj && pk !== void 0) {
28704
29736
  const hit = pureCallMemo.get(fnObj)?.get(pk);
28705
- if (hit !== void 0) return routeApplyThrows(hit.abs, hit.throws);
29737
+ if (hit !== void 0) {
29738
+ const routed = routeApplyThrows(hit.abs, hit.throws);
29739
+ return faces ? presentCallResultFace(routed, faces) : routed;
29740
+ }
28706
29741
  }
28707
29742
  let result = unknown;
28708
29743
  let threw = false;
@@ -28736,24 +29771,24 @@ function $callNamed(name, fn2, args, loc, argLocs) {
28736
29771
  } else if (isHostGlobalFn(fn2)) {
28737
29772
  result = callHostGlobalLiteralOnly(name, fn2, args);
28738
29773
  } else {
28739
- const entered = evalEnterCall(name, fn2, args);
29774
+ const entered = evalEnterCall(name, fn2, execArgs);
28740
29775
  if (!entered.ok) {
28741
29776
  result = evalTruncatedAbs();
28742
29777
  } else {
28743
29778
  try {
28744
- result = callAtFunctionBoundary(() => fn2(...args));
29779
+ result = callAtFunctionBoundary(() => fn2(...execArgs));
28745
29780
  } finally {
28746
29781
  evalExitCall();
28747
29782
  }
28748
29783
  }
28749
29784
  }
28750
29785
  } else if (fn2 && typeof fn2 === "object" && "shape" in fn2) {
28751
- const entered = evalEnterCall(name, fn2, args);
29786
+ const entered = evalEnterCall(name, fn2, execArgs);
28752
29787
  if (!entered.ok) {
28753
29788
  result = evalTruncatedAbs();
28754
29789
  } else {
28755
29790
  try {
28756
- result = $call(fn2, args);
29791
+ result = $call(fn2, execArgs);
28757
29792
  } finally {
28758
29793
  evalExitCall();
28759
29794
  }
@@ -28787,7 +29822,7 @@ function $callNamed(name, fn2, args, loc, argLocs) {
28787
29822
  }
28788
29823
  }
28789
29824
  }
28790
- return result;
29825
+ return faces ? presentCallResultFace(result, faces) : result;
28791
29826
  }
28792
29827
  var PURE_CALL_MEMO_MAX, pureCallMemo, evalCallCollectorSlot, evalAssignCollectorSlot, bindingSinkSlot, GLOBAL_FNS, NEVER_EXEC_HOST_FN_NAMES, hostGlobalFnIds, MAX_EVAL_CALL_DEPTH, MAX_EVAL_TOTAL_CALLS, evalCallDepth, evalTotalCalls, evalActiveCallKeys, evalBudgetSessionDepth, evalCallDepthLimit, evalTotalCallsLimit, evalFnCallIds, evalFnCallIdSeq;
28793
29828
  var init_calls = __esm({
@@ -28808,6 +29843,7 @@ var init_calls = __esm({
28808
29843
  init_objects();
28809
29844
  init_lru_map();
28810
29845
  init_collector_scope();
29846
+ init_contract_face();
28811
29847
  PURE_CALL_MEMO_MAX = 256;
28812
29848
  pureCallMemo = /* @__PURE__ */ new WeakMap();
28813
29849
  evalCallCollectorSlot = createScopedSlot(() => null);
@@ -32953,9 +33989,14 @@ function $call(fn2, args, thisVal) {
32953
33989
  function $callInner(fn2, args, thisVal) {
32954
33990
  if (fn2?.shape?.k === "sum") {
32955
33991
  const results = fn2.shape.members.map((m) => $call(m, args, thisVal));
32956
- if (results.every((r) => r.shape.k === "unknown")) return unknown;
33992
+ if (results.every((r2) => r2.shape.k === "unknown")) return unknown;
32957
33993
  return results.reduce((a, b) => joinAbs(a, b));
32958
33994
  }
33995
+ const faces = contractFacesOf(fn2);
33996
+ const r = $callDispatch(fn2, faces ? adoptCallArgsToFaces(args, faces) : args, thisVal);
33997
+ return faces ? presentCallResultFace(r, faces) : r;
33998
+ }
33999
+ function $callDispatch(fn2, args, thisVal) {
32959
34000
  const pureName = pureFnNameOf(fn2);
32960
34001
  const fnObj = fn2 && typeof fn2 === "object" ? fn2 : void 0;
32961
34002
  const pk = pureName && fnObj ? pureMemoKey(args) : void 0;
@@ -33040,6 +34081,7 @@ var init_call = __esm({
33040
34081
  init_nudo_throw2();
33041
34082
  init_may_throw2();
33042
34083
  init_surface();
34084
+ init_contract_face();
33043
34085
  init_state();
33044
34086
  init_call_budget();
33045
34087
  init_lru_map();
@@ -37036,539 +38078,6 @@ var init_diag_channel = __esm({
37036
38078
  }
37037
38079
  });
37038
38080
 
37039
- // ../core/src/algebra/constraint.ts
37040
- function selfTerm() {
37041
- return v(SELF);
37042
- }
37043
- function getTerm(obj2, key) {
37044
- return app("get", [obj2, lit(key)]);
37045
- }
37046
- function lenTerm(t) {
37047
- return app("length", [t]);
37048
- }
37049
- function isConstraint(x) {
37050
- return !!x && typeof x === "object" && x.__nudoConstraint === true;
37051
- }
37052
- function isNudoConstraint(x) {
37053
- return isConstraint(x);
37054
- }
37055
- function isIntFlag(c) {
37056
- return c.int === true || intFlaggedBuilders.has(c);
37057
- }
37058
- function makeBuilder(prim2, preds, extra) {
37059
- const fields = extra?.fields;
37060
- const element = extra?.element;
37061
- const isInt = extra?.int;
37062
- const optional = extra?.optional;
37063
- const members = extra?.members;
37064
- const fnSlot = extra?.fn;
37065
- const base = {
37066
- __nudoConstraint: true,
37067
- ...prim2 ? { prim: prim2 } : {},
37068
- preds: [...preds],
37069
- ...fields ? { fields } : {},
37070
- ...element ? { element } : {},
37071
- ...optional ? { isOptional: true } : {},
37072
- ...members ? { members } : {},
37073
- ...fnSlot ? { fn: fnSlot } : {}
37074
- };
37075
- const add2 = (p) => makeBuilder(prim2, [...preds, p], extra);
37076
- const builder = Object.assign(
37077
- /* @__PURE__ */ Object.create(null),
37078
- base,
37079
- {
37080
- gt: (n) => add2(gt(selfTerm(), lit(n))),
37081
- ge: (n) => add2(ge(selfTerm(), lit(n))),
37082
- lt: (n) => add2(lt(selfTerm(), lit(n))),
37083
- le: (n) => add2(le(selfTerm(), lit(n))),
37084
- int: () => makeBuilder(prim2 ?? "number", preds, { ...extra, int: true }),
37085
- min: (n) => add2(ge(lenTerm(selfTerm()), lit(n))),
37086
- max: (n) => add2(le(lenTerm(selfTerm()), lit(n))),
37087
- length: (n) => add2(and(ge(lenTerm(selfTerm()), lit(n)), le(lenTerm(selfTerm()), lit(n)))),
37088
- shift: (n) => {
37089
- if (!Number.isFinite(n))
37090
- throw new Error("nudo shift(): offset must be a finite number");
37091
- if (fields || element || members || fnSlot)
37092
- throw new Error("nudo shift(): only numeric scalar constraint chains are allowed (shape/array/union/fn are not supported)");
37093
- if (prim2 !== void 0 && prim2 !== "number")
37094
- throw new Error(`nudo shift(): only numeric chains are allowed (prim=${prim2})`);
37095
- return makeBuilder(prim2, shiftBoundPreds(preds, n), extra);
37096
- },
37097
- optional: () => makeBuilder(prim2, preds, { ...extra, optional: true })
37098
- }
37099
- );
37100
- if (isInt) intFlaggedBuilders.add(builder);
37101
- return builder;
37102
- }
37103
- function shiftBoundPreds(preds, n) {
37104
- return preds.map((p) => {
37105
- if (p.op !== "gt" && p.op !== "ge" && p.op !== "lt" && p.op !== "le")
37106
- throw new Error(`nudo shift(): predicate ${p.op} is not supported (only gt/ge/lt/le constant bounds)`);
37107
- const { a, b } = p;
37108
- if (b.op !== "lit" || typeof b.value !== "number")
37109
- throw new Error("nudo shift(): the right-hand side of a constant bound must be a numeric literal");
37110
- if (termHasApp(a, "length") || termHasApp(b, "length"))
37111
- throw new Error("nudo shift(): length(...) bounds are not supported");
37112
- return { op: p.op, a, b: lit(b.value + n) };
37113
- });
37114
- }
37115
- function termHasApp(t, fn2) {
37116
- if (t.op !== "app") return false;
37117
- if (t.fn === fn2) return true;
37118
- return t.args.some((x) => termHasApp(x, fn2));
37119
- }
37120
- function number() {
37121
- return makeBuilder("number", []);
37122
- }
37123
- function string() {
37124
- return makeBuilder("string", []);
37125
- }
37126
- function boolean() {
37127
- return makeBuilder("boolean", []);
37128
- }
37129
- function any() {
37130
- return makeBuilder(void 0, []);
37131
- }
37132
- function array(item) {
37133
- return makeBuilder(void 0, [], {
37134
- element: asNestedConstraint(item, "array(item)")
37135
- });
37136
- }
37137
- function shape(fields) {
37138
- const mapped = {};
37139
- for (const [k, v2] of Object.entries(fields)) {
37140
- const constraint = asNestedConstraint(v2, `shape \u5B57\u6BB5 '${k}'`);
37141
- mapped[k] = {
37142
- constraint,
37143
- ...constraint.isOptional ? { optional: true } : {}
37144
- };
37145
- }
37146
- return makeBuilder(void 0, [], { fields: mapped });
37147
- }
37148
- function toPlainConstraint(c) {
37149
- if (!isConstraint(c))
37150
- throw new Error("nudo: expected a constraint value (number()/string()/\u2026 or a combinator)");
37151
- return {
37152
- __nudoConstraint: true,
37153
- ...c.prim ? { prim: c.prim } : {},
37154
- preds: [...c.preds],
37155
- ...c.fields ? { fields: c.fields } : {},
37156
- ...c.element ? { element: c.element } : {},
37157
- // isIntFlag 统一读取:builder(int 是方法)查 WeakSet,纯数据看 === true
37158
- ...isIntFlag(c) ? { int: true } : {},
37159
- ...c.isOptional ? { isOptional: true } : {},
37160
- ...c.members ? { members: c.members } : {},
37161
- ...c.fn ? { fn: c.fn } : {}
37162
- };
37163
- }
37164
- function litC(v2) {
37165
- const prim2 = typeof v2 === "number" ? "number" : typeof v2 === "string" ? "string" : typeof v2 === "boolean" ? "boolean" : void 0;
37166
- return makeBuilder(prim2, [eq(selfTerm(), lit(v2))]);
37167
- }
37168
- function asNestedConstraint(x, ctx2) {
37169
- if (isConstraint(x)) return toPlainConstraint(x);
37170
- if (x === null || x === void 0 || typeof x === "number" || typeof x === "string" || typeof x === "boolean") {
37171
- return toPlainConstraint(litC(x));
37172
- }
37173
- throw new Error(
37174
- `nudo: ${ctx2} expects a constraint value (number()/string()/\u2026) or a concrete literal; received a non-constraint`
37175
- );
37176
- }
37177
- function union(...cs) {
37178
- if (cs.length === 0)
37179
- throw new Error("nudo union(): at least one member constraint is required");
37180
- return makeBuilder(void 0, [], {
37181
- members: cs.map((c) => asNestedConstraint(c, "union member"))
37182
- });
37183
- }
37184
- function nullable(c) {
37185
- return makeBuilder(void 0, [], {
37186
- members: [
37187
- asNestedConstraint(c, "nullable()"),
37188
- toPlainConstraint(litC(null)),
37189
- toPlainConstraint(litC(void 0))
37190
- ]
37191
- });
37192
- }
37193
- function constraintAdmitsNullish(c) {
37194
- if (c.members) return c.members.some((m) => constraintAdmitsNullish(m));
37195
- if (!c.prim && c.preds.length === 0 && !c.fields && !c.element && !c.fn) return true;
37196
- for (const p of c.preds) {
37197
- for (const flat of p.op === "and" ? p.args : [p]) {
37198
- if (flat.op !== "eq") continue;
37199
- for (const side of [flat.a, flat.b]) {
37200
- if (side.op === "lit" && (side.value === null || side.value === void 0)) return true;
37201
- }
37202
- }
37203
- }
37204
- return false;
37205
- }
37206
- function fn(params, returns, opts) {
37207
- const normalized = {};
37208
- for (const [k, v2] of Object.entries(params)) {
37209
- normalized[k] = asNestedConstraint(v2, `fn param '${k}'`);
37210
- }
37211
- return makeBuilder(void 0, [], {
37212
- fn: {
37213
- params: normalized,
37214
- ...returns !== void 0 ? { returns: asNestedConstraint(returns, "fn return value") } : {},
37215
- ...opts?.throws !== void 0 ? { throws: asNestedConstraint(opts.throws, "fn throws") } : {}
37216
- }
37217
- });
37218
- }
37219
- function andC(...cs) {
37220
- if (cs.length === 0)
37221
- throw new Error("nudo and(): at least one constraint is required");
37222
- let prim2;
37223
- let isInt = false;
37224
- let allOptional = true;
37225
- const preds = [];
37226
- for (const c of cs) {
37227
- if (!isConstraint(c))
37228
- throw new Error("nudo: expected a constraint value (number()/string()/\u2026 or a combinator)");
37229
- if (c.fields || c.element || c.members || c.fn)
37230
- throw new Error("nudo and(): Phase 1 supports scalar constraint conjunction only (shape/array/union/fn are not supported)");
37231
- if (c.prim) {
37232
- if (prim2 !== void 0 && prim2 !== c.prim)
37233
- throw new Error(`nudo and(): inconsistent prim (${prim2} vs ${c.prim})`);
37234
- prim2 = c.prim;
37235
- }
37236
- preds.push(...c.preds);
37237
- if (isIntFlag(c)) isInt = true;
37238
- if (!c.isOptional) allOptional = false;
37239
- }
37240
- return makeBuilder(prim2, preds, {
37241
- ...isInt ? { int: true } : {},
37242
- ...allOptional ? { optional: true } : {}
37243
- });
37244
- }
37245
- function partial(c) {
37246
- if (!isConstraint(c) || !c.fields)
37247
- throw new Error("nudo partial(): only shape(...) constraints are accepted");
37248
- const fields = {};
37249
- for (const [k, f] of Object.entries(c.fields)) {
37250
- fields[k] = {
37251
- constraint: { ...toPlainConstraint(f.constraint), isOptional: true },
37252
- optional: true
37253
- };
37254
- }
37255
- return makeBuilder(c.prim, c.preds, { fields });
37256
- }
37257
- function pick(c, keys) {
37258
- if (!isConstraint(c) || !c.fields)
37259
- throw new Error("nudo pick(): only shape(...) constraints are accepted");
37260
- const fields = {};
37261
- for (const k of keys) {
37262
- const f = c.fields[k];
37263
- if (f) fields[k] = f;
37264
- }
37265
- return makeBuilder(c.prim, c.preds, { fields });
37266
- }
37267
- function omit(c, keys) {
37268
- if (!isConstraint(c) || !c.fields)
37269
- throw new Error("nudo omit(): only shape(...) constraints are accepted");
37270
- const drop = new Set(keys);
37271
- const fields = {};
37272
- for (const [k, f] of Object.entries(c.fields)) {
37273
- if (!drop.has(k)) fields[k] = f;
37274
- }
37275
- return makeBuilder(c.prim, c.preds, { fields });
37276
- }
37277
- function substTerm(t, paramName2) {
37278
- if (t.op === "var" && t.id === SELF) return v(paramName2);
37279
- if (t.op === "app" && t.fn === "get" && t.args.length === 2) {
37280
- return getTerm(substTerm(t.args[0], paramName2), String(
37281
- t.args[1].op === "lit" ? t.args[1].value : ""
37282
- ));
37283
- }
37284
- return t;
37285
- }
37286
- function substPred2(p, paramName2) {
37287
- switch (p.op) {
37288
- case "gt":
37289
- case "ge":
37290
- case "lt":
37291
- case "le":
37292
- case "eq":
37293
- case "ne": {
37294
- return { op: p.op, a: substTerm(p.a, paramName2), b: substTerm(p.b, paramName2) };
37295
- }
37296
- case "typeof": {
37297
- return { op: "typeof", t: substTerm(p.t, paramName2), type: p.type };
37298
- }
37299
- case "and":
37300
- return and(...p.args.map((x) => substPred2(x, paramName2)));
37301
- default:
37302
- return p;
37303
- }
37304
- }
37305
- function instantiateConstraint(c, paramName2) {
37306
- if (c.fields) {
37307
- const parts = [];
37308
- for (const [key, field] of Object.entries(c.fields)) {
37309
- if (field.optional || field.constraint.isOptional) continue;
37310
- const fieldTerm = getTerm(v(paramName2), key);
37311
- parts.push(instantiateOnTerm(field.constraint, fieldTerm));
37312
- }
37313
- if (c.prim) parts.push(ptypeof(v(paramName2), primToTypeof(c.prim)));
37314
- if (parts.length === 0) return { op: "true" };
37315
- return parts.length === 1 ? parts[0] : and(...parts);
37316
- }
37317
- if (c.members) {
37318
- const disj = or(
37319
- ...c.members.map((m) => instantiateOnTerm(m, v(paramName2)))
37320
- );
37321
- const own = c.preds.map((p) => substPred2(p, paramName2));
37322
- return own.length === 0 ? disj : and(...own, disj);
37323
- }
37324
- if (c.fn) {
37325
- const own = c.preds.map((p) => substPred2(p, paramName2));
37326
- return own.length === 0 ? pTrue : and(...own);
37327
- }
37328
- const preds = c.preds.map((p) => substPred2(p, paramName2));
37329
- if (c.prim && c.preds.length === 0) {
37330
- return ptypeof(v(paramName2), primToTypeof(c.prim));
37331
- }
37332
- return preds.length === 0 ? { op: "true" } : preds.length === 1 ? preds[0] : and(...preds);
37333
- }
37334
- function instantiateOnTerm(c, t) {
37335
- const subst = (p) => {
37336
- switch (p.op) {
37337
- case "gt":
37338
- case "ge":
37339
- case "lt":
37340
- case "le":
37341
- case "eq":
37342
- case "ne": {
37343
- const a = p.a.op === "var" && p.a.id === SELF ? t : p.a;
37344
- const b = p.b.op === "var" && p.b.id === SELF ? t : p.b;
37345
- return { op: p.op, a, b };
37346
- }
37347
- case "typeof": {
37348
- const tt2 = p.t.op === "var" && p.t.id === SELF ? t : p.t;
37349
- return { op: "typeof", t: tt2, type: p.type };
37350
- }
37351
- case "and":
37352
- return and(...p.args.map(subst));
37353
- default:
37354
- return p;
37355
- }
37356
- };
37357
- if (c.fields) {
37358
- const parts = [];
37359
- for (const [key, field] of Object.entries(c.fields)) {
37360
- if (field.optional || field.constraint.isOptional) continue;
37361
- parts.push(instantiateOnTerm(field.constraint, getTerm(t, key)));
37362
- }
37363
- if (parts.length === 0) return { op: "true" };
37364
- return parts.length === 1 ? parts[0] : and(...parts);
37365
- }
37366
- if (c.members) {
37367
- const disj = or(...c.members.map((m) => instantiateOnTerm(m, t)));
37368
- const own = c.preds.map(subst);
37369
- return own.length === 0 ? disj : and(...own, disj);
37370
- }
37371
- if (c.fn) {
37372
- const own = c.preds.map(subst);
37373
- return own.length === 0 ? pTrue : and(...own);
37374
- }
37375
- const preds = c.preds.map(subst);
37376
- if (c.prim && c.preds.length === 0) return ptypeof(t, primToTypeof(c.prim));
37377
- return preds.length === 0 ? { op: "true" } : preds.length === 1 ? preds[0] : and(...preds);
37378
- }
37379
- function constraintToEntryAbs(c, paramName2) {
37380
- const t = v(paramName2);
37381
- if (c.fields) {
37382
- const slots = {};
37383
- for (const [key, field] of Object.entries(c.fields)) {
37384
- const fieldTerm = getTerm(t, key);
37385
- slots[key] = {
37386
- value: constraintOnTermAbs(field.constraint, fieldTerm),
37387
- ...field.optional || field.constraint.isOptional ? { optional: true } : {}
37388
- };
37389
- }
37390
- return abs({ k: "obj", slots }, t, void 0, "path");
37391
- }
37392
- return constraintOnTermAbs(c, t);
37393
- }
37394
- function memberLitValue(m) {
37395
- const leaves = [];
37396
- const visit2 = (p2) => {
37397
- if (p2.op === "and") {
37398
- p2.args.forEach(visit2);
37399
- return;
37400
- }
37401
- leaves.push(p2);
37402
- };
37403
- m.preds.forEach(visit2);
37404
- if (leaves.length !== 1) return { ok: false };
37405
- const p = leaves[0];
37406
- if (p.op !== "eq") return { ok: false };
37407
- if (p.a.op === "var" && p.b.op === "lit") {
37408
- return { ok: true, v: p.b.value };
37409
- }
37410
- if (p.b.op === "var" && p.a.op === "lit") {
37411
- return { ok: true, v: p.a.value };
37412
- }
37413
- return { ok: false };
37414
- }
37415
- function samePrimLiteralUnionAbs(members, t) {
37416
- if (members.length === 0) return void 0;
37417
- const values = [];
37418
- let prim2;
37419
- for (const m of members) {
37420
- const mk = memberLitValue(m);
37421
- if (!mk.ok) return void 0;
37422
- const v2 = mk.v;
37423
- if (v2 === void 0 || v2 === null) return void 0;
37424
- const mp = m.prim ?? (typeof v2 === "number" ? "number" : typeof v2 === "string" ? "string" : "boolean");
37425
- if (prim2 === void 0) prim2 = mp;
37426
- else if (prim2 !== mp) return void 0;
37427
- values.push(v2);
37428
- }
37429
- if (prim2 === void 0) return void 0;
37430
- const uniq = [];
37431
- for (const v2 of values) {
37432
- if (!uniq.some((u) => Object.is(u, v2))) uniq.push(v2);
37433
- }
37434
- const disj = or(
37435
- ...uniq.map((v2) => eq(t, lit(v2)))
37436
- );
37437
- return abs({ k: "prim", type: prim2 }, t, disj, "path");
37438
- }
37439
- function constraintOnTermAbs(c, t) {
37440
- if (c.fields) {
37441
- const slots = {};
37442
- for (const [key, field] of Object.entries(c.fields)) {
37443
- slots[key] = {
37444
- value: constraintOnTermAbs(field.constraint, getTerm(t, key)),
37445
- ...field.optional || field.constraint.isOptional ? { optional: true } : {}
37446
- };
37447
- }
37448
- return abs({ k: "obj", slots }, t, void 0, "path");
37449
- }
37450
- if (c.members) {
37451
- const litUnion = samePrimLiteralUnionAbs(c.members, t);
37452
- if (litUnion) return litUnion;
37453
- const joined = c.members.map((m) => constraintOnTermAbs(m, t)).reduce((a, b) => joinAbs(a, b));
37454
- if (joined.shape.k === "prim" && joined.pred === void 0 && c.members.every((m) => m.prim === joined.shape.type)) {
37455
- const type = joined.shape.type;
37456
- return abs({ k: "prim", type }, t, ptypeof(t, primToTypeof(type)), "path");
37457
- }
37458
- return joined;
37459
- }
37460
- if (c.fn) {
37461
- const paramNames = Object.keys(c.fn.params);
37462
- const paramTypes = paramNames.map(
37463
- (p, i) => constraintOnTermAbs(c.fn.params[p], v(`x${i}`))
37464
- );
37465
- const returnType = c.fn.returns ? constraintOnTermAbs(c.fn.returns, v("ret")) : unknown;
37466
- return abs(
37467
- { k: "fn", params: paramNames, paramTypes, returnType },
37468
- t,
37469
- void 0,
37470
- "path"
37471
- );
37472
- }
37473
- if (c.element) {
37474
- const elem = constraintOnTermAbs(c.element, v("x[]"));
37475
- return abs({ k: "arr", element: elem }, t, void 0, "path");
37476
- }
37477
- const pred = instantiateOnTerm(c, t);
37478
- const predOut = pred.op === "true" ? void 0 : pred;
37479
- if (c.prim) {
37480
- return abs({ k: "prim", type: c.prim }, t, predOut, "path");
37481
- }
37482
- const allEqNullish = c.preds.length > 0 && c.preds.every(
37483
- (p) => p.op === "eq" && (p.b.op === "lit" && (p.b.value === null || p.b.value === void 0) || p.a.op === "lit" && (p.a.value === null || p.a.value === void 0))
37484
- );
37485
- if (allEqNullish) {
37486
- let nullish = null;
37487
- for (const p of c.preds) {
37488
- if (p.op !== "eq") continue;
37489
- if (p.b.op === "lit" && (p.b.value === null || p.b.value === void 0)) {
37490
- nullish = p.b.value;
37491
- break;
37492
- }
37493
- if (p.a.op === "lit" && (p.a.value === null || p.a.value === void 0)) {
37494
- nullish = p.a.value;
37495
- break;
37496
- }
37497
- }
37498
- return abs({ k: "unknown" }, lit(nullish), void 0, "path");
37499
- }
37500
- if (c.preds.length > 0) {
37501
- return abs({ k: "prim", type: "number" }, t, predOut, "path");
37502
- }
37503
- return abs({ k: "any" }, t, void 0, "path");
37504
- }
37505
- function fnConstraintToEntryReqs(c) {
37506
- if (!c.fn) throw new Error("nudo fnConstraintToEntryReqs(): constraint is not in fn() form");
37507
- return Object.entries(c.fn.params).map(([param, constraint]) => ({
37508
- param,
37509
- constraint
37510
- }));
37511
- }
37512
- function throwConstraintToKinds(c) {
37513
- if (!c) return void 0;
37514
- const out = /* @__PURE__ */ new Set();
37515
- let any2 = false;
37516
- const note2 = (s) => {
37517
- if (s === "*" || s === "any") any2 = true;
37518
- else if (s) out.add(s);
37519
- };
37520
- const walk = (x) => {
37521
- if (x.members) {
37522
- for (const m of x.members) walk(m);
37523
- return;
37524
- }
37525
- for (const p of x.preds) {
37526
- if (p.op !== "eq" && p.op !== "ne") continue;
37527
- for (const side of [p.a, p.b]) {
37528
- if (side.op === "lit" && typeof side.value === "string") note2(side.value);
37529
- }
37530
- }
37531
- };
37532
- walk(c);
37533
- if (any2) return "*";
37534
- if (out.size > 0) return [...out];
37535
- return void 0;
37536
- }
37537
- var SELF, intFlaggedBuilders, CONSTRAINT_BUILDERS, CONSTRAINT_BUILDER_NAMES, CONSTRAINT_EXPR_RE;
37538
- var init_constraint = __esm({
37539
- "../core/src/algebra/constraint.ts"() {
37540
- "use strict";
37541
- init_pred();
37542
- init_term();
37543
- init_abs();
37544
- init_objects();
37545
- SELF = "__nudo_self__";
37546
- intFlaggedBuilders = /* @__PURE__ */ new WeakSet();
37547
- CONSTRAINT_BUILDERS = {
37548
- number,
37549
- string,
37550
- boolean,
37551
- any,
37552
- array,
37553
- shape,
37554
- lit: litC,
37555
- union,
37556
- nullable,
37557
- fn,
37558
- and: andC,
37559
- partial,
37560
- pick,
37561
- omit
37562
- };
37563
- CONSTRAINT_BUILDER_NAMES = Object.keys(
37564
- CONSTRAINT_BUILDERS
37565
- );
37566
- CONSTRAINT_EXPR_RE = new RegExp(
37567
- `^(${CONSTRAINT_BUILDER_NAMES.join("|")})\\s*\\(`
37568
- );
37569
- }
37570
- });
37571
-
37572
38081
  // ../core/src/algebra/refine.ts
37573
38082
  function diagnoseMalformedNudoImports(source) {
37574
38083
  for (const bad of scanMalformedNudoImports(source)) {
@@ -38979,24 +39488,28 @@ function predToChain(p) {
38979
39488
  }
38980
39489
  return `{${predToString(p)}}`;
38981
39490
  }
38982
- function fmtConstraint(c) {
39491
+ function fmtConstraint(c, depth = LAZY_DISPLAY_DEPTH) {
39492
+ if (c.lazy) {
39493
+ if (depth <= 0) return "\u2026";
39494
+ return fmtConstraint(derefConstraint(c), depth - 1);
39495
+ }
38983
39496
  if (c.fn) {
38984
39497
  const args = [
38985
- `{ ${Object.entries(c.fn.params).map(([k, v2]) => `${k}: ${fmtConstraint(v2)}`).join(", ")} }`
39498
+ `{ ${Object.entries(c.fn.params).map(([k, v2]) => `${k}: ${fmtConstraint(v2, depth)}`).join(", ")} }`
38986
39499
  ];
38987
- if (c.fn.returns !== void 0) args.push(fmtConstraint(c.fn.returns));
38988
- if (c.fn.throws !== void 0) args.push(`{ throws: ${fmtConstraint(c.fn.throws)} }`);
39500
+ if (c.fn.returns !== void 0) args.push(fmtConstraint(c.fn.returns, depth));
39501
+ if (c.fn.throws !== void 0) args.push(`{ throws: ${fmtConstraint(c.fn.throws, depth)} }`);
38989
39502
  return `fn(${args.join(", ")})`;
38990
39503
  }
38991
- if (c.members) return `union(${c.members.map(fmtConstraint).join(", ")})`;
39504
+ if (c.members) return `union(${c.members.map((m) => fmtConstraint(m, depth)).join(", ")})`;
38992
39505
  if (c.fields) {
38993
39506
  const fs = Object.entries(c.fields).map(([k, f]) => {
38994
39507
  const opt = f.optional || f.constraint.isOptional ? "?" : "";
38995
- return `${k}${opt}: ${fmtConstraint(f.constraint)}`;
39508
+ return `${k}${opt}: ${fmtConstraint(f.constraint, depth)}`;
38996
39509
  });
38997
39510
  return `shape({ ${fs.join(", ")} })`;
38998
39511
  }
38999
- if (c.element) return `array(${fmtConstraint(c.element)})`;
39512
+ if (c.element) return `array(${fmtConstraint(c.element, depth)})`;
39000
39513
  if (c.preds.length === 1 && c.preds[0].op === "eq" && c.preds[0].a.op === "var" && c.preds[0].b.op === "lit" && !isIntFlag(c)) {
39001
39514
  return `lit(${litToString(c.preds[0].b.value)})`;
39002
39515
  }
@@ -39030,7 +39543,7 @@ function interfaceTierOf(source, fnName, fromFile, opts = {}) {
39030
39543
  function interfaceSourceOf(source, fnName, fromFile, opts = {}) {
39031
39544
  return interfaceTierOf(source, fnName, fromFile, opts)?.source;
39032
39545
  }
39033
- var MAX_INTERFACE_DIAGS, interfaceDiagChannel, sidecarLoadFailureSlot, MAX_SIDECAR_FP_NODES;
39546
+ var MAX_INTERFACE_DIAGS, interfaceDiagChannel, sidecarLoadFailureSlot, MAX_SIDECAR_FP_NODES, LAZY_DISPLAY_DEPTH;
39034
39547
  var init_interface = __esm({
39035
39548
  "../core/src/algebra/interface.ts"() {
39036
39549
  "use strict";
@@ -39054,6 +39567,7 @@ var init_interface = __esm({
39054
39567
  );
39055
39568
  registerCollectorScopeParticipant((body) => sidecarLoadFailureSlot.runScoped(body));
39056
39569
  MAX_SIDECAR_FP_NODES = 64;
39570
+ LAZY_DISPLAY_DEPTH = 2;
39057
39571
  }
39058
39572
  });
39059
39573
 
@@ -40758,98 +41272,6 @@ var init_diagnostics = __esm({
40758
41272
  }
40759
41273
  });
40760
41274
 
40761
- // ../core/src/algebra/domain-membership.ts
40762
- function literalMeetsConstraint(lv, c) {
40763
- const ext = c;
40764
- if (c.fields || c.element) return false;
40765
- if (ext.fn) return false;
40766
- if (Array.isArray(ext.members) && ext.members.length > 0) {
40767
- return ext.members.some((m) => literalMeetsConstraint(lv, m));
40768
- }
40769
- if (c.prim === void 0) {
40770
- return c.preds.every((p) => predHolds(lv, p));
40771
- }
40772
- if (!primMatches(c.prim, lv)) return false;
40773
- if (isIntFlag(c) && c.prim === "number" && !(typeof lv === "number" && Number.isInteger(lv))) {
40774
- return false;
40775
- }
40776
- return c.preds.every((p) => predHolds(lv, p));
40777
- }
40778
- function primMatches(prim2, lv) {
40779
- switch (prim2) {
40780
- case "number":
40781
- return typeof lv === "number";
40782
- case "string":
40783
- return typeof lv === "string";
40784
- case "boolean":
40785
- return typeof lv === "boolean";
40786
- case "object":
40787
- return lv === null;
40788
- case "undefined":
40789
- return lv === void 0;
40790
- default:
40791
- return false;
40792
- }
40793
- }
40794
- function predHolds(lv, p) {
40795
- switch (p.op) {
40796
- case "eq": {
40797
- const litT = isSelfVar(p.a) && p.b.op === "lit" ? p.b : isSelfVar(p.b) && p.a.op === "lit" ? p.a : void 0;
40798
- if (!litT) return false;
40799
- return Object.is(lv, litT.value);
40800
- }
40801
- case "gt":
40802
- case "ge":
40803
- case "lt":
40804
- case "le":
40805
- return boundHolds(lv, p);
40806
- case "typeof":
40807
- return p.t.op === "var" && p.t.id === SELF && primMatches(p.type, lv);
40808
- // and 是合取:逐参数按同一规则判定(string().length(n) 的 preds 是
40809
- // and 包裹的两个长度界,叶子仍是 gt/ge/lt/le,无假阳性风险)
40810
- case "and":
40811
- return p.args.every((x) => predHolds(lv, x));
40812
- // ne / or / not / true / false 等其余形态:保守不满足
40813
- default:
40814
- return false;
40815
- }
40816
- }
40817
- function cmpHolds(x, op, n) {
40818
- switch (op) {
40819
- case "gt":
40820
- return x > n;
40821
- case "ge":
40822
- return x >= n;
40823
- case "lt":
40824
- return x < n;
40825
- case "le":
40826
- return x <= n;
40827
- }
40828
- }
40829
- function boundHolds(lv, p) {
40830
- if (p.b.op !== "lit" || typeof p.b.value !== "number") return false;
40831
- const n = p.b.value;
40832
- if (isLengthSelf(p.a)) {
40833
- return typeof lv === "string" && cmpHolds(lv.length, p.op, n);
40834
- }
40835
- if (isSelfVar(p.a)) {
40836
- return typeof lv === "number" && cmpHolds(lv, p.op, n);
40837
- }
40838
- return false;
40839
- }
40840
- function isSelfVar(t) {
40841
- return t.op === "var" && t.id === SELF;
40842
- }
40843
- function isLengthSelf(t) {
40844
- return t.op === "app" && t.fn === "length" && t.args.length === 1 && isSelfVar(t.args[0]);
40845
- }
40846
- var init_domain_membership = __esm({
40847
- "../core/src/algebra/domain-membership.ts"() {
40848
- "use strict";
40849
- init_constraint();
40850
- }
40851
- });
40852
-
40853
41275
  // ../core/src/algebra/postcondition.ts
40854
41276
  function proved() {
40855
41277
  return { status: "proved" };
@@ -40899,6 +41321,15 @@ function provesBarePrimDomain(arm, constraint) {
40899
41321
  return arm.shape.k === "prim" && arm.shape.type === constraint.prim;
40900
41322
  }
40901
41323
  function assertImplies(ret, constraint, opts) {
41324
+ if (constraint.lazy) {
41325
+ const seen = opts?.seen;
41326
+ if (seen?.has(constraint.lazy)) {
41327
+ return unprovable("lazy constraint cycle");
41328
+ }
41329
+ const next = seen ? new Set(seen) : /* @__PURE__ */ new Set();
41330
+ next.add(constraint.lazy);
41331
+ return assertImplies(ret, derefConstraint(constraint), { ...opts, seen: next });
41332
+ }
40902
41333
  const phi2 = opts?.phi ?? pTrue;
40903
41334
  if (ret.shape.k === "never") return proved();
40904
41335
  if (isAnyConstraint(constraint)) return proved();
@@ -40984,7 +41415,7 @@ function assertImpliesSingle(arm, constraint, opts, phi2) {
40984
41415
  return assertScalar(arm, constraint, phi2);
40985
41416
  }
40986
41417
  function isAnyConstraint(c) {
40987
- return !c.prim && c.preds.length === 0 && !c.fields && !c.element && !c.members && !c.fn && !isIntFlag(c);
41418
+ return !c.prim && c.preds.length === 0 && !c.fields && !c.element && !c.members && !c.fn && !c.lazy && !isIntFlag(c);
40988
41419
  }
40989
41420
  function assertShapeFields(ret, constraint, opts) {
40990
41421
  let slots;
@@ -43901,43 +44332,142 @@ function checkSourceInScope(filePath, source, phi2, opts) {
43901
44332
  resetAbsCallBudget();
43902
44333
  const prevTrunc = setAbsTruncationCollector((label) => truncated.add(label));
43903
44334
  try {
43904
- const report = checkSourceInner(
43905
- filePath,
43906
- source,
43907
- file,
43908
- phi2,
43909
- callOpts,
43910
- issues,
43911
- signatures,
43912
- names2,
43913
- truncated,
43914
- opts,
43915
- depsFp,
43916
- sidecarFp
44335
+ const prevFaceResolver = setContractFaceResolver(
44336
+ makeSameFileFaceResolver(callOpts, filePath, source, file)
43917
44337
  );
43918
- const diagIssues = sidecarDiagIssues([
43919
- ...takeRefineDiagsSince(refineSince),
43920
- ...takeInterfaceDiagsSince(ifaceSince)
43921
- ]);
43922
- if (diagIssues.length > 0) {
43923
- report.issues.push(...diagIssues);
43924
- const errors = report.issues.filter((i) => i.severity === "error").length;
43925
- const warnings = report.issues.filter((i) => i.severity === "warning").length;
43926
- const infos = report.issues.filter((i) => i.severity === "info").length;
43927
- report.ok = errors === 0;
43928
- report.summary = {
43929
- errors,
43930
- warnings,
43931
- infos,
43932
- functions: report.summary.functions
43933
- };
44338
+ try {
44339
+ attachCrossModuleContractFaces(callOpts, filePath);
44340
+ const report = checkSourceInner(
44341
+ filePath,
44342
+ source,
44343
+ file,
44344
+ phi2,
44345
+ callOpts,
44346
+ issues,
44347
+ signatures,
44348
+ names2,
44349
+ truncated,
44350
+ opts,
44351
+ depsFp,
44352
+ sidecarFp
44353
+ );
44354
+ const diagIssues = sidecarDiagIssues([
44355
+ ...takeRefineDiagsSince(refineSince),
44356
+ ...takeInterfaceDiagsSince(ifaceSince)
44357
+ ]);
44358
+ if (diagIssues.length > 0) {
44359
+ report.issues.push(...diagIssues);
44360
+ const errors = report.issues.filter((i) => i.severity === "error").length;
44361
+ const warnings = report.issues.filter((i) => i.severity === "warning").length;
44362
+ const infos = report.issues.filter((i) => i.severity === "info").length;
44363
+ report.ok = errors === 0;
44364
+ report.summary = {
44365
+ errors,
44366
+ warnings,
44367
+ infos,
44368
+ functions: report.summary.functions
44369
+ };
44370
+ }
44371
+ if (memoKey) checkMemoSet(memoKey, report, memoPaths);
44372
+ return cloneCheckReport(report);
44373
+ } finally {
44374
+ setContractFaceResolver(prevFaceResolver);
43934
44375
  }
43935
- if (memoKey) checkMemoSet(memoKey, report, memoPaths);
43936
- return cloneCheckReport(report);
43937
44376
  } finally {
43938
44377
  setAbsTruncationCollector(prevTrunc);
43939
44378
  }
43940
44379
  }
44380
+ function makeSameFileFaceResolver(opts, filePath, source, file) {
44381
+ const loadModule = opts.loadModule;
44382
+ const fromFile = opts.fromFile ?? filePath;
44383
+ const autoBind = opts.autoBind;
44384
+ const projectDir = opts.projectDir;
44385
+ const memo = /* @__PURE__ */ new Map();
44386
+ return (fnName) => {
44387
+ if (memo.has(fnName)) return memo.get(fnName);
44388
+ let faces;
44389
+ try {
44390
+ const eff = effectiveInterface(source, fnName, {
44391
+ ...loadModule ? { loadModule } : {},
44392
+ fromFile,
44393
+ ...autoBind !== void 0 ? { autoBind } : {},
44394
+ ...projectDir !== void 0 ? { projectDir } : {}
44395
+ });
44396
+ if (eff) {
44397
+ const params = extractFn(source, fnName, file)?.params ?? [];
44398
+ faces = contractFacesFromEffectiveInterface(eff, params);
44399
+ }
44400
+ } catch {
44401
+ faces = void 0;
44402
+ }
44403
+ memo.set(fnName, faces);
44404
+ return faces;
44405
+ };
44406
+ }
44407
+ function attachCrossModuleContractFaces(opts, filePath) {
44408
+ const loadModule = opts.loadModule;
44409
+ const fromFile = opts.fromFile ?? filePath;
44410
+ if (!loadModule) return;
44411
+ const tables2 = [];
44412
+ for (const t of [opts.modules, opts.inject?.modules]) {
44413
+ if (t && typeof t === "object" && !tables2.includes(t)) tables2.push(t);
44414
+ }
44415
+ if (tables2.length === 0) return;
44416
+ const autoBind = opts.autoBind;
44417
+ const projectDir = opts.projectDir;
44418
+ const facesCache = /* @__PURE__ */ new Map();
44419
+ const facesFor = (depSource, depPath, name, paramNames) => {
44420
+ const key = `${depPath}\0${name}`;
44421
+ if (facesCache.has(key)) return facesCache.get(key);
44422
+ let faces;
44423
+ try {
44424
+ const eff = effectiveInterface(depSource, name, {
44425
+ loadModule,
44426
+ fromFile: depPath,
44427
+ ...autoBind !== void 0 ? { autoBind } : {},
44428
+ ...projectDir !== void 0 ? { projectDir } : {}
44429
+ });
44430
+ if (eff) faces = contractFacesFromEffectiveInterface(eff, paramNames);
44431
+ } catch {
44432
+ faces = void 0;
44433
+ }
44434
+ facesCache.set(key, faces);
44435
+ return faces;
44436
+ };
44437
+ const attachFnAbs = (v2, depSource, depPath, name) => {
44438
+ if (!v2 || typeof v2 !== "object" || !("shape" in v2)) return;
44439
+ const shape2 = v2.shape;
44440
+ if (shape2.k !== "fn") return;
44441
+ let paramNames;
44442
+ try {
44443
+ paramNames = extractFn(depSource, name)?.params ?? [];
44444
+ } catch {
44445
+ paramNames = [];
44446
+ }
44447
+ const faces = facesFor(depSource, depPath, name, paramNames);
44448
+ if (faces) attachContractFaces(v2, faces);
44449
+ };
44450
+ for (const table of tables2) {
44451
+ for (const [spec, mod2] of Object.entries(table)) {
44452
+ if (!mod2 || typeof mod2 !== "object") continue;
44453
+ const named = mod2.named;
44454
+ if (!named) continue;
44455
+ let depSource;
44456
+ try {
44457
+ depSource = loadModule(spec, fromFile);
44458
+ } catch {
44459
+ depSource = void 0;
44460
+ }
44461
+ if (!depSource) continue;
44462
+ const depPath = resolveDepPath(fromFile, spec);
44463
+ for (const [name, v2] of Object.entries(named)) {
44464
+ attachFnAbs(v2, depSource, depPath, name);
44465
+ }
44466
+ const def = mod2.default;
44467
+ if (def !== void 0) attachFnAbs(def, depSource, depPath, "default");
44468
+ }
44469
+ }
44470
+ }
43941
44471
  function sidecarDiagIssues(diags) {
43942
44472
  const seen = /* @__PURE__ */ new Set();
43943
44473
  const out = [];
@@ -44445,6 +44975,8 @@ var init_check = __esm({
44445
44975
  init_constraint();
44446
44976
  init_postcondition();
44447
44977
  init_generalize();
44978
+ init_contract_face();
44979
+ init_sidecar_path();
44448
44980
  init_param_surface();
44449
44981
  init_fn_fp();
44450
44982
  init_stable_source_key();
@@ -45026,6 +45558,7 @@ __export(src_exports, {
45026
45558
  currentExecPhi: () => currentExecPhi,
45027
45559
  currentPhi: () => currentPhi,
45028
45560
  definitelyNotNullishShape: () => definitelyNotNullishShape,
45561
+ derefConstraint: () => derefConstraint,
45029
45562
  describePhi: () => describePhi,
45030
45563
  div: () => div,
45031
45564
  drainPromiseMicros: () => drainPromiseMicros,
@@ -45149,6 +45682,7 @@ __export(src_exports, {
45149
45682
  joinObjects: () => joinObjects,
45150
45683
  joinThenProject: () => joinThenProject,
45151
45684
  joinValues: () => joinValues,
45685
+ lazy: () => lazy,
45152
45686
  le: () => le,
45153
45687
  leNum: () => leNum,
45154
45688
  leavePromiseExecutorScope: () => leavePromiseExecutorScope,
@@ -60210,7 +60744,7 @@ var require_typescript = __commonJS({
60210
60744
  affectsEmitOptionDeclarations: () => affectsEmitOptionDeclarations,
60211
60745
  allKeysStartWithDot: () => allKeysStartWithDot,
60212
60746
  altDirectorySeparator: () => altDirectorySeparator,
60213
- and: () => and7,
60747
+ and: () => and8,
60214
60748
  append: () => append,
60215
60749
  appendIfUnique: () => appendIfUnique,
60216
60750
  arrayFrom: () => arrayFrom,
@@ -63665,7 +64199,7 @@ var require_typescript = __commonJS({
63665
64199
  function isPatternMatch({ prefix: prefix2, suffix }, candidate) {
63666
64200
  return candidate.length >= prefix2.length + suffix.length && startsWith(candidate, prefix2) && endsWith(candidate, suffix);
63667
64201
  }
63668
- function and7(f, g) {
64202
+ function and8(f, g) {
63669
64203
  return (arg) => f(arg) && g(arg);
63670
64204
  }
63671
64205
  function or2(...fs) {
@@ -114751,7 +115285,7 @@ ${lanes.join("\n")}
114751
115285
  SignatureCheckMode3[SignatureCheckMode3["Callback"] = 3] = "Callback";
114752
115286
  return SignatureCheckMode3;
114753
115287
  })(SignatureCheckMode || {});
114754
- var isNotOverloadAndNotAccessor = and7(isNotOverload, isNotAccessor);
115288
+ var isNotOverloadAndNotAccessor = and8(isNotOverload, isNotAccessor);
114755
115289
  var intrinsicTypeKinds = new Map(Object.entries({
114756
115290
  Uppercase: 0,
114757
115291
  Lowercase: 1,
@@ -157737,7 +158271,7 @@ ${lanes.join("\n")}
157737
158271
  if (flags & (1920 | 384)) {
157738
158272
  return;
157739
158273
  }
157740
- const exportedDeclarationsCount = countWhere(declarations, and7(isNotOverloadAndNotAccessor, not2(isInterfaceDeclaration)));
158274
+ const exportedDeclarationsCount = countWhere(declarations, and8(isNotOverloadAndNotAccessor, not2(isInterfaceDeclaration)));
157741
158275
  if (flags & 524288 && exportedDeclarationsCount <= 2) {
157742
158276
  return;
157743
158277
  }
@@ -229094,7 +229628,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
229094
229628
  const maybeHeritageClauseSymbol = getHeritageClauseSymbolTable(classDeclaration, checker);
229095
229629
  const implementedType = checker.getTypeAtLocation(implementedTypeNode);
229096
229630
  const implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
229097
- const nonPrivateAndNotExistedInHeritageClauseMembers = implementedTypeSymbols.filter(and7(symbolPointsToNonPrivateMember, (symbol) => !maybeHeritageClauseSymbol.has(symbol.escapedName)));
229631
+ const nonPrivateAndNotExistedInHeritageClauseMembers = implementedTypeSymbols.filter(and8(symbolPointsToNonPrivateMember, (symbol) => !maybeHeritageClauseSymbol.has(symbol.escapedName)));
229098
229632
  const classType = checker.getTypeAtLocation(classDeclaration);
229099
229633
  const constructor = find2(classDeclaration.members, (m) => isConstructorDeclaration(m));
229100
229634
  if (!classType.getNumberIndexType()) {
@@ -256467,7 +257001,7 @@ ${options.prefix}` : "\n" : options.prefix
256467
257001
  affectsEmitOptionDeclarations: () => affectsEmitOptionDeclarations,
256468
257002
  allKeysStartWithDot: () => allKeysStartWithDot,
256469
257003
  altDirectorySeparator: () => altDirectorySeparator,
256470
- and: () => and7,
257004
+ and: () => and8,
256471
257005
  append: () => append,
256472
257006
  appendIfUnique: () => appendIfUnique,
256473
257007
  arrayFrom: () => arrayFrom,
@@ -288176,7 +288710,7 @@ function runTscBaseline(root, files) {
288176
288710
  }
288177
288711
  }
288178
288712
  async function migrateVerify(paths, opts = {}) {
288179
- const { checkSource: checkSource2, formatCheckReport: formatCheckReport2, pTrue: pTrue3 } = await Promise.resolve().then(() => (init_src(), src_exports));
288713
+ const { checkSource: checkSource2, formatCheckReport: formatCheckReport2, pTrue: pTrue4 } = await Promise.resolve().then(() => (init_src(), src_exports));
288180
288714
  const { collectSkipReturns: collectSkipReturns2, defaultLoadModule: defaultLoadModule3, findProjectConfig: findProjectConfig3, interfaceConfig: interfaceConfig3, checkConfig: checkConfig2 } = await Promise.resolve().then(() => (init_src4(), src_exports3));
288181
288715
  const files = [];
288182
288716
  for (const p of paths) {
@@ -288201,7 +288735,7 @@ async function migrateVerify(paths, opts = {}) {
288201
288735
  const proj = findProjectConfig3(dirname29(file));
288202
288736
  const cCfg = checkConfig2(proj?.config);
288203
288737
  const autoBind = interfaceConfig3(proj?.config).autoBind;
288204
- const report = checkSource2(file, source, pTrue3, {
288738
+ const report = checkSource2(file, source, pTrue4, {
288205
288739
  loadModule: defaultLoadModule3,
288206
288740
  fromFile: file,
288207
288741
  ...autoBind === false ? { autoBind: false } : {},
@@ -290630,7 +291164,7 @@ async function healthFile(filePath, records) {
290630
291164
  return report;
290631
291165
  }
290632
291166
  async function countInterfaceDrift(filePath) {
290633
- const { sidecarPathOf: sidecarPathOf2, checkSource: checkSource2, pTrue: pTrue3 } = await Promise.resolve().then(() => (init_src(), src_exports));
291167
+ const { sidecarPathOf: sidecarPathOf2, checkSource: checkSource2, pTrue: pTrue4 } = await Promise.resolve().then(() => (init_src(), src_exports));
290634
291168
  const { defaultLoadModule: defaultLoadModule3 } = await Promise.resolve().then(() => (init_src4(), src_exports3));
290635
291169
  const { existsSync: ex, readFileSync: rf } = await import("fs");
290636
291170
  const abs2 = resolve18(filePath);
@@ -290648,7 +291182,7 @@ async function countInterfaceDrift(filePath) {
290648
291182
  const proj = findProjectConfig3(dirname28(abs2));
290649
291183
  const autoBind = interfaceConfig3(proj?.config).autoBind;
290650
291184
  const source = rf(abs2, "utf-8");
290651
- const r = checkSource2(abs2, source, pTrue3, {
291185
+ const r = checkSource2(abs2, source, pTrue4, {
290652
291186
  loadModule: defaultLoadModule3,
290653
291187
  fromFile: abs2,
290654
291188
  ...autoBind === false ? { autoBind: false } : {},