@nudojs/core 1.7.9 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,18 @@
1
1
  import {
2
2
  $invoke,
3
3
  $new,
4
+ CONSTRAINT_BUILDERS,
4
5
  abs,
5
- and,
6
+ andC,
6
7
  anyAbs,
7
- app,
8
8
  callTranspiledExportFull,
9
+ constraintToEntryAbs,
9
10
  createScopedSlot,
10
11
  defaultLeakBudget,
12
+ derefConstraint,
11
13
  emptyEnv,
12
- eq,
13
14
  evalExprAbs,
15
+ fnConstraintToEntryReqs,
14
16
  foldRequireSpecArg,
15
17
  formalParamDisplayNames,
16
18
  formalParamsFromNodes,
@@ -18,37 +20,32 @@ import {
18
20
  formatShape,
19
21
  formatShapeSlot,
20
22
  freeIdentifiers,
21
- ge,
22
23
  getFnImpl,
23
24
  getSlot,
24
- gt,
25
25
  identBoundaryRegex,
26
- joinAbs,
27
- le,
28
- lit,
26
+ instantiateConstraint,
27
+ isIntFlag,
28
+ isNudoConstraint,
29
29
  litKeyString,
30
30
  litValue,
31
+ literalMeetsConstraint,
31
32
  locateContractParam,
32
- lt,
33
33
  numLit,
34
- or,
35
34
  pTrue,
36
35
  parseSource,
37
36
  predToString,
38
- primToTypeof,
39
- ptypeof,
40
37
  registerCollectorScopeParticipant,
41
38
  runTranspiledOptionsMemoKey,
42
39
  snapshotAbs,
43
40
  stripStringsKeepComments,
44
41
  termToString,
42
+ throwConstraintToKinds,
45
43
  tryRunTranspiled,
46
- unknown,
47
44
  v,
48
45
  withEvalBudgetOverride,
49
46
  withExecPhi,
50
47
  withFnBudgetOverride
51
- } from "./chunk-YQIRU637.js";
48
+ } from "./chunk-P6O5BXOA.js";
52
49
 
53
50
  // src/algebra/directive-scan.ts
