@nudojs/core 1.3.0 → 1.4.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.
package/dist/index.js CHANGED
@@ -1,5 +1,8 @@
1
1
  import "./chunk-US532PZA.js";
2
2
  import {
3
+ CONSTRAINT_BUILDERS,
4
+ CONSTRAINT_BUILDER_NAMES,
5
+ CONSTRAINT_EXPR_RE,
3
6
  NudoSidecarError,
4
7
  SELF,
5
8
  andC,
@@ -14,14 +17,20 @@ import {
14
17
  effectiveInterface,
15
18
  evictGeneralizeMemoForPaths,
16
19
  execNudoModule,
20
+ extractBalancedParens,
17
21
  extractDeclaredThrows,
22
+ extractFileEnvNames,
18
23
  extractFn,
19
24
  extractFnBudget,
25
+ extractMockModuleRecords,
26
+ extractNudoImportRecords,
20
27
  extractNudoImports,
21
28
  extractRefineReturnFromSource,
22
29
  extractRefinesFromSource,
30
+ findFnDirectiveScope,
23
31
  fn,
24
32
  fnConstraintToEntryReqs,
33
+ fnDirectiveCommentLines,
25
34
  formatConstraint,
26
35
  formatEffectiveInterfaceDisplay,
27
36
  formatInterfaceTierLine,
@@ -40,6 +49,7 @@ import {
40
49
  isNodeModulesPath,
41
50
  isNudoConstraint,
42
51
  lenTerm,
52
+ listFnDirectiveScopes,
43
53
  listFunctionNames,
44
54
  listTopFunctions,
45
55
  litC,
@@ -50,6 +60,9 @@ import {
50
60
  nullable,
51
61
  number,
52
62
  omit,
63
+ parseEnvPayload,
64
+ parseMockModulePayload,
65
+ parseNudoImportPayload,
53
66
  partial,
54
67
  pick,
55
68
  refineDiagCount,
@@ -58,13 +71,19 @@ import {
58
71
  resetHashSourceCache,
59
72
  resetNudoModuleExecCache,
60
73
  resetSidecarLoadFailureCache,
74
+ scanBudgetDecl,
75
+ scanCaseArgSpans,
76
+ scanCaseTags,
77
+ scanContractSegments,
61
78
  scanLiteralCalls,
79
+ scanThrowsDecl,
62
80
  setInterfaceDiagCollector,
63
81
  setRefineDiagCollector,
64
82
  shape,
65
83
  sidecarClosureFingerprint,
66
84
  sidecarPathOf,
67
85
  stableAnalyzeKeySource,
86
+ stablePathKey,
68
87
  string,
69
88
  takeInterfaceDiags,
70
89
  takeInterfaceDiagsSince,
@@ -72,7 +91,7 @@ import {
72
91
  takeRefineDiagsSince,
73
92
  throwConstraintToKinds,
74
93
  union
75
- } from "./chunk-5YNR4Q7E.js";
94
+ } from "./chunk-7QUVTEYZ.js";
76
95
  import {
77
96
  $add,
78
97
  $arguments,
@@ -200,6 +219,7 @@ import {
200
219
  TYPEOF_NAMES,
201
220
  abs,
202
221
  absFunction,
222
+ absOnly,
203
223
  absShapeKey,
204
224
  absToString,
205
225
  add,
@@ -231,6 +251,7 @@ import {
231
251
  callAbsMethod,
232
252
  callAtFunctionBoundary,
233
253
  callTranspiledExport,
254
+ callTranspiledExportApply,
234
255
  callTranspiledExportFull,
235
256
  canonicalArrayIndex,
236
257
  clearBClasses,
@@ -309,6 +330,7 @@ import {
309
330
  identBoundaryRegex,
310
331
  implies,
311
332
  instantiateReturn,
333
+ isAbsApplyResult,
312
334
  isArrMutator,
313
335
  isBigPrim,
314
336
  isDefinitelyFalse,
@@ -345,6 +367,7 @@ import {
345
367
  looseEqAbs,
346
368
  lt,
347
369
  ltNum,
370
+ makeAbsApplyResult,
348
371
  makeArrayCtorAbs,
349
372
  makeMapAbs,
350
373
  makeSetAbs,
@@ -484,7 +507,7 @@ import {
484
507
  v,
485
508
  withExecPhi,
486
509
  withVar
487
- } from "./chunk-CKH6GQAI.js";
510
+ } from "./chunk-LFCF6BLE.js";
488
511
 
489
512
  // src/environment.ts
490
513
  function createEnvironment(parent, bindings = /* @__PURE__ */ new Map()) {
@@ -613,15 +636,15 @@ function checkArg(arg, expect, phi = pTrue) {
613
636
  }
614
637
  const combined = arg.pred && arg.pred.op !== "true" ? phi.op === "true" ? arg.pred : { op: "and", args: [phi, arg.pred] } : phi;
615
638
  if (implies(combined, expect)) return void 0;
616
- const lv = litValue(arg);
617
- if (lv !== void 0 && (expect.op === "gt" || expect.op === "ge" || expect.op === "lt" || expect.op === "le")) {
618
- const ok = decideLitCmp(lv, expect);
639
+ const lvR = litValue(arg);
640
+ if (lvR.ok && (expect.op === "gt" || expect.op === "ge" || expect.op === "lt" || expect.op === "le")) {
641
+ const ok = decideLitCmp(lvR.value, expect);
619
642
  if (ok === true) return void 0;
620
643
  if (ok === false) {
621
644
  return {
622
645
  severity: "error",
623
646
  code: "nudo:constraint-violated",
624
- message: `argument ${JSON.stringify(lv)} does not satisfy ${predToString(expect)}`,
647
+ message: `argument ${JSON.stringify(lvR.value)} does not satisfy ${predToString(expect)}`,
625
648
  suggestion: `use a value satisfying the constraint, or relax the function precondition`
626
649
  };
627
650
  }
@@ -778,7 +801,7 @@ function assertImplies(ret, constraint, opts) {
778
801
  }
779
802
  return sawUnprovable ? unprovable("union: no member proved the return contract") : disproved(`return \u22AD union(${constraint.members.map((m) => formatConstraint(m)).join(", ")})`);
780
803
  }
781
- if (sumMembers && constraint.fields) {
804
+ if (sumMembers && (constraint.fields || constraint.element)) {
782
805
  let sawUnprovable = false;
783
806
  for (const m of sumMembers) {
784
807
  if (isValueSetUnknown(m)) continue;
@@ -838,13 +861,18 @@ function assertScalar(ret, constraint, phi) {
838
861
  if (retPrim && retPrim !== constraint.prim) {
839
862
  return disproved(`typeof return = "${retPrim}" \u22AD "${constraint.prim}"`);
840
863
  }
841
- if (!retPrim && ret.shape.k !== "sum" && ret.shape.k !== "never") {
864
+ if (!retPrim) {
865
+ const k = ret.shape.k;
866
+ if (k === "obj" || k === "arr" || k === "tuple" || k === "fn" || k === "brand" || k === "eff") {
867
+ return disproved(`return shape ${k} \u22AD prim "${constraint.prim}"`);
868
+ }
842
869
  }
843
870
  }
844
871
  if (isIntFlag(constraint) && constraint.prim === "number") {
845
- const lv2 = litValue(ret);
846
- if (typeof lv2 === "number" && !Number.isInteger(lv2)) {
847
- return disproved(`return ${lv2} \u22AD int`);
872
+ const lvR = litValue(ret);
873
+ const lv = lvR.ok ? lvR.value : void 0;
874
+ if (typeof lv === "number" && !Number.isInteger(lv)) {
875
+ return disproved(`return ${lv} \u22AD int`);
848
876
  }
849
877
  }
850
878
  const t = retAnchorTerm(ret);
@@ -867,18 +895,17 @@ function assertScalar(ret, constraint, phi) {
867
895
  );
868
896
  }
869
897
  }
870
- const lv = litValue(ret);
871
- if (lv !== void 0 && (typeof lv === "number" || typeof lv === "string" || typeof lv === "boolean" || lv === null)) {
872
- if (literalMeetsConstraint(lv, constraint)) {
873
- return proved();
898
+ if (ret.term?.op === "lit") {
899
+ const lv = ret.term.value;
900
+ if (typeof lv === "number" || typeof lv === "string" || typeof lv === "boolean" || lv === null || lv === void 0) {
901
+ if (literalMeetsConstraint(lv, constraint)) {
902
+ return proved();
903
+ }
904
+ const boundDesc = describeBoundViolation(lv, constraint);
905
+ return disproved(
906
+ boundDesc ?? `return ${JSON.stringify(lv)} \u22AD ${formatConstraint(constraint)}`
907
+ );
874
908
  }
875
- const boundDesc = describeBoundViolation(lv, constraint);
876
- return disproved(
877
- boundDesc ?? `return ${JSON.stringify(lv)} \u22AD ${formatConstraint(constraint)}`
878
- );
879
- }
880
- if (ret.term?.op === "lit" && ret.term.value === void 0) {
881
- return proved();
882
909
  }
883
910
  if (constraintPred.op !== "true" || constraint.preds.length > 0) {
884
911
  if (isBoundedEvidenceMissing(ret, constraint)) {
@@ -924,7 +951,8 @@ function litLE(a, b) {
924
951
  }
925
952
  function primOfAbs(a) {
926
953
  if (a.shape.k === "prim") return a.shape.type;
927
- const lv = litValue(a);
954
+ const lvR = litValue(a);
955
+ const lv = lvR.ok ? lvR.value : void 0;
928
956
  if (typeof lv === "number") return "number";
929
957
  if (typeof lv === "string") return "string";
930
958
  if (typeof lv === "boolean") return "boolean";
@@ -1513,7 +1541,7 @@ function unindexCheckKey(key) {
1513
1541
  function evictCheckSourceMemoForPaths(paths) {
1514
1542
  let n = 0;
1515
1543
  for (const raw of paths) {
1516
- const p = normPath(raw);
1544
+ const p = stablePathKey(raw);
1517
1545
  const keys = checkDepIndex.get(p);
1518
1546
  if (!keys) continue;
1519
1547
  for (const key of [...keys]) {
@@ -1589,8 +1617,9 @@ function checkMemoSet(key, value, depPaths) {
1589
1617
  }
1590
1618
  checkReportMemo.set(key, value);
1591
1619
  if (depPaths.length > 0) {
1592
- checkKeyDeps.set(key, depPaths);
1593
- for (const p of depPaths) {
1620
+ const normDeps = [...new Set(depPaths.map(stablePathKey))];
1621
+ checkKeyDeps.set(key, normDeps);
1622
+ for (const p of normDeps) {
1594
1623
  let set = checkDepIndex.get(p);
1595
1624
  if (!set) {
1596
1625
  set = /* @__PURE__ */ new Set();
@@ -1915,13 +1944,14 @@ function scanCaseInconsistency(source, knownFns, opts) {
1915
1944
  }
1916
1945
  arg = projected;
1917
1946
  }
1918
- const lv = litValue(arg);
1919
- if (lv === void 0 || typeof lv !== "number" && typeof lv !== "string" && typeof lv !== "boolean") {
1947
+ const argLit = arg.term?.op === "lit" ? arg.term.value : void 0;
1948
+ const argIsLit = arg.term?.op === "lit";
1949
+ if (!argIsLit || typeof argLit !== "number" && typeof argLit !== "string" && typeof argLit !== "boolean" && argLit !== null && argLit !== void 0) {
1920
1950
  continue;
1921
1951
  }
1922
1952
  const hasEqOr = (entry.constraint.members?.length ?? 0) > 0 || entry.constraint.preds.some((p) => p.op === "eq");
1923
1953
  if (hasEqOr) {
1924
- if (!literalMeetsConstraint(lv, entry.constraint)) {
1954
+ if (!literalMeetsConstraint(argLit, entry.constraint)) {
1925
1955
  const paramName = entry.param || paramNames[idx] || `arg${idx}`;
1926
1956
  out.push({
1927
1957
  severity: "error",
@@ -1936,16 +1966,16 @@ function scanCaseInconsistency(source, knownFns, opts) {
1936
1966
  }
1937
1967
  continue;
1938
1968
  }
1939
- if (typeof lv !== "number") continue;
1969
+ if (typeof argLit !== "number") continue;
1940
1970
  const flatten = (p) => p.op === "and" ? p.args.flatMap(flatten) : p.op === "true" ? [] : [p];
1941
1971
  for (const p of flatten(entry.pred)) {
1942
1972
  if ((p.op === "gt" || p.op === "ge" || p.op === "lt" || p.op === "le") && p.b.op === "lit" && typeof p.b.value === "number") {
1943
1973
  const n = p.b.value;
1944
1974
  let ok = true;
1945
- if (p.op === "gt") ok = lv > n;
1946
- if (p.op === "ge") ok = lv >= n;
1947
- if (p.op === "lt") ok = lv < n;
1948
- if (p.op === "le") ok = lv <= n;
1975
+ if (p.op === "gt") ok = argLit > n;
1976
+ if (p.op === "ge") ok = argLit >= n;
1977
+ if (p.op === "lt") ok = argLit < n;
1978
+ if (p.op === "le") ok = argLit <= n;
1949
1979
  if (!ok) {
1950
1980
  const paramName = entry.param || paramNames[idx] || `arg${idx}`;
1951
1981
  out.push({
@@ -1963,36 +1993,18 @@ function scanCaseInconsistency(source, knownFns, opts) {
1963
1993
  }
1964
1994
  }
1965
1995
  };
1966
- const visit = (n) => {
1967
- if (!n || typeof n !== "object") return;
1968
- const obj2 = n;
1969
- let decl = obj2;
1970
- if (obj2.type === "ExportNamedDeclaration" || obj2.type === "ExportDefaultDeclaration") {
1971
- decl = obj2.declaration;
1972
- }
1973
- if (decl && (decl.type === "FunctionDeclaration" || decl.type === "VariableDeclaration" && (decl.declarations ?? [])[0]?.init && ["ArrowFunctionExpression", "FunctionExpression"].includes(
1974
- String(
1975
- decl.declarations[0].init.type
1976
- )
1977
- ))) {
1978
- const id = decl.type === "FunctionDeclaration" ? decl.id?.name : decl.declarations[0]?.id?.name;
1979
- if (id && knownFns.includes(id)) {
1980
- for (const c of obj2.leadingComments ?? []) {
1981
- const caseArgs = parseCaseArgs(c.value);
1982
- if (!caseArgs) continue;
1983
- const caseName = /@nudo:case\s+"([^"]+)"/.exec(c.value)?.[1] ?? "?";
1984
- checkCaseAgainstReqs(id, caseName, caseArgs, c.loc?.start.line);
1985
- }
1996
+ for (const scope of listFnDirectiveScopes(file)) {
1997
+ if (!knownFns.includes(scope.name)) continue;
1998
+ for (let ci = 0; ci < scope.commentTexts.length; ci++) {
1999
+ const text = scope.commentTexts[ci];
2000
+ const startLine = scope.commentStartLines[ci] ?? 0;
2001
+ for (const tag of scanCaseTags(text)) {
2002
+ const caseArgs = parseCaseArgs(`@nudo:case "${tag.name}" (${tag.argsText})`);
2003
+ if (!caseArgs) continue;
2004
+ checkCaseAgainstReqs(scope.name, tag.name, caseArgs, startLine);
1986
2005
  }
1987
2006
  }
1988
- for (const key of Object.keys(obj2)) {
1989
- if (key === "loc" || key === "start" || key === "end" || key === "leadingComments") continue;
1990
- const val = obj2[key];
1991
- if (Array.isArray(val)) val.forEach(visit);
1992
- else if (val && typeof val === "object") visit(val);
1993
- }
1994
- };
1995
- visit(file);
2007
+ }
1996
2008
  return out;
1997
2009
  }
1998
2010
 
@@ -2085,7 +2097,8 @@ function sidecarDiagIssues(diags) {
2085
2097
  const k = `${d.code}\0${d.message}`;
2086
2098
  if (seen.has(k)) continue;
2087
2099
  seen.add(k);
2088
- out.push({ severity: "error", code: d.code, message: d.message });
2100
+ const severity = d.code === "nudo:contract-syntax" || d.code === "nudo:directive-syntax" ? "warning" : "error";
2101
+ out.push({ severity, code: d.code, message: d.message });
2089
2102
  }
2090
2103
  return out;
2091
2104
  }
@@ -2979,6 +2992,9 @@ export {
2979
2992
  $while,
2980
2993
  $whileSeq,
2981
2994
  $yield,
2995
+ CONSTRAINT_BUILDERS,
2996
+ CONSTRAINT_BUILDER_NAMES,
2997
+ CONSTRAINT_EXPR_RE,
2982
2998
  DEFAULT_MAX_LOOP_ITERS,
2983
2999
  MAX_EVAL_CALL_DEPTH,
2984
3000
  MAX_EVAL_TOTAL_CALLS,
@@ -2993,6 +3009,7 @@ export {
2993
3009
  TYPEOF_NAMES,
2994
3010
  abs,
2995
3011
  absFunction,
3012
+ absOnly,
2996
3013
  absShapeKey,
2997
3014
  absToConstraint,
2998
3015
  absToString,
@@ -3031,6 +3048,7 @@ export {
3031
3048
  callAbsMethod,
3032
3049
  callAtFunctionBoundary,
3033
3050
  callTranspiledExport,
3051
+ callTranspiledExportApply,
3034
3052
  callTranspiledExportFull,
3035
3053
  canonicalArrayIndex,
3036
3054
  checkArg,
@@ -3090,16 +3108,22 @@ export {
3090
3108
  evictGeneralizeMemoForPaths,
3091
3109
  execNudoModule,
3092
3110
  extStateOf,
3111
+ extractBalancedParens,
3093
3112
  extractDeclaredThrows,
3113
+ extractFileEnvNames,
3094
3114
  extractFn,
3095
3115
  extractFnBudget,
3116
+ extractMockModuleRecords,
3117
+ extractNudoImportRecords,
3096
3118
  extractNudoImports,
3097
3119
  extractRefineReturnFromSource,
3098
3120
  extractRefinesFromSource,
3099
3121
  falseConstraint,
3100
3122
  fillTuple,
3123
+ findFnDirectiveScope,
3101
3124
  fn,
3102
3125
  fnConstraintToEntryReqs,
3126
+ fnDirectiveCommentLines,
3103
3127
  fnOf,
3104
3128
  foldRequireSpecArg,
3105
3129
  foldStaticStringExpr,
@@ -3141,6 +3165,7 @@ export {
3141
3165
  interfaceDiagCount,
3142
3166
  interfaceSourceOf,
3143
3167
  interfaceTierOf,
3168
+ isAbsApplyResult,
3144
3169
  isArrMutator,
3145
3170
  isBigPrim,
3146
3171
  isDefinitelyFalse,
@@ -3174,6 +3199,7 @@ export {
3174
3199
  leavePromiseExecutorScope,
3175
3200
  lenTerm,
3176
3201
  leqAbs,
3202
+ listFnDirectiveScopes,
3177
3203
  listFunctionNames,
3178
3204
  lit,
3179
3205
  litC,
@@ -3186,6 +3212,7 @@ export {
3186
3212
  looseEqAbs,
3187
3213
  lt,
3188
3214
  ltNum,
3215
+ makeAbsApplyResult,
3189
3216
  makeArrayCtorAbs,
3190
3217
  makeMapAbs,
3191
3218
  makeSetAbs,
@@ -3235,6 +3262,9 @@ export {
3235
3262
  or,
3236
3263
  pFalse,
3237
3264
  pTrue,
3265
+ parseEnvPayload,
3266
+ parseMockModulePayload,
3267
+ parseNudoImportPayload,
3238
3268
  parseSource,
3239
3269
  partial,
3240
3270
  phiAnd,
@@ -3277,6 +3307,11 @@ export {
3277
3307
  runTranspiledOptionsMemoKey,
3278
3308
  runWithLoopExits,
3279
3309
  runtimeImportOf,
3310
+ scanBudgetDecl,
3311
+ scanCaseArgSpans,
3312
+ scanCaseTags,
3313
+ scanContractSegments,
3314
+ scanThrowsDecl,
3280
3315
  serializeCheckJson,
3281
3316
  serializeCheckJsonMulti,
3282
3317
  setAddEntry,
@@ -1,7 +1,7 @@
1
- import { I as InterfaceSource, a as InterfaceTierOpts, p as parseSource, C as CheckIssue } from './check-report-BWmfy810.js';
2
- export { L as LeakBudget, b as LoadDepsFingerprint, M as MAX_PROMISE_MICROS, d as defaultLeakBudget, e as exceedsBudget, c as extractAllLoadSpecs, g as getPromiseMicrosLength, l as leakIfNeeded, f as loadModuleDepsFingerprint, m as maybeLeak, n as normPath, r as resetLeakCounter, h as resolveDepPath, s as sidecarSpecsOf, t as termDepth, i as termNodes } from './check-report-BWmfy810.js';
3
- import { A as Abs, T as Term, c as AstEnv } from './run-Dk08Q5zl.js';
4
- export { $ as $tryDigestSoft, d as $tryMarkSoft, e as $tryReleaseSoft, E as ERROR_FAMILY, f as EvalFallbackStats, M as MayThrowEffect, g as enterEvalCallBudgetSession, h as errorTypeAbs, i as exitEvalCallBudgetSession, j as filterDeclaredThrows, k as filterGateThrows, l as filterIgnoredThrows, m as flushMayThrowEffects, n as formatThrowsAbs, o as getEvalCallBudgetState, p as getEvalFallbackStats, q as getMayThrowCollector, r as isThrowsIgnored, s as mayThrowEffectsToAbs, t as orphanMayThrowEffects, u as popMayThrowFrame, v as pushMayThrowFrame, w as recordMayThrow, x as resetEvalFallbackStats, y as runWithMayThrowSession, z as setMayThrowCollector, B as throwAbsToKinds, D as throwsKindCovered, F as withEvalBudgetOverride } from './run-Dk08Q5zl.js';
1
+ import { I as InterfaceSource, a as InterfaceTierOpts, p as parseSource, C as CheckIssue } from './check-report-Ci1dDysO.js';
2
+ export { L as LeakBudget, b as LoadDepsFingerprint, M as MAX_PROMISE_MICROS, d as defaultLeakBudget, e as exceedsBudget, c as extractAllLoadSpecs, g as getPromiseMicrosLength, l as leakIfNeeded, f as loadModuleDepsFingerprint, m as maybeLeak, n as normPath, r as resetLeakCounter, h as resolveDepPath, s as sidecarSpecsOf, i as stablePathKey, j as stablePathKeyGraph, t as termDepth, k as termNodes } from './check-report-Ci1dDysO.js';
3
+ import { A as Abs, T as Term, c as AstEnv } from './run-WJfj477N.js';
4
+ export { $ as $tryDigestSoft, d as $tryMarkSoft, e as $tryReleaseSoft, E as ERROR_FAMILY, f as EvalFallbackStats, M as MayThrowEffect, g as clearPureCallMemo, h as clearPureMemo, i as enterEvalCallBudgetSession, j as errorTypeAbs, k as exitEvalCallBudgetSession, l as filterDeclaredThrows, m as filterGateThrows, n as filterIgnoredThrows, o as flushMayThrowEffects, p as formatThrowsAbs, q as getEvalCallBudgetState, r as getEvalFallbackStats, s as getMayThrowCollector, t as isThrowsIgnored, u as mayThrowEffectsToAbs, v as orphanMayThrowEffects, w as popMayThrowFrame, x as pushMayThrowFrame, y as recordMayThrow, z as resetEvalFallbackStats, B as runWithMayThrowSession, D as setMayThrowCollector, F as throwAbsToKinds, G as throwsKindCovered, H as withEvalBudgetOverride } from './run-WJfj477N.js';
5
5
  import { File, Node } from '@babel/types';
6
6
 
7
7
  /**
package/dist/internal.js CHANGED
@@ -15,8 +15,10 @@ import {
15
15
  resetHashSourceCache,
16
16
  resolveDepPath,
17
17
  sidecarSpecsOf,
18
- stableAnalyzeKeySource
19
- } from "./chunk-5YNR4Q7E.js";
18
+ stableAnalyzeKeySource,
19
+ stablePathKey,
20
+ stablePathKeyGraph
21
+ } from "./chunk-7QUVTEYZ.js";
20
22
  import {
21
23
  $tryDigestSoft,
22
24
  $tryMarkSoft,
@@ -41,6 +43,8 @@ import {
41
43
  callBudgetKey,
42
44
  classChainNames,
43
45
  classFromMethods,
46
+ clearPureCallMemo,
47
+ clearPureMemo,
44
48
  coerceAsyncReturn,
45
49
  concatString,
46
50
  createTemplateAbs,
@@ -153,7 +157,7 @@ import {
153
157
  withEvalBudgetOverride,
154
158
  withFnBudgetOverride,
155
159
  wrapPromise
156
- } from "./chunk-CKH6GQAI.js";
160
+ } from "./chunk-LFCF6BLE.js";
157
161
 
158
162
  // src/algebra/inlay.ts
159
163
  function listFunctions(source) {
@@ -211,12 +215,13 @@ function formatReturnDisplay(g) {
211
215
  const t = stripParens(renameTypeVars(termToString(m.term), varMap));
212
216
  return { key: `app:${t}`, text: t };
213
217
  }
214
- const lv = litValue(m);
215
- if (typeof lv === "number" && !Number.isFinite(lv)) {
216
- return { key: `lit:${String(lv)}`, text: String(lv) };
217
- }
218
- if (lv !== void 0) {
219
- return { key: `lit:${String(lv)}`, text: JSON.stringify(lv) };
218
+ const lvR = litValue(m);
219
+ if (lvR.ok) {
220
+ const lv = lvR.value;
221
+ if (typeof lv === "number" && !Number.isFinite(lv)) {
222
+ return { key: `lit:${String(lv)}`, text: String(lv) };
223
+ }
224
+ return { key: `lit:${String(lv)}`, text: JSON.stringify(lv) ?? "undefined" };
220
225
  }
221
226
  return { key: `shape:${formatShape(m)}`, text: formatShape(m) };
222
227
  };
@@ -327,9 +332,8 @@ function sanitizeCommentText(text) {
327
332
 
328
333
  // src/algebra/denote.ts
329
334
  function denoteGuard(a, v) {
330
- const lv = litValue(a);
331
- if (lv !== void 0 && (!a.pred || a.pred.op === "true")) {
332
- return eqGuard(v, lv);
335
+ if (a.term?.op === "lit" && (!a.pred || a.pred.op === "true")) {
336
+ return eqGuard(v, a.term.value);
333
337
  }
334
338
  const shape = denoteShape(a.shape, v);
335
339
  const pred = denotePred(a, v);
@@ -377,11 +381,19 @@ function denoteShape(s, v) {
377
381
  case "tuple": {
378
382
  const checks = [`Array.isArray(${v})`];
379
383
  const minLen = s.elements.length;
384
+ const holes = new Set(s.holes ?? []);
380
385
  checks.push(s.rest ? `${v}.length >= ${minLen}` : `${v}.length === ${minLen}`);
381
386
  s.elements.forEach((el, i) => {
387
+ if (holes.has(i)) {
388
+ checks.push(`!(${i} in ${v})`);
389
+ return;
390
+ }
382
391
  const inner = denoteGuard(el, `${v}[${i}]`);
383
392
  if (inner !== "true") checks.push(inner);
384
393
  });
394
+ for (const i of holes) {
395
+ if (i >= minLen) checks.push(`!(${i} in ${v})`);
396
+ }
385
397
  if (s.rest) {
386
398
  const rest = denoteGuard(s.rest, "item");
387
399
  if (rest !== "true") {
@@ -407,8 +419,7 @@ function denoteShape(s, v) {
407
419
  function denotePred(a, v) {
408
420
  const p = a.pred;
409
421
  if (!p || p.op === "true") {
410
- const lv = litValue(a);
411
- if (lv !== void 0) return eqGuard(v, lv);
422
+ if (a.term?.op === "lit") return eqGuard(v, a.term.value);
412
423
  return "true";
413
424
  }
414
425
  return predAsJs(p, v, a);
@@ -435,17 +446,17 @@ function predAsJs(p, v, a) {
435
446
  case "ne": {
436
447
  const op = { gt: ">", ge: ">=", lt: "<", le: "<=", eq: "===", ne: "!==" }[p.op];
437
448
  const leftIsValue = termIsValue(p.a, a);
438
- const rightLit = litOfTerm(p.b);
439
- if (leftIsValue && rightLit !== void 0) {
440
- return cmpOp(v, op, rightLit);
449
+ const rightLitTerm = p.b.op === "lit" ? p.b : void 0;
450
+ if (leftIsValue && rightLitTerm) {
451
+ return cmpOp(v, op, rightLitTerm.value);
441
452
  }
442
- const leftLit = litOfTerm(p.a);
453
+ const leftLitTerm = p.a.op === "lit" ? p.a : void 0;
443
454
  const rightIsValue = termIsValue(p.b, a);
444
- if (rightIsValue && leftLit !== void 0) {
445
- return cmpLitValue(leftLit, op, v);
455
+ if (rightIsValue && leftLitTerm) {
456
+ return cmpLitValue(leftLitTerm.value, op, v);
446
457
  }
447
- if (leftLit !== void 0 && rightLit !== void 0) {
448
- return `${jsLit(leftLit)} ${op} ${jsLit(rightLit)}`;
458
+ if (leftLitTerm && rightLitTerm) {
459
+ return `${jsLit(leftLitTerm.value)} ${op} ${jsLit(rightLitTerm.value)}`;
449
460
  }
450
461
  return "true";
451
462
  }
@@ -453,12 +464,10 @@ function predAsJs(p, v, a) {
453
464
  return "true";
454
465
  }
455
466
  }
456
- function litOfTerm(t) {
457
- return t.op === "lit" ? t.value : void 0;
458
- }
459
467
  function jsLit(v) {
460
468
  if (v === void 0) return "undefined";
461
469
  if (v === null) return "null";
470
+ if (typeof v === "bigint") return `${v}n`;
462
471
  if (typeof v === "number") {
463
472
  if (Number.isNaN(v)) return "NaN";
464
473
  if (v === Infinity) return "Infinity";
@@ -488,8 +497,7 @@ function cmpLitValue(lit, op, v) {
488
497
  function termIsValue(t, a) {
489
498
  if (t.op === "var") return true;
490
499
  if (t.op === "lit") {
491
- const lv = litValue(a);
492
- return lv !== void 0 && Object.is(lv, t.value);
500
+ return a.term?.op === "lit" && Object.is(a.term.value, t.value);
493
501
  }
494
502
  return false;
495
503
  }
@@ -519,6 +527,8 @@ export {
519
527
  checkInjectedDomainEvidence,
520
528
  classChainNames,
521
529
  classFromMethods,
530
+ clearPureCallMemo,
531
+ clearPureMemo,
522
532
  coerceAsyncReturn,
523
533
  collectAbsInlays,
524
534
  concatString,
@@ -629,6 +639,8 @@ export {
629
639
  sourceHasRequireCall,
630
640
  stableAnalyzeKeySource,
631
641
  stableCallId,
642
+ stablePathKey,
643
+ stablePathKeyGraph,
632
644
  stripCommentsAndStrings,
633
645
  stripStringsKeepComments,
634
646
  superNameOf,