54
51
  function cleanDirectiveLine(raw, kind) {
@@ -153,16 +150,16 @@ function listFnDirectiveScopes(file) {
153
150
  const decl = d;
154
151
  const idName = decl.id?.type === "Identifier" ? decl.id.name : void 0;
155
152
  if (isFnExpr(decl.init)) {
156
- const fn2 = decl.init;
153
+ const fn = decl.init;
157
154
  const scope = buildScope(
158
155
  idName ?? "<anonymous>",
159
- fn2,
156
+ fn,
160
157
  ctx.wrapperNode,
161
158
  node.leadingComments,
162
159
  ctx.wrapperNode?.leadingComments
163
160
  );
164
161
  out.push(scope);
165
- visit2(fn2, { owner: idName });
162
+ visit2(fn, { owner: idName });
166
163
  } else {
167
164
  visit2(decl.init, { owner: idName, commentHost: node, wrapperNode: ctx.wrapperNode });
168
165
  }
@@ -360,17 +357,17 @@ function listFnDirectiveScopes(file) {
360
357
  const vd = raw;
361
358
  const idName = vd.id?.type === "Identifier" ? vd.id.name : void 0;
362
359
  if (isFnExpr(vd.init)) {
363
- const fn2 = vd.init;
360
+ const fn = vd.init;
364
361
  out.push(
365
362
  buildScope(
366
363
  idName ?? "default",
367
- fn2,
364
+ fn,
368
365
  wrapper,
369
366
  d.leadingComments,
370
367
  wrapper.leadingComments
371
368
  )
372
369
  );
373
- visit2(fn2, { owner: idName });
370
+ visit2(fn, { owner: idName });
374
371
  } else {
375
372
  visit2(vd.init, {
376
373
  owner: idName,
@@ -419,10 +416,10 @@ function parseEnvPayload(payload) {
419
416
  return payload.split(",").map((e) => e.trim().replace(/^['"]|['"]$/g, "")).filter((e) => e && (/^\w+$/.test(e) || isPathLikeEnv(e)));
420
417
  }
421
418
  function parseMockModulePayload(payload) {
422
- const partial2 = payload.match(/^\s*"([^"]+)"\s*\{([^}]+)\}\s*from\s*"([^"]+)"\s*$/);
423
- if (partial2) {
424
- const names = partial2[2].split(",").map((n) => n.trim()).filter(Boolean);
425
- return { source: partial2[1], names, fromPath: partial2[3] };
419
+ const partial = payload.match(/^\s*"([^"]+)"\s*\{([^}]+)\}\s*from\s*"([^"]+)"\s*$/);
420
+ if (partial) {
421
+ const names = partial[2].split(",").map((n) => n.trim()).filter(Boolean);
422
+ return { source: partial[1], names, fromPath: partial[3] };
426
423
  }
427
424
  const full = payload.match(/^\s*"([^"]+)"\s+from\s*"([^"]+)"\s*$/);
428
425
  if (full) {
@@ -617,15 +614,15 @@ function scanContractSegments(lines) {
617
614
  }
618
615
  function scanThrowsDecl(lines) {
619
616
  const kinds = /* @__PURE__ */ new Set();
620
- let any2 = false;
617
+ let any = false;
621
618
  for (const line of lines) {
622
619
  const th = line.match(/^@nudo:throws\s+(.+)$/i);
623
620
  if (th) {
624
621
  const spec = th[1].trim();
625
- if (spec === "*") any2 = true;
622
+ if (spec === "*") any = true;
626
623
  else {
627
624
  for (const k of spec.split(/[,\s|]+/).map((s) => s.trim()).filter(Boolean)) {
628
- if (k === "*") any2 = true;
625
+ if (k === "*") any = true;
629
626
  else kinds.add(k);
630
627
  }
631
628
  }
@@ -633,16 +630,16 @@ function scanThrowsDecl(lines) {
633
630
  const cs = line.match(/!!\s*throws(?:\s+([A-Za-z*][\w*|,\s]*))?/i);
634
631
  if (cs) {
635
632
  const spec = (cs[1] ?? "*").trim();
636
- if (spec === "" || spec === "*") any2 = true;
633
+ if (spec === "" || spec === "*") any = true;
637
634
  else {
638
635
  for (const k of spec.split(/[,\s|]+/).map((s) => s.trim()).filter(Boolean)) {
639
- if (k === "*") any2 = true;
636
+ if (k === "*") any = true;
640
637
  else kinds.add(k);
641
638
  }
642
639
  }
643
640
  }
644
641
  }
645
- if (any2) return "*";
642
+ if (any) return "*";
646
643
  if (kinds.size > 0) return [...kinds].join(",");
647
644
  return void 0;
648
645
  }
@@ -753,8 +750,8 @@ function createDiagChannel(cap) {
753
750
  let seq = 0;
754
751
  const buf = [];
755
752
  return {
756
- setCollector(fn2) {
757
- collector = fn2;
753
+ setCollector(fn) {
754
+ collector = fn;
758
755
  },
759
756
  getCollector() {
760
757
  return collector;
@@ -789,7 +786,7 @@ function createScopedDiagChannel(cap) {
789
786
  const fallback = createDiagChannel(cap);
790
787
  const chan = () => als.getStore() ?? fallback;
791
788
  return {
792
- setCollector: (fn2) => chan().setCollector(fn2),
789
+ setCollector: (fn) => chan().setCollector(fn),
793
790
  getCollector: () => chan().getCollector(),
794
791
  count: () => chan().count(),
795
792
  take: () => chan().take(),
@@ -803,529 +800,6 @@ function createScopedDiagChannel(cap) {
803
800
  };
804
801
  }
805
802
 
806
- // src/algebra/constraint.ts
807
- var SELF = "__nudo_self__";
808
- function selfTerm() {
809
- return v(SELF);
810
- }
811
- function getTerm(obj, key) {
812
- return app("get", [obj, lit(key)]);
813
- }
814
- function lenTerm(t) {
815
- return app("length", [t]);
816
- }
817
- function isConstraint(x) {
818
- return !!x && typeof x === "object" && x.__nudoConstraint === true;
819
- }
820
- function isNudoConstraint(x) {
821
- return isConstraint(x);
822
- }
823
- var intFlaggedBuilders = /* @__PURE__ */ new WeakSet();
824
- function isIntFlag(c) {
825
- return c.int === true || intFlaggedBuilders.has(c);
826
- }
827
- function makeBuilder(prim, preds, extra) {
828
- const fields = extra?.fields;
829
- const element = extra?.element;
830
- const isInt = extra?.int;
831
- const optional = extra?.optional;
832
- const members = extra?.members;
833
- const fnSlot = extra?.fn;
834
- const base = {
835
- __nudoConstraint: true,
836
- ...prim ? { prim } : {},
837
- preds: [...preds],
838
- ...fields ? { fields } : {},
839
- ...element ? { element } : {},
840
- ...optional ? { isOptional: true } : {},
841
- ...members ? { members } : {},
842
- ...fnSlot ? { fn: fnSlot } : {}
843
- };
844
- const add = (p) => makeBuilder(prim, [...preds, p], extra);
845
- const builder = Object.assign(
846
- /* @__PURE__ */ Object.create(null),
847
- base,
848
- {
849
- gt: (n) => add(gt(selfTerm(), lit(n))),
850
- ge: (n) => add(ge(selfTerm(), lit(n))),
851
- lt: (n) => add(lt(selfTerm(), lit(n))),
852
- le: (n) => add(le(selfTerm(), lit(n))),
853
- int: () => makeBuilder(prim ?? "number", preds, { ...extra, int: true }),
854
- min: (n) => add(ge(lenTerm(selfTerm()), lit(n))),
855
- max: (n) => add(le(lenTerm(selfTerm()), lit(n))),
856
- length: (n) => add(and(ge(lenTerm(selfTerm()), lit(n)), le(lenTerm(selfTerm()), lit(n)))),
857
- shift: (n) => {
858
- if (!Number.isFinite(n))
859
- throw new Error("nudo shift(): offset must be a finite number");
860
- if (fields || element || members || fnSlot)
861
- throw new Error("nudo shift(): only numeric scalar constraint chains are allowed (shape/array/union/fn are not supported)");
862
- if (prim !== void 0 && prim !== "number")
863
- throw new Error(`nudo shift(): only numeric chains are allowed (prim=${prim})`);
864
- return makeBuilder(prim, shiftBoundPreds(preds, n), extra);
865
- },
866
- optional: () => makeBuilder(prim, preds, { ...extra, optional: true })
867
- }
868
- );
869
- if (isInt) intFlaggedBuilders.add(builder);
870
- return builder;
871
- }
872
- function shiftBoundPreds(preds, n) {
873
- return preds.map((p) => {
874
- if (p.op !== "gt" && p.op !== "ge" && p.op !== "lt" && p.op !== "le")
875
- throw new Error(`nudo shift(): predicate ${p.op} is not supported (only gt/ge/lt/le constant bounds)`);
876
- const { a, b } = p;
877
- if (b.op !== "lit" || typeof b.value !== "number")
878
- throw new Error("nudo shift(): the right-hand side of a constant bound must be a numeric literal");
879
- if (termHasApp(a, "length") || termHasApp(b, "length"))
880
- throw new Error("nudo shift(): length(...) bounds are not supported");
881
- return { op: p.op, a, b: lit(b.value + n) };
882
- });
883
- }
884
- function termHasApp(t, fn2) {
885
- if (t.op !== "app") return false;
886
- if (t.fn === fn2) return true;
887
- return t.args.some((x) => termHasApp(x, fn2));
888
- }
889
- function number() {
890
- return makeBuilder("number", []);
891
- }
892
- function string() {
893
- return makeBuilder("string", []);
894
- }
895
- function boolean() {
896
- return makeBuilder("boolean", []);
897
- }
898
- function any() {
899
- return makeBuilder(void 0, []);
900
- }
901
- function array(item) {
902
- return makeBuilder(void 0, [], {
903
- element: asNestedConstraint(item, "array(item)")
904
- });
905
- }
906
- function shape(fields) {
907
- const mapped = {};
908
- for (const [k, v2] of Object.entries(fields)) {
909
- const constraint = asNestedConstraint(v2, `shape \u5B57\u6BB5 '${k}'`);
910
- mapped[k] = {
911
- constraint,
912
- ...constraint.isOptional ? { optional: true } : {}
913
- };
914
- }
915
- return makeBuilder(void 0, [], { fields: mapped });
916
- }
917
- function toPlainConstraint(c) {
918
- if (!isConstraint(c))
919
- throw new Error("nudo: expected a constraint value (number()/string()/\u2026 or a combinator)");
920
- return {
921
- __nudoConstraint: true,
922
- ...c.prim ? { prim: c.prim } : {},
923
- preds: [...c.preds],
924
- ...c.fields ? { fields: c.fields } : {},
925
- ...c.element ? { element: c.element } : {},
926
- // isIntFlag 统一读取:builder(int 是方法)查 WeakSet,纯数据看 === true
927
- ...isIntFlag(c) ? { int: true } : {},
928
- ...c.isOptional ? { isOptional: true } : {},
929
- ...c.members ? { members: c.members } : {},
930
- ...c.fn ? { fn: c.fn } : {}
931
- };
932
- }
933
- function litC(v2) {
934
- const prim = typeof v2 === "number" ? "number" : typeof v2 === "string" ? "string" : typeof v2 === "boolean" ? "boolean" : void 0;
935
- return makeBuilder(prim, [eq(selfTerm(), lit(v2))]);
936
- }
937
- function asNestedConstraint(x, ctx) {
938
- if (isConstraint(x)) return toPlainConstraint(x);
939
- if (x === null || x === void 0 || typeof x === "number" || typeof x === "string" || typeof x === "boolean") {
940
- return toPlainConstraint(litC(x));
941
- }
942
- throw new Error(
943
- `nudo: ${ctx} expects a constraint value (number()/string()/\u2026) or a concrete literal; received a non-constraint`
944
- );
945
- }
946
- function union(...cs) {
947
- if (cs.length === 0)
948
- throw new Error("nudo union(): at least one member constraint is required");
949
- return makeBuilder(void 0, [], {
950
- members: cs.map((c) => asNestedConstraint(c, "union member"))
951
- });
952
- }
953
- function nullable(c) {
954
- return makeBuilder(void 0, [], {
955
- members: [
956
- asNestedConstraint(c, "nullable()"),
957
- toPlainConstraint(litC(null)),
958
- toPlainConstraint(litC(void 0))
959
- ]
960
- });
961
- }
962
- function constraintAdmitsNullish(c) {
963
- if (c.members) return c.members.some((m) => constraintAdmitsNullish(m));
964
- if (!c.prim && c.preds.length === 0 && !c.fields && !c.element && !c.fn) return true;
965
- for (const p of c.preds) {
966
- for (const flat of p.op === "and" ? p.args : [p]) {
967
- if (flat.op !== "eq") continue;
968
- for (const side of [flat.a, flat.b]) {
969
- if (side.op === "lit" && (side.value === null || side.value === void 0)) return true;
970
- }
971
- }
972
- }
973
- return false;
974
- }
975
- function fn(params, returns, opts) {
976
- const normalized = {};
977
- for (const [k, v2] of Object.entries(params)) {
978
- normalized[k] = asNestedConstraint(v2, `fn param '${k}'`);
979
- }
980
- return makeBuilder(void 0, [], {
981
- fn: {
982
- params: normalized,
983
- ...returns !== void 0 ? { returns: asNestedConstraint(returns, "fn return value") } : {},
984
- ...opts?.throws !== void 0 ? { throws: asNestedConstraint(opts.throws, "fn throws") } : {}
985
- }
986
- });
987
- }
988
- function andC(...cs) {
989
- if (cs.length === 0)
990
- throw new Error("nudo and(): at least one constraint is required");
991
- let prim;
992
- let isInt = false;
993
- let allOptional = true;
994
- const preds = [];
995
- for (const c of cs) {
996
- if (!isConstraint(c))
997
- throw new Error("nudo: expected a constraint value (number()/string()/\u2026 or a combinator)");
998
- if (c.fields || c.element || c.members || c.fn)
999
- throw new Error("nudo and(): Phase 1 supports scalar constraint conjunction only (shape/array/union/fn are not supported)");
1000
- if (c.prim) {
1001
- if (prim !== void 0 && prim !== c.prim)
1002
- throw new Error(`nudo and(): inconsistent prim (${prim} vs ${c.prim})`);
1003
- prim = c.prim;
1004
- }
1005
- preds.push(...c.preds);
1006
- if (isIntFlag(c)) isInt = true;
1007
- if (!c.isOptional) allOptional = false;
1008
- }
1009
- return makeBuilder(prim, preds, {
1010
- ...isInt ? { int: true } : {},
1011
- ...allOptional ? { optional: true } : {}
1012
- });
1013
- }
1014
- function partial(c) {
1015
- if (!isConstraint(c) || !c.fields)
1016
- throw new Error("nudo partial(): only shape(...) constraints are accepted");
1017
- const fields = {};
1018
- for (const [k, f] of Object.entries(c.fields)) {
1019
- fields[k] = {
1020
- constraint: { ...toPlainConstraint(f.constraint), isOptional: true },
1021
- optional: true
1022
- };
1023
- }
1024
- return makeBuilder(c.prim, c.preds, { fields });
1025
- }
1026
- function pick(c, keys) {
1027
- if (!isConstraint(c) || !c.fields)
1028
- throw new Error("nudo pick(): only shape(...) constraints are accepted");
1029
- const fields = {};
1030
- for (const k of keys) {
1031
- const f = c.fields[k];
1032
- if (f) fields[k] = f;
1033
- }
1034
- return makeBuilder(c.prim, c.preds, { fields });
1035
- }
1036
- function omit(c, keys) {
1037
- if (!isConstraint(c) || !c.fields)
1038
- throw new Error("nudo omit(): only shape(...) constraints are accepted");
1039
- const drop = new Set(keys);
1040
- const fields = {};
1041
- for (const [k, f] of Object.entries(c.fields)) {
1042
- if (!drop.has(k)) fields[k] = f;
1043
- }
1044
- return makeBuilder(c.prim, c.preds, { fields });
1045
- }
1046
- var CONSTRAINT_BUILDERS = {
1047
- number,
1048
- string,
1049
- boolean,
1050
- any,
1051
- array,
1052
- shape,
1053
- lit: litC,
1054
- union,
1055
- nullable,
1056
- fn,
1057
- and: andC,
1058
- partial,
1059
- pick,
1060
- omit
1061
- };
1062
- var CONSTRAINT_BUILDER_NAMES = Object.keys(
1063
- CONSTRAINT_BUILDERS
1064
- );
1065
- var CONSTRAINT_EXPR_RE = new RegExp(
1066
- `^(${CONSTRAINT_BUILDER_NAMES.join("|")})\\s*\\(`
1067
- );
1068
- function substTerm(t, paramName) {
1069
- if (t.op === "var" && t.id === SELF) return v(paramName);
1070
- if (t.op === "app" && t.fn === "get" && t.args.length === 2) {
1071
- return getTerm(substTerm(t.args[0], paramName), String(
1072
- t.args[1].op === "lit" ? t.args[1].value : ""
1073
- ));
1074
- }
1075
- return t;
1076
- }
1077
- function substPred(p, paramName) {
1078
- switch (p.op) {
1079
- case "gt":
1080
- case "ge":
1081
- case "lt":
1082
- case "le":
1083
- case "eq":
1084
- case "ne": {
1085
- return { op: p.op, a: substTerm(p.a, paramName), b: substTerm(p.b, paramName) };
1086
- }
1087
- case "typeof": {
1088
- return { op: "typeof", t: substTerm(p.t, paramName), type: p.type };
1089
- }
1090
- case "and":
1091
- return and(...p.args.map((x) => substPred(x, paramName)));
1092
- default:
1093
- return p;
1094
- }
1095
- }
1096
- function instantiateConstraint(c, paramName) {
1097
- if (c.fields) {
1098
- const parts = [];
1099
- for (const [key, field] of Object.entries(c.fields)) {
1100
- if (field.optional || field.constraint.isOptional) continue;
1101
- const fieldTerm = getTerm(v(paramName), key);
1102
- parts.push(instantiateOnTerm(field.constraint, fieldTerm));
1103
- }
1104
- if (c.prim) parts.push(ptypeof(v(paramName), primToTypeof(c.prim)));
1105
- if (parts.length === 0) return { op: "true" };
1106
- return parts.length === 1 ? parts[0] : and(...parts);
1107
- }
1108
- if (c.members) {
1109
- const disj = or(
1110
- ...c.members.map((m) => instantiateOnTerm(m, v(paramName)))
1111
- );
1112
- const own = c.preds.map((p) => substPred(p, paramName));
1113
- return own.length === 0 ? disj : and(...own, disj);
1114
- }
1115
- if (c.fn) {
1116
- const own = c.preds.map((p) => substPred(p, paramName));
1117
- return own.length === 0 ? pTrue : and(...own);
1118
- }
1119
- const preds = c.preds.map((p) => substPred(p, paramName));
1120
- if (c.prim && c.preds.length === 0) {
1121
- return ptypeof(v(paramName), primToTypeof(c.prim));
1122
- }
1123
- return preds.length === 0 ? { op: "true" } : preds.length === 1 ? preds[0] : and(...preds);
1124
- }
1125
- function instantiateOnTerm(c, t) {
1126
- const subst = (p) => {
1127
- switch (p.op) {
1128
- case "gt":
1129
- case "ge":
1130
- case "lt":
1131
- case "le":
1132
- case "eq":
1133
- case "ne": {
1134
- const a = p.a.op === "var" && p.a.id === SELF ? t : p.a;
1135
- const b = p.b.op === "var" && p.b.id === SELF ? t : p.b;
1136
- return { op: p.op, a, b };
1137
- }
1138
- case "typeof": {
1139
- const tt = p.t.op === "var" && p.t.id === SELF ? t : p.t;
1140
- return { op: "typeof", t: tt, type: p.type };
1141
- }
1142
- case "and":
1143
- return and(...p.args.map(subst));
1144
- default:
1145
- return p;
1146
- }
1147
- };
1148
- if (c.fields) {
1149
- const parts = [];
1150
- for (const [key, field] of Object.entries(c.fields)) {
1151
- if (field.optional || field.constraint.isOptional) continue;
1152
- parts.push(instantiateOnTerm(field.constraint, getTerm(t, key)));
1153
- }
1154
- if (parts.length === 0) return { op: "true" };
1155
- return parts.length === 1 ? parts[0] : and(...parts);
1156
- }
1157
- if (c.members) {
1158
- const disj = or(...c.members.map((m) => instantiateOnTerm(m, t)));
1159
- const own = c.preds.map(subst);
1160
- return own.length === 0 ? disj : and(...own, disj);
1161
- }
1162
- if (c.fn) {
1163
- const own = c.preds.map(subst);
1164
- return own.length === 0 ? pTrue : and(...own);
1165
- }
1166
- const preds = c.preds.map(subst);
1167
- if (c.prim && c.preds.length === 0) return ptypeof(t, primToTypeof(c.prim));
1168
- return preds.length === 0 ? { op: "true" } : preds.length === 1 ? preds[0] : and(...preds);
1169
- }
1170
- function constraintToEntryAbs(c, paramName) {
1171
- const t = v(paramName);
1172
- if (c.fields) {
1173
- const slots = {};
1174
- for (const [key, field] of Object.entries(c.fields)) {
1175
- const fieldTerm = getTerm(t, key);
1176
- slots[key] = {
1177
- value: constraintOnTermAbs(field.constraint, fieldTerm),
1178
- ...field.optional || field.constraint.isOptional ? { optional: true } : {}
1179
- };
1180
- }
1181
- return abs({ k: "obj", slots }, t, void 0, "path");
1182
- }
1183
- return constraintOnTermAbs(c, t);
1184
- }
1185
- function memberLitValue(m) {
1186
- const leaves = [];
1187
- const visit2 = (p2) => {
1188
- if (p2.op === "and") {
1189
- p2.args.forEach(visit2);
1190
- return;
1191
- }
1192
- leaves.push(p2);
1193
- };
1194
- m.preds.forEach(visit2);
1195
- if (leaves.length !== 1) return { ok: false };
1196
- const p = leaves[0];
1197
- if (p.op !== "eq") return { ok: false };
1198
- if (p.a.op === "var" && p.b.op === "lit") {
1199
- return { ok: true, v: p.b.value };
1200
- }
1201
- if (p.b.op === "var" && p.a.op === "lit") {
1202
- return { ok: true, v: p.a.value };
1203
- }
1204
- return { ok: false };
1205
- }
1206
- function samePrimLiteralUnionAbs(members, t) {
1207
- if (members.length === 0) return void 0;
1208
- const values = [];
1209
- let prim;
1210
- for (const m of members) {
1211
- const mk = memberLitValue(m);
1212
- if (!mk.ok) return void 0;
1213
- const v2 = mk.v;
1214
- if (v2 === void 0 || v2 === null) return void 0;
1215
- const mp = m.prim ?? (typeof v2 === "number" ? "number" : typeof v2 === "string" ? "string" : "boolean");
1216
- if (prim === void 0) prim = mp;
1217
- else if (prim !== mp) return void 0;
1218
- values.push(v2);
1219
- }
1220
- if (prim === void 0) return void 0;
1221
- const uniq = [];
1222
- for (const v2 of values) {
1223
- if (!uniq.some((u) => Object.is(u, v2))) uniq.push(v2);
1224
- }
1225
- const disj = or(
1226
- ...uniq.map((v2) => eq(t, lit(v2)))
1227
- );
1228
- return abs({ k: "prim", type: prim }, t, disj, "path");
1229
- }
1230
- function constraintOnTermAbs(c, t) {
1231
- if (c.fields) {
1232
- const slots = {};
1233
- for (const [key, field] of Object.entries(c.fields)) {
1234
- slots[key] = {
1235
- value: constraintOnTermAbs(field.constraint, getTerm(t, key)),
1236
- ...field.optional || field.constraint.isOptional ? { optional: true } : {}
1237
- };
1238
- }
1239
- return abs({ k: "obj", slots }, t, void 0, "path");
1240
- }
1241
- if (c.members) {
1242
- const litUnion = samePrimLiteralUnionAbs(c.members, t);
1243
- if (litUnion) return litUnion;
1244
- const joined = c.members.map((m) => constraintOnTermAbs(m, t)).reduce((a, b) => joinAbs(a, b));
1245
- if (joined.shape.k === "prim" && joined.pred === void 0 && c.members.every((m) => m.prim === joined.shape.type)) {
1246
- const type = joined.shape.type;
1247
- return abs({ k: "prim", type }, t, ptypeof(t, primToTypeof(type)), "path");
1248
- }
1249
- return joined;
1250
- }
1251
- if (c.fn) {
1252
- const paramNames = Object.keys(c.fn.params);
1253
- const paramTypes = paramNames.map(
1254
- (p, i) => constraintOnTermAbs(c.fn.params[p], v(`x${i}`))
1255
- );
1256
- const returnType = c.fn.returns ? constraintOnTermAbs(c.fn.returns, v("ret")) : unknown;
1257
- return abs(
1258
- { k: "fn", params: paramNames, paramTypes, returnType },
1259
- t,
1260
- void 0,
1261
- "path"
1262
- );
1263
- }
1264
- if (c.element) {
1265
- const elem = constraintOnTermAbs(c.element, v("x[]"));
1266
- return abs({ k: "arr", element: elem }, t, void 0, "path");
1267
- }
1268
- const pred = instantiateOnTerm(c, t);
1269
- const predOut = pred.op === "true" ? void 0 : pred;
1270
- if (c.prim) {
1271
- return abs({ k: "prim", type: c.prim }, t, predOut, "path");
1272
- }
1273
- const allEqNullish = c.preds.length > 0 && c.preds.every(
1274
- (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))
1275
- );
1276
- if (allEqNullish) {
1277
- let nullish = null;
1278
- for (const p of c.preds) {
1279
- if (p.op !== "eq") continue;
1280
- if (p.b.op === "lit" && (p.b.value === null || p.b.value === void 0)) {
1281
- nullish = p.b.value;
1282
- break;
1283
- }
1284
- if (p.a.op === "lit" && (p.a.value === null || p.a.value === void 0)) {
1285
- nullish = p.a.value;
1286
- break;
1287
- }
1288
- }
1289
- return abs({ k: "unknown" }, lit(nullish), void 0, "path");
1290
- }
1291
- if (c.preds.length > 0) {
1292
- return abs({ k: "prim", type: "number" }, t, predOut, "path");
1293
- }
1294
- return abs({ k: "any" }, t, void 0, "path");
1295
- }
1296
- function fnConstraintToEntryReqs(c) {
1297
- if (!c.fn) throw new Error("nudo fnConstraintToEntryReqs(): constraint is not in fn() form");
1298
- return Object.entries(c.fn.params).map(([param, constraint]) => ({
1299
- param,
1300
- constraint
1301
- }));
1302
- }
1303
- function throwConstraintToKinds(c) {
1304
- if (!c) return void 0;
1305
- const out = /* @__PURE__ */ new Set();
1306
- let any2 = false;
1307
- const note = (s) => {
1308
- if (s === "*" || s === "any") any2 = true;
1309
- else if (s) out.add(s);
1310
- };
1311
- const walk = (x) => {
1312
- if (x.members) {
1313
- for (const m of x.members) walk(m);
1314
- return;
1315
- }
1316
- for (const p of x.preds) {
1317
- if (p.op !== "eq" && p.op !== "ne") continue;
1318
- for (const side of [p.a, p.b]) {
1319
- if (side.op === "lit" && typeof side.value === "string") note(side.value);
1320
- }
1321
- }
1322
- };
1323
- walk(c);
1324
- if (any2) return "*";
1325
- if (out.size > 0) return [...out];
1326
- return void 0;
1327
- }
1328
-
1329
803
  // src/algebra/refine.ts
1330
804
  function diagnoseMalformedNudoImports(source) {
1331
805
  for (const bad of scanMalformedNudoImports(source)) {
@@ -1352,8 +826,8 @@ function extractNudoImports(source) {
1352
826
  var MAX_REFINE_DIAGS = 1024;
1353
827
  var refineDiagChannel = createScopedDiagChannel(MAX_REFINE_DIAGS);
1354
828
  registerCollectorScopeParticipant((body) => refineDiagChannel.runScoped(body));
1355
- function setRefineDiagCollector(fn2) {
1356
- refineDiagChannel.setCollector(fn2);
829
+ function setRefineDiagCollector(fn) {
830
+ refineDiagChannel.setCollector(fn);
1357
831
  }
1358
832
  function refineDiagCount() {
1359
833
  return refineDiagChannel.count();
@@ -1730,13 +1204,13 @@ function execSidecar(src, opts, chain, preloaded) {
1730
1204
  const body = `${prologue.length > 0 ? `${prologue.join("\n")}
1731
1205
  ` : ""}${code}
1732
1206
  return { ${returnObj} };`;
1733
- const fn2 = new Function(
1207
+ const fn = new Function(
1734
1208
  ...Object.keys(sidecarInjects),
1735
1209
  "__nudoInjects",
1736
1210
  "__nudoDeps",
1737
1211
  body
1738
1212
  );
1739
- return fn2(...Object.values(sidecarInjects), sidecarInjects, deps);
1213
+ return fn(...Object.values(sidecarInjects), sidecarInjects, deps);
1740
1214
  }
1741
1215
  function execNudoModule(src, opts) {
1742
1216
  return execNudoModuleCached(src, opts ?? {});
@@ -2250,8 +1724,8 @@ function regionHasGeneratedMarker(stmts, exportIdx, src) {
2250
1724
  var MAX_INTERFACE_DIAGS = 1024;
2251
1725
  var interfaceDiagChannel = createScopedDiagChannel(MAX_INTERFACE_DIAGS);
2252
1726
  registerCollectorScopeParticipant((body) => interfaceDiagChannel.runScoped(body));
2253
- function setInterfaceDiagCollector(fn2) {
2254
- interfaceDiagChannel.setCollector(fn2);
1727
+ function setInterfaceDiagCollector(fn) {
1728
+ interfaceDiagChannel.setCollector(fn);
2255
1729
  }
2256
1730
  function interfaceDiagCount() {
2257
1731
  return interfaceDiagChannel.count();
@@ -2512,11 +1986,11 @@ function crossBoundConflict(a, b) {
2512
1986
  if (x.value !== y.value) return true;
2513
1987
  }
2514
1988
  }
2515
- for (const eq2 of eqA) {
2516
- if (typeof eq2.value === "number" && boundExcludes(B, eq2.term, eq2.value)) return true;
1989
+ for (const eq of eqA) {
1990
+ if (typeof eq.value === "number" && boundExcludes(B, eq.term, eq.value)) return true;
2517
1991
  }
2518
- for (const eq2 of eqB) {
2519
- if (typeof eq2.value === "number" && boundExcludes(A, eq2.term, eq2.value)) return true;
1992
+ for (const eq of eqB) {
1993
+ if (typeof eq.value === "number" && boundExcludes(A, eq.term, eq.value)) return true;
2520
1994
  }
2521
1995
  return false;
2522
1996
  }
@@ -2712,9 +2186,9 @@ function predToChain(p) {
2712
2186
  [a, b],
2713
2187
  [b, a]
2714
2188
  ]) {
2715
- const ge2 = lengthBound(x, "ge");
2716
- const le2 = lengthBound(y, "le");
2717
- if (ge2 !== void 0 && ge2 === le2) return `.length(${ge2})`;
2189
+ const ge = lengthBound(x, "ge");
2190
+ const le = lengthBound(y, "le");
2191
+ if (ge !== void 0 && ge === le) return `.length(${ge})`;
2718
2192
  }
2719
2193
  }
2720
2194
  return p.args.map(predToChain).join("");
@@ -2724,24 +2198,29 @@ function predToChain(p) {
2724
2198
  }
2725
2199
  return `{${predToString(p)}}`;
2726
2200
  }
2727
- function fmtConstraint(c) {
2201
+ var LAZY_DISPLAY_DEPTH = 2;
2202
+ function fmtConstraint(c, depth = LAZY_DISPLAY_DEPTH) {
2203
+ if (c.lazy) {
2204
+ if (depth <= 0) return "\u2026";
2205
+ return fmtConstraint(derefConstraint(c), depth - 1);
2206
+ }
2728
2207
  if (c.fn) {
2729
2208
  const args = [
2730
- `{ ${Object.entries(c.fn.params).map(([k, v2]) => `${k}: ${fmtConstraint(v2)}`).join(", ")} }`
2209
+ `{ ${Object.entries(c.fn.params).map(([k, v2]) => `${k}: ${fmtConstraint(v2, depth)}`).join(", ")} }`
2731
2210
  ];
2732
- if (c.fn.returns !== void 0) args.push(fmtConstraint(c.fn.returns));
2733
- if (c.fn.throws !== void 0) args.push(`{ throws: ${fmtConstraint(c.fn.throws)} }`);
2211
+ if (c.fn.returns !== void 0) args.push(fmtConstraint(c.fn.returns, depth));
2212
+ if (c.fn.throws !== void 0) args.push(`{ throws: ${fmtConstraint(c.fn.throws, depth)} }`);
2734
2213
  return `fn(${args.join(", ")})`;
2735
2214
  }
2736
- if (c.members) return `union(${c.members.map(fmtConstraint).join(", ")})`;
2215
+ if (c.members) return `union(${c.members.map((m) => fmtConstraint(m, depth)).join(", ")})`;
2737
2216
  if (c.fields) {
2738
2217
  const fs = Object.entries(c.fields).map(([k, f]) => {
2739
2218
  const opt = f.optional || f.constraint.isOptional ? "?" : "";
2740
- return `${k}${opt}: ${fmtConstraint(f.constraint)}`;
2219
+ return `${k}${opt}: ${fmtConstraint(f.constraint, depth)}`;
2741
2220
  });
2742
2221
  return `shape({ ${fs.join(", ")} })`;
2743
2222
  }
2744
- if (c.element) return `array(${fmtConstraint(c.element)})`;
2223
+ if (c.element) return `array(${fmtConstraint(c.element, depth)})`;
2745
2224
  if (c.preds.length === 1 && c.preds[0].op === "eq" && c.preds[0].a.op === "var" && c.preds[0].b.op === "lit" && !isIntFlag(c)) {
2746
2225
  return `lit(${litToString(c.preds[0].b.value)})`;
2747
2226
  }
@@ -3361,8 +2840,8 @@ function alphaOfTerm(t, ctx) {
3361
2840
  }
3362
2841
  function rawTermOf(arg, ctx) {
3363
2842
  if (arg?.type === "Identifier") {
3364
- const lt2 = ctx.localTerms.get(arg.name);
3365
- if (lt2) return lt2;
2843
+ const lt = ctx.localTerms.get(arg.name);
2844
+ if (lt) return lt;
3366
2845
  if (ctx.paramTermId.has(arg.name)) {
3367
2846
  return v(ctx.paramTermId.get(arg.name));
3368
2847
  }
@@ -3374,22 +2853,22 @@ function rawTermOf(arg, ctx) {
3374
2853
  }
3375
2854
  function alphaTermOf(arg, ctx) {
3376
2855
  if (arg?.type === "Identifier") {
3377
- const lt2 = ctx.localTerms.get(arg.name);
3378
- if (lt2) return lt2;
2856
+ const lt = ctx.localTerms.get(arg.name);
2857
+ if (lt) return lt;
3379
2858
  if (ctx.paramTermId.has(arg.name)) {
3380
2859
  return v(ctx.paramTermId.get(arg.name));
3381
2860
  }
3382
2861
  }
3383
2862
  return alphaOfTerm(void 0, ctx);
3384
2863
  }
3385
- function promoteShape(ctx, param, shape2, loc, recordSite = true) {
2864
+ function promoteShape(ctx, param, shape, loc, recordSite = true) {
3386
2865
  const prev = ctx.shapes.get(param);
3387
2866
  if (!prev) return;
3388
2867
  if (prev.shape.k !== "any" && prev.shape.k !== "unknown") return;
3389
- const next = { shape: shape2, term: prev.term, pred: prev.pred, conf: "path" };
2868
+ const next = { shape, term: prev.term, pred: prev.pred, conf: "path" };
3390
2869
  ctx.shapes.set(param, next);
3391
- ctx.promotedShapes.set(param, shape2);
3392
- if (shape2.k === "fn") {
2870
+ ctx.promotedShapes.set(param, shape);
2871
+ if (shape.k === "fn") {
3393
2872
  if (!ctx.fnRels.has(param) && !ctx.entryShapes.has(param)) {
3394
2873
  ctx.fnRels.set(param, { abs: { ...next }, source: "promote" });
3395
2874
  }
@@ -3397,7 +2876,7 @@ function promoteShape(ctx, param, shape2, loc, recordSite = true) {
3397
2876
  ctx.sites.push({
3398
2877
  param,
3399
2878
  argTerms: [],
3400
- result: shape2.returnType ?? next,
2879
+ result: shape.returnType ?? next,
3401
2880
  loc
3402
2881
  });
3403
2882
  }
@@ -3684,12 +3163,12 @@ function evictGeneralizeMemoForPaths(paths) {
3684
3163
  }
3685
3164
  return n;
3686
3165
  }
3687
- function loadModuleId(fn2) {
3688
- if (!fn2) return 0;
3689
- let id = loadModuleIds.get(fn2);
3166
+ function loadModuleId(fn) {
3167
+ if (!fn) return 0;
3168
+ let id = loadModuleIds.get(fn);
3690
3169
  if (id === void 0) {
3691
3170
  id = nextLoadModuleId++;
3692
- loadModuleIds.set(fn2, id);
3171
+ loadModuleIds.set(fn, id);
3693
3172
  }
3694
3173
  return id;
3695
3174
  }
@@ -3934,9 +3413,9 @@ function extractFn(source, fnName, fileAst) {
3934
3413
  });
3935
3414
  formalsByName.set(scope.name, formals);
3936
3415
  }
3937
- const fn2 = env.fns.get(fnName);
3938
- if (!fn2) return void 0;
3939
- return { params: fn2.params, body: fn2.body, env, formals: formalsByName.get(fnName) ?? [] };
3416
+ const fn = env.fns.get(fnName);
3417
+ if (!fn) return void 0;
3418
+ return { params: fn.params, body: fn.body, env, formals: formalsByName.get(fnName) ?? [] };
3940
3419
  }
3941
3420
  function generalizeFromAst(fnName, source, opts = {}) {
3942
3421
  const { key, depPaths, truncated } = generalizeMemoKey(fnName, source, opts);
@@ -4099,9 +3578,9 @@ function generalizeFromAstUncached(fnName, source, opts = {}) {
4099
3578
  return void 0;
4100
3579
  } else if (fnName in evalRun) {
4101
3580
  const evalArgs = args.map((a, i) => {
4102
- const shape2 = promoteScan.promotedShapes.get(params[i]);
4103
- if (shape2 && (a.shape.k === "any" || a.shape.k === "unknown")) {
4104
- return { shape: shape2, term: a.term, pred: a.pred, conf: "path" };
3581
+ const shape = promoteScan.promotedShapes.get(params[i]);
3582
+ if (shape && (a.shape.k === "any" || a.shape.k === "unknown")) {
3583
+ return { shape, term: a.term, pred: a.pred, conf: "path" };
4105
3584
  }
4106
3585
  return a;
4107
3586
  });
@@ -4288,92 +3767,6 @@ function buildArgsFromAssume(source, fnName, assumeIds) {
4288
3767
  });
4289
3768
  }
4290
3769
 
4291
- // src/algebra/domain-membership.ts
4292
- function literalMeetsConstraint(lv, c) {
4293
- const ext = c;
4294
- if (c.fields || c.element) return false;
4295
- if (ext.fn) return false;
4296
- if (Array.isArray(ext.members) && ext.members.length > 0) {
4297
- return ext.members.some((m) => literalMeetsConstraint(lv, m));
4298
- }
4299
- if (c.prim === void 0) {
4300
- return c.preds.every((p) => predHolds(lv, p));
4301
- }
4302
- if (!primMatches(c.prim, lv)) return false;
4303
- if (isIntFlag(c) && c.prim === "number" && !(typeof lv === "number" && Number.isInteger(lv))) {
4304
- return false;
4305
- }
4306
- return c.preds.every((p) => predHolds(lv, p));
4307
- }
4308
- function primMatches(prim, lv) {
4309
- switch (prim) {
4310
- case "number":
4311
- return typeof lv === "number";
4312
- case "string":
4313
- return typeof lv === "string";
4314
- case "boolean":
4315
- return typeof lv === "boolean";
4316
- case "object":
4317
- return lv === null;
4318
- case "undefined":
4319
- return lv === void 0;
4320
- default:
4321
- return false;
4322
- }
4323
- }
4324
- function predHolds(lv, p) {
4325
- switch (p.op) {
4326
- case "eq": {
4327
- const litT = isSelfVar(p.a) && p.b.op === "lit" ? p.b : isSelfVar(p.b) && p.a.op === "lit" ? p.a : void 0;
4328
- if (!litT) return false;
4329
- return Object.is(lv, litT.value);
4330
- }
4331
- case "gt":
4332
- case "ge":
4333
- case "lt":
4334
- case "le":
4335
- return boundHolds(lv, p);
4336
- case "typeof":
4337
- return p.t.op === "var" && p.t.id === SELF && primMatches(p.type, lv);
4338
- // and 是合取:逐参数按同一规则判定(string().length(n) 的 preds 是
4339
- // and 包裹的两个长度界,叶子仍是 gt/ge/lt/le,无假阳性风险)
4340
- case "and":
4341
- return p.args.every((x) => predHolds(lv, x));
4342
- // ne / or / not / true / false 等其余形态:保守不满足
4343
- default:
4344
- return false;
4345
- }
4346
- }
4347
- function cmpHolds(x, op, n) {
4348
- switch (op) {
4349
- case "gt":
4350
- return x > n;
4351
- case "ge":
4352
- return x >= n;
4353
- case "lt":
4354
- return x < n;
4355
- case "le":
4356
- return x <= n;
4357
- }
4358
- }
4359
- function boundHolds(lv, p) {
4360
- if (p.b.op !== "lit" || typeof p.b.value !== "number") return false;
4361
- const n = p.b.value;
4362
- if (isLengthSelf(p.a)) {
4363
- return typeof lv === "string" && cmpHolds(lv.length, p.op, n);
4364
- }
4365
- if (isSelfVar(p.a)) {
4366
- return typeof lv === "number" && cmpHolds(lv, p.op, n);
4367
- }
4368
- return false;
4369
- }
4370
- function isSelfVar(t) {
4371
- return t.op === "var" && t.id === SELF;
4372
- }
4373
- function isLengthSelf(t) {
4374
- return t.op === "app" && t.fn === "length" && t.args.length === 1 && isSelfVar(t.args[0]);
4375
- }
4376
-
4377
3770
  // src/algebra/stable-source-key.ts
4378
3771
  function stableAnalyzeKeySource(source) {
4379
3772
  let end = source.length;
@@ -4608,9 +4001,9 @@ function checkInjectedDomainEvidence(fnName, source, records, opts) {
4608
4001
  if (idx < 0) continue;
4609
4002
  const failures = [];
4610
4003
  for (const rec of usable) {
4611
- const lit2 = extractLiteralEvidence(rec, idx);
4612
- if (lit2 === void 0) continue;
4613
- if (!literalMeetsConstraint(lit2, constraint)) failures.push(lit2);
4004
+ const lit = extractLiteralEvidence(rec, idx);
4005
+ if (lit === void 0) continue;
4006
+ if (!literalMeetsConstraint(lit, constraint)) failures.push(lit);
4614
4007
  }
4615
4008
  if (failures.length === 0) continue;
4616
4009
  const shown = [...new Set(failures)].map(evidenceToString).join(", ");
@@ -5213,16 +4606,16 @@ function scanLiteralCalls(source, knownFns, phi, opts) {
5213
4606
  }
5214
4607
  if (p.op === "or") {
5215
4608
  let pass = false;
5216
- let unknown3 = false;
4609
+ let unknown2 = false;
5217
4610
  for (const q of p.args) {
5218
4611
  const r = judgeLiteralPred(q, lv, strLen);
5219
4612
  if (r === true) {
5220
4613
  pass = true;
5221
4614
  break;
5222
4615
  }
5223
- if (r === void 0) unknown3 = true;
4616
+ if (r === void 0) unknown2 = true;
5224
4617
  }
5225
- if (!pass && !unknown3) {
4618
+ if (!pass && !unknown2) {
5226
4619
  out.push({
5227
4620
  severity: "error",
5228
4621
  code: "nudo:constraint-violated",
@@ -5884,34 +5277,6 @@ export {
5884
5277
  sidecarPathOf,
5885
5278
  createDiagChannel,
5886
5279
  createScopedDiagChannel,
5887
- SELF,
5888
- getTerm,
5889
- lenTerm,
5890
- isNudoConstraint,
5891
- isIntFlag,
5892
- number,
5893
- string,
5894
- boolean,
5895
- any,
5896
- array,
5897
- shape,
5898
- litC,
5899
- union,
5900
- nullable,
5901
- constraintAdmitsNullish,
5902
- fn,
5903
- andC,
5904
- partial,
5905
- pick,
5906
- omit,
5907
- CONSTRAINT_BUILDERS,
5908
- CONSTRAINT_BUILDER_NAMES,
5909
- CONSTRAINT_EXPR_RE,
5910
- instantiateConstraint,
5911
- instantiateOnTerm,
5912
- constraintToEntryAbs,
5913
- fnConstraintToEntryReqs,
5914
- throwConstraintToKinds,
5915
5280
  extractNudoImports,
5916
5281
  setRefineDiagCollector,
5917
5282
  refineDiagCount,
@@ -5957,7 +5322,6 @@ export {
5957
5322
  generalizeAll,
5958
5323
  listFunctionNames,
5959
5324
  buildArgsFromAssume,
5960
- literalMeetsConstraint,
5961
5325
  stableAnalyzeKeySource,
5962
5326
  listTopFunctions,
5963
5327
  scanLiteralCalls,