@nudojs/core 1.7.1 → 1.7.2

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.
@@ -76,6 +76,7 @@ function simplifyTerm(t) {
76
76
  if (typeof v2 === "boolean") return lit(v2 ? 1 : 0);
77
77
  if (v2 === null) return lit(0);
78
78
  if (typeof v2 === "string") return lit(Number(v2));
79
+ if (typeof v2 === "bigint") return app(fn, args);
79
80
  return lit(NaN);
80
81
  };
81
82
  if (one(b)) return surviveMulOne(a);
@@ -112,6 +113,36 @@ function foldLiterals(fn, xs) {
112
113
  return void 0;
113
114
  }
114
115
 
116
+ // src/algebra/collector-scope.ts
117
+ import { AsyncLocalStorage } from "async_hooks";
118
+ function createScopedSlot(init) {
119
+ const als = new AsyncLocalStorage();
120
+ const fallback = { v: init() };
121
+ const current = () => als.getStore() ?? fallback;
122
+ return {
123
+ get: () => current().v,
124
+ set: (v2) => {
125
+ current().v = v2;
126
+ },
127
+ runScoped: (body) => als.run({ v: current().v }, body)
128
+ };
129
+ }
130
+ var participants = [];
131
+ function registerCollectorScopeParticipant(enter) {
132
+ participants.push(enter);
133
+ }
134
+ var scopeActive = new AsyncLocalStorage();
135
+ function runWithCollectorScope(body) {
136
+ if (scopeActive.getStore() === true) return body();
137
+ let scoped = body;
138
+ for (let i = participants.length - 1; i >= 0; i--) {
139
+ const enter = participants[i];
140
+ const inner = scoped;
141
+ scoped = () => enter(inner);
142
+ }
143
+ return scopeActive.run(true, scoped);
144
+ }
145
+
115
146
  // src/algebra/pred.ts
116
147
  var TYPEOF_NAMES = [
117
148
  "undefined",
@@ -343,12 +374,15 @@ function predVars(p) {
343
374
  }
344
375
  var emptyPhi = pTrue;
345
376
  var phiAnd = and;
346
- var implicationOracle;
377
+ var implicationOracleSlot = createScopedSlot(
378
+ () => void 0
379
+ );
380
+ registerCollectorScopeParticipant((body) => implicationOracleSlot.runScoped(body));
347
381
  function setImplicationOracle(fn) {
348
- implicationOracle = fn;
382
+ implicationOracleSlot.set(fn);
349
383
  }
350
384
  function getImplicationOracle() {
351
- return implicationOracle;
385
+ return implicationOracleSlot.get();
352
386
  }
353
387
  function implies(phi2, pred) {
354
388
  if (pred.op === "true") return true;
@@ -391,6 +425,7 @@ function implies(phi2, pred) {
391
425
  const ctx2 = buildCtx(phi2);
392
426
  if (proveInCtx(ctx2, pred)) return true;
393
427
  if (decideLiteralPred(pred) === true) return true;
428
+ const implicationOracle = implicationOracleSlot.get();
394
429
  if (implicationOracle && implicationOracle(phi2, pred) === true) return true;
395
430
  return false;
396
431
  }
@@ -1160,6 +1195,35 @@ function isExactLit(a) {
1160
1195
  function litValue(a) {
1161
1196
  return a?.term?.op === "lit" ? { ok: true, value: a.term.value } : { ok: false };
1162
1197
  }
1198
+ function absNumLit(a) {
1199
+ if (!a) return void 0;
1200
+ const vR = litValue(a);
1201
+ const v2 = vR.ok ? vR.value : void 0;
1202
+ return typeof v2 === "number" ? v2 : void 0;
1203
+ }
1204
+ function absStrLit(a) {
1205
+ if (!a) return void 0;
1206
+ const vR = litValue(a);
1207
+ const v2 = vR.ok ? vR.value : void 0;
1208
+ return typeof v2 === "string" ? v2 : void 0;
1209
+ }
1210
+ function allAbsStr(args) {
1211
+ const result = [];
1212
+ for (const a of args) {
1213
+ const s = absStrLit(a);
1214
+ if (s === void 0) return void 0;
1215
+ result.push(s);
1216
+ }
1217
+ return result;
1218
+ }
1219
+ function absLit(value) {
1220
+ if (typeof value === "number") return numLit(value);
1221
+ if (typeof value === "string") return strLit(value);
1222
+ if (typeof value === "boolean") return boolLit(value);
1223
+ if (typeof value === "bigint") return abs({ k: "prim", type: "bigint" }, void 0, void 0, "exact");
1224
+ if (value === null) return abs({ k: "unknown" }, lit(null), void 0, "exact");
1225
+ return abs({ k: "unknown" }, lit(void 0), void 0, "exact");
1226
+ }
1163
1227
 
1164
1228
  // src/strip-types.ts
1165
1229
  var REMOVE = /* @__PURE__ */ Symbol("nudo.strip.remove");
@@ -1526,34 +1590,41 @@ function shapeOnlyFn(paramTypes, returnType, opts) {
1526
1590
  }
1527
1591
 
1528
1592
  // src/algebra/derivation.ts
1529
- var collector = null;
1530
- var nextId = 1;
1593
+ var derivationSlot = createScopedSlot(() => ({
1594
+ collector: null,
1595
+ nextId: 1,
1596
+ sessionNodes: null
1597
+ }));
1598
+ registerCollectorScopeParticipant((body) => derivationSlot.runScoped(body));
1531
1599
  var byAbs = /* @__PURE__ */ new WeakMap();
1532
- var sessionNodes = null;
1533
1600
  function setDerivationCollector(fn) {
1534
- collector = fn;
1601
+ derivationSlot.get().collector = fn;
1535
1602
  }
1536
1603
  function hasDerivationSession() {
1537
- return sessionNodes !== null;
1604
+ return derivationSlot.get().sessionNodes !== null;
1538
1605
  }
1539
1606
  function beginDerivationSession() {
1540
- sessionNodes = /* @__PURE__ */ new Map();
1541
- nextId = 1;
1607
+ const s = derivationSlot.get();
1608
+ s.sessionNodes = /* @__PURE__ */ new Map();
1609
+ s.nextId = 1;
1542
1610
  }
1543
1611
  function endDerivationSession() {
1544
- const nodes = sessionNodes ? [...sessionNodes.values()] : [];
1545
- sessionNodes = null;
1546
- collector = null;
1612
+ const s = derivationSlot.get();
1613
+ const nodes = s.sessionNodes ? [...s.sessionNodes.values()] : [];
1614
+ s.sessionNodes = null;
1615
+ s.collector = null;
1547
1616
  return nodes;
1548
1617
  }
1549
1618
  function abortDerivationSession() {
1550
- sessionNodes = null;
1551
- collector = null;
1619
+ const s = derivationSlot.get();
1620
+ s.sessionNodes = null;
1621
+ s.collector = null;
1552
1622
  }
1553
1623
  function note(node) {
1554
- const full = { ...node, id: nextId++ };
1555
- if (sessionNodes) sessionNodes.set(full.id, full);
1556
- collector?.(full);
1624
+ const s = derivationSlot.get();
1625
+ const full = { ...node, id: s.nextId++ };
1626
+ if (s.sessionNodes) s.sessionNodes.set(full.id, full);
1627
+ s.collector?.(full);
1557
1628
  return full;
1558
1629
  }
1559
1630
  function tagDerivationRoot(abs2, meta) {
@@ -1579,6 +1650,7 @@ function derivationChain(node) {
1579
1650
  let cur = node;
1580
1651
  while (cur.kind !== "root" && cur.parents.length > 0) {
1581
1652
  const pid = cur.parents[0];
1653
+ const sessionNodes = derivationSlot.get().sessionNodes;
1582
1654
  if (seen.has(pid) || !sessionNodes) break;
1583
1655
  const parent = sessionNodes.get(pid);
1584
1656
  if (!parent) break;
@@ -1589,7 +1661,7 @@ function derivationChain(node) {
1589
1661
  return chain;
1590
1662
  }
1591
1663
  function noteDerivationAdd(a, b, result) {
1592
- if (!sessionNodes) return;
1664
+ if (!derivationSlot.get().sessionNodes) return;
1593
1665
  const vbR = litValue(b);
1594
1666
  const vb = vbR.ok ? vbR.value : void 0;
1595
1667
  const vaR = litValue(a);
@@ -1612,7 +1684,7 @@ function noteDerivationAdd(a, b, result) {
1612
1684
  byAbs.set(result, node);
1613
1685
  }
1614
1686
  function noteDerivationJoin(inputs, result) {
1615
- if (!sessionNodes) return;
1687
+ if (!derivationSlot.get().sessionNodes) return;
1616
1688
  const parents = [];
1617
1689
  for (const a of inputs) {
1618
1690
  const n = byAbs.get(a);
@@ -2944,7 +3016,7 @@ function isSymbolAbs(a) {
2944
3016
  return !!a && a.shape.k === "prim" && a.shape.type === "symbol";
2945
3017
  }
2946
3018
 
2947
- // src/algebra/exec/nudo-throw.ts
3019
+ // src/algebra/nudo-throw.ts
2948
3020
  var NudoThrow = class extends Error {
2949
3021
  absValue;
2950
3022
  constructor(absValue) {
@@ -2957,9 +3029,9 @@ function isNudoThrow(e) {
2957
3029
  return e instanceof NudoThrow;
2958
3030
  }
2959
3031
 
2960
- // src/algebra/exec/may-throw.ts
2961
- import { AsyncLocalStorage } from "async_hooks";
2962
- var mayThrowAls = new AsyncLocalStorage();
3032
+ // src/algebra/may-throw.ts
3033
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
3034
+ var mayThrowAls = new AsyncLocalStorage2();
2963
3035
  var syncCtx = { collector: null, tryFrames: [] };
2964
3036
  function ctx() {
2965
3037
  return mayThrowAls.getStore() ?? syncCtx;
@@ -3011,11 +3083,11 @@ function $tryReleaseSoft() {
3011
3083
  return effects;
3012
3084
  }
3013
3085
  function flushMayThrowEffects(effects) {
3014
- const collector2 = ctx().collector;
3015
- if (!collector2 || effects.length === 0) return;
3086
+ const collector = ctx().collector;
3087
+ if (!collector || effects.length === 0) return;
3016
3088
  for (const e of effects) {
3017
3089
  try {
3018
- collector2(e);
3090
+ collector(e);
3019
3091
  } catch {
3020
3092
  }
3021
3093
  }
@@ -3840,7 +3912,7 @@ function migrateInvariants(from, to) {
3840
3912
  }
3841
3913
 
3842
3914
  // src/algebra/exec/runtime/state.ts
3843
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
3915
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
3844
3916
 
3845
3917
  // src/algebra/containers.ts
3846
3918
  var TUPLE_LITERAL_CAP = 8;
@@ -3865,6 +3937,17 @@ function clearStaleTermPred(v2) {
3865
3937
  v2.pred = void 0;
3866
3938
  }
3867
3939
  var phi = pTrue;
3940
+ function confPartial(a) {
3941
+ return a.conf === "exact" || a.conf === "path" ? { ...a, conf: "partial" } : a;
3942
+ }
3943
+ function confPartialPacked(a) {
3944
+ if (a.shape.k !== "obj") return confPartial(a);
3945
+ const slots = {};
3946
+ for (const [k, slot] of Object.entries(a.shape.slots)) {
3947
+ slots[k] = { value: confPartial(slot.value) };
3948
+ }
3949
+ return objOf(slots);
3950
+ }
3868
3951
  function currentExecPhi() {
3869
3952
  return phi;
3870
3953
  }
@@ -4014,10 +4097,10 @@ function isDefinitelyFalse(a) {
4014
4097
  function undef() {
4015
4098
  return abs({ k: "unknown" }, { op: "lit", value: void 0 }, pTrue, "exact");
4016
4099
  }
4017
- var loopExitsAls = new AsyncLocalStorage2();
4018
- var throwExitsAls = new AsyncLocalStorage2();
4019
- var tryMarksAls = new AsyncLocalStorage2();
4020
- var softFrameActiveAls = new AsyncLocalStorage2();
4100
+ var loopExitsAls = new AsyncLocalStorage3();
4101
+ var throwExitsAls = new AsyncLocalStorage3();
4102
+ var tryMarksAls = new AsyncLocalStorage3();
4103
+ var softFrameActiveAls = new AsyncLocalStorage3();
4021
4104
  function runWithLoopExits(body) {
4022
4105
  return loopExitsAls.run(
4023
4106
  [],
@@ -4151,6 +4234,150 @@ function $rethrowIfNudoReturn(e) {
4151
4234
  if (isNudoReturn(e)) throw e;
4152
4235
  }
4153
4236
 
4237
+ // src/algebra/call-budget.ts
4238
+ var MAX_CALL_DEPTH = 64;
4239
+ var MAX_TOTAL_CALLS = 2e4;
4240
+ var _absCallDepth = 0;
4241
+ var _absTotalCalls = 0;
4242
+ var _activeCallKeys = [];
4243
+ var _fnCallIds = /* @__PURE__ */ new WeakMap();
4244
+ var _fnCallIdSeq = 0;
4245
+ var _callTruncated = false;
4246
+ var _callDepthLimit = MAX_CALL_DEPTH;
4247
+ var _totalCallsLimit = MAX_TOTAL_CALLS;
4248
+ function getAbsCallBudgetStats() {
4249
+ return {
4250
+ calls: _absTotalCalls,
4251
+ maxCalls: _totalCallsLimit,
4252
+ forks: _evalForkCount,
4253
+ maxForks: _evalForkBudgetLimit,
4254
+ callTruncated: _callTruncated,
4255
+ forkTruncated: _evalForkTruncNoted,
4256
+ truncated: _callTruncated || _evalForkTruncNoted
4257
+ };
4258
+ }
4259
+ function resetAbsCallBudget() {
4260
+ _absCallDepth = 0;
4261
+ _absTotalCalls = 0;
4262
+ _activeCallKeys = [];
4263
+ _callTruncated = false;
4264
+ _callDepthLimit = MAX_CALL_DEPTH;
4265
+ _totalCallsLimit = MAX_TOTAL_CALLS;
4266
+ resetEvalForkBudget();
4267
+ }
4268
+ function withFnBudgetOverride(budget, run) {
4269
+ const prevDepth = _callDepthLimit;
4270
+ const prevCalls = _totalCallsLimit;
4271
+ const prevForks = _evalForkBudgetLimit;
4272
+ if (typeof budget.depth === "number" && Number.isFinite(budget.depth) && budget.depth >= 1) {
4273
+ _callDepthLimit = Math.floor(budget.depth);
4274
+ }
4275
+ if (typeof budget.calls === "number" && Number.isFinite(budget.calls) && budget.calls >= 1) {
4276
+ _totalCallsLimit = Math.floor(budget.calls);
4277
+ }
4278
+ if (typeof budget.forks === "number" && Number.isFinite(budget.forks) && budget.forks >= 1) {
4279
+ setEvalForkBudgetLimit(Math.floor(budget.forks));
4280
+ }
4281
+ try {
4282
+ run();
4283
+ } finally {
4284
+ _callDepthLimit = prevDepth;
4285
+ _totalCallsLimit = prevCalls;
4286
+ setEvalForkBudgetLimit(prevForks);
4287
+ }
4288
+ }
4289
+ function stableCallId(obj2) {
4290
+ let id = _fnCallIds.get(obj2);
4291
+ if (id === void 0) {
4292
+ id = `#${++_fnCallIdSeq}`;
4293
+ _fnCallIds.set(obj2, id);
4294
+ }
4295
+ return id;
4296
+ }
4297
+ function truncatedAbs() {
4298
+ return abs({ k: "unknown" }, void 0, void 0, "opaque");
4299
+ }
4300
+ function callBudgetKey(kind, id, args) {
4301
+ const parts = args.map((a) => {
4302
+ const sh = a?.shape;
4303
+ if (!sh) return `js:${typeof a}`;
4304
+ const t = a.term ? termToString(a.term) : "";
4305
+ return `${sh.k}:${t}`;
4306
+ });
4307
+ return `${kind}|${id}|${parts.join(",")}`;
4308
+ }
4309
+ var absTruncCollectorSlot = createScopedSlot(() => null);
4310
+ registerCollectorScopeParticipant((body) => absTruncCollectorSlot.runScoped(body));
4311
+ function setAbsTruncationCollector(collector) {
4312
+ const prev = absTruncCollectorSlot.get();
4313
+ absTruncCollectorSlot.set(collector);
4314
+ return prev;
4315
+ }
4316
+ function noteAbsTruncation(label) {
4317
+ const absTruncCollector = absTruncCollectorSlot.get();
4318
+ if (!absTruncCollector) return;
4319
+ try {
4320
+ absTruncCollector(label);
4321
+ } catch {
4322
+ }
4323
+ }
4324
+ function enterCall(key, label) {
4325
+ if (_activeCallKeys.includes(key) || _absCallDepth >= _callDepthLimit || _absTotalCalls >= _totalCallsLimit) {
4326
+ _callTruncated = true;
4327
+ noteAbsTruncation(label);
4328
+ return false;
4329
+ }
4330
+ _activeCallKeys.push(key);
4331
+ _absCallDepth++;
4332
+ _absTotalCalls++;
4333
+ return true;
4334
+ }
4335
+ function exitCall() {
4336
+ if (_absCallDepth > 0) _absCallDepth--;
4337
+ if (_activeCallKeys.length > 0) _activeCallKeys.pop();
4338
+ }
4339
+ var MAX_EVAL_TOTAL_FORKS = 5e3;
4340
+ var _evalForkBudgetLimit = MAX_EVAL_TOTAL_FORKS;
4341
+ var _evalForkCount = 0;
4342
+ var _evalForkTruncNoted = false;
4343
+ var FORK_TRUNCATION_LABEL = "#fork-budget";
4344
+ var HOST_EFFECT_LABEL_PREFIX = "#host-effect:";
4345
+ var PROMISE_MICRO_OVERFLOW_LABEL = "#promise-micro-overflow";
4346
+ var PROMISE_MICRO_ERROR_LABEL = "#promise-micro-error";
4347
+ var MATH_FOLD_ERROR_LABEL = "#math-fold-error";
4348
+ function noteHostEffectBlocked(name) {
4349
+ noteAbsTruncation(`${HOST_EFFECT_LABEL_PREFIX}${name}`);
4350
+ }
4351
+ function noteEvalForkTruncation() {
4352
+ noteAbsTruncation(FORK_TRUNCATION_LABEL);
4353
+ }
4354
+ function setEvalForkBudgetLimit(n) {
4355
+ if (typeof n === "number" && Number.isFinite(n) && n >= 1) {
4356
+ _evalForkBudgetLimit = Math.floor(n);
4357
+ } else {
4358
+ _evalForkBudgetLimit = MAX_EVAL_TOTAL_FORKS;
4359
+ }
4360
+ return _evalForkBudgetLimit;
4361
+ }
4362
+ function getEvalForkBudgetLimit() {
4363
+ return _evalForkBudgetLimit;
4364
+ }
4365
+ function getEvalForkCount() {
4366
+ return _evalForkCount;
4367
+ }
4368
+ function resetEvalForkBudget() {
4369
+ _evalForkCount = 0;
4370
+ _evalForkTruncNoted = false;
4371
+ }
4372
+ function bumpEvalForkBudget() {
4373
+ if (++_evalForkCount <= _evalForkBudgetLimit) return true;
4374
+ if (!_evalForkTruncNoted) {
4375
+ _evalForkTruncNoted = true;
4376
+ noteEvalForkTruncation();
4377
+ }
4378
+ return false;
4379
+ }
4380
+
4154
4381
  // src/algebra/builtins/shared.ts
4155
4382
  var noBody2 = { type: "BlockStatement", body: [], directives: [] };
4156
4383
  function numPrim(conf = "path") {
@@ -4359,6 +4586,7 @@ function evalMathMethod(name, args) {
4359
4586
  try {
4360
4587
  return numLit((name === "min" ? Math.min : Math.max)(...nums2));
4361
4588
  } catch {
4589
+ noteAbsTruncation(MATH_FOLD_ERROR_LABEL);
4362
4590
  return numPrim();
4363
4591
  }
4364
4592
  }
@@ -4377,6 +4605,7 @@ function evalMathMethod(name, args) {
4377
4605
  name === "round" ? Math.round(n) : name === "floor" ? Math.floor(n) : name === "ceil" ? Math.ceil(n) : Math.trunc(n)
4378
4606
  );
4379
4607
  } catch {
4608
+ noteAbsTruncation(MATH_FOLD_ERROR_LABEL);
4380
4609
  return numPrim();
4381
4610
  }
4382
4611
  }
@@ -4399,6 +4628,7 @@ function evalMathMethod(name, args) {
4399
4628
  try {
4400
4629
  return numLit(impl(...nums));
4401
4630
  } catch {
4631
+ noteAbsTruncation(MATH_FOLD_ERROR_LABEL);
4402
4632
  return numPrim();
4403
4633
  }
4404
4634
  }
@@ -6158,147 +6388,6 @@ function evalRegExpMethod(name, recv, args) {
6158
6388
  return void 0;
6159
6389
  }
6160
6390
 
6161
- // src/algebra/call-budget.ts
6162
- var MAX_CALL_DEPTH = 64;
6163
- var MAX_TOTAL_CALLS = 2e4;
6164
- var _absCallDepth = 0;
6165
- var _absTotalCalls = 0;
6166
- var _activeCallKeys = [];
6167
- var _fnCallIds = /* @__PURE__ */ new WeakMap();
6168
- var _fnCallIdSeq = 0;
6169
- var _callTruncated = false;
6170
- var _callDepthLimit = MAX_CALL_DEPTH;
6171
- var _totalCallsLimit = MAX_TOTAL_CALLS;
6172
- function getAbsCallBudgetStats() {
6173
- return {
6174
- calls: _absTotalCalls,
6175
- maxCalls: _totalCallsLimit,
6176
- forks: _evalForkCount,
6177
- maxForks: _evalForkBudgetLimit,
6178
- callTruncated: _callTruncated,
6179
- forkTruncated: _evalForkTruncNoted,
6180
- truncated: _callTruncated || _evalForkTruncNoted
6181
- };
6182
- }
6183
- function resetAbsCallBudget() {
6184
- _absCallDepth = 0;
6185
- _absTotalCalls = 0;
6186
- _activeCallKeys = [];
6187
- _callTruncated = false;
6188
- _callDepthLimit = MAX_CALL_DEPTH;
6189
- _totalCallsLimit = MAX_TOTAL_CALLS;
6190
- resetEvalForkBudget();
6191
- }
6192
- function withFnBudgetOverride(budget, run) {
6193
- const prevDepth = _callDepthLimit;
6194
- const prevCalls = _totalCallsLimit;
6195
- const prevForks = _evalForkBudgetLimit;
6196
- if (typeof budget.depth === "number" && Number.isFinite(budget.depth) && budget.depth >= 1) {
6197
- _callDepthLimit = Math.floor(budget.depth);
6198
- }
6199
- if (typeof budget.calls === "number" && Number.isFinite(budget.calls) && budget.calls >= 1) {
6200
- _totalCallsLimit = Math.floor(budget.calls);
6201
- }
6202
- if (typeof budget.forks === "number" && Number.isFinite(budget.forks) && budget.forks >= 1) {
6203
- setEvalForkBudgetLimit(Math.floor(budget.forks));
6204
- }
6205
- try {
6206
- run();
6207
- } finally {
6208
- _callDepthLimit = prevDepth;
6209
- _totalCallsLimit = prevCalls;
6210
- setEvalForkBudgetLimit(prevForks);
6211
- }
6212
- }
6213
- function stableCallId(obj2) {
6214
- let id = _fnCallIds.get(obj2);
6215
- if (id === void 0) {
6216
- id = `#${++_fnCallIdSeq}`;
6217
- _fnCallIds.set(obj2, id);
6218
- }
6219
- return id;
6220
- }
6221
- function truncatedAbs() {
6222
- return abs({ k: "unknown" }, void 0, void 0, "opaque");
6223
- }
6224
- function callBudgetKey(kind, id, args) {
6225
- const parts = args.map((a) => {
6226
- const sh = a?.shape;
6227
- if (!sh) return `js:${typeof a}`;
6228
- const t = a.term ? termToString(a.term) : "";
6229
- return `${sh.k}:${t}`;
6230
- });
6231
- return `${kind}|${id}|${parts.join(",")}`;
6232
- }
6233
- var absTruncCollector = null;
6234
- function setAbsTruncationCollector(collector2) {
6235
- const prev = absTruncCollector;
6236
- absTruncCollector = collector2;
6237
- return prev;
6238
- }
6239
- function noteAbsTruncation(label) {
6240
- if (!absTruncCollector) return;
6241
- try {
6242
- absTruncCollector(label);
6243
- } catch {
6244
- }
6245
- }
6246
- function enterCall(key, label) {
6247
- if (_activeCallKeys.includes(key) || _absCallDepth >= _callDepthLimit || _absTotalCalls >= _totalCallsLimit) {
6248
- _callTruncated = true;
6249
- noteAbsTruncation(label);
6250
- return false;
6251
- }
6252
- _activeCallKeys.push(key);
6253
- _absCallDepth++;
6254
- _absTotalCalls++;
6255
- return true;
6256
- }
6257
- function exitCall() {
6258
- if (_absCallDepth > 0) _absCallDepth--;
6259
- if (_activeCallKeys.length > 0) _activeCallKeys.pop();
6260
- }
6261
- var MAX_EVAL_TOTAL_FORKS = 5e3;
6262
- var _evalForkBudgetLimit = MAX_EVAL_TOTAL_FORKS;
6263
- var _evalForkCount = 0;
6264
- var _evalForkTruncNoted = false;
6265
- var FORK_TRUNCATION_LABEL = "#fork-budget";
6266
- var HOST_EFFECT_LABEL_PREFIX = "#host-effect:";
6267
- var PROMISE_MICRO_OVERFLOW_LABEL = "#promise-micro-overflow";
6268
- var PROMISE_MICRO_ERROR_LABEL = "#promise-micro-error";
6269
- function noteHostEffectBlocked(name) {
6270
- noteAbsTruncation(`${HOST_EFFECT_LABEL_PREFIX}${name}`);
6271
- }
6272
- function noteEvalForkTruncation() {
6273
- noteAbsTruncation(FORK_TRUNCATION_LABEL);
6274
- }
6275
- function setEvalForkBudgetLimit(n) {
6276
- if (typeof n === "number" && Number.isFinite(n) && n >= 1) {
6277
- _evalForkBudgetLimit = Math.floor(n);
6278
- } else {
6279
- _evalForkBudgetLimit = MAX_EVAL_TOTAL_FORKS;
6280
- }
6281
- return _evalForkBudgetLimit;
6282
- }
6283
- function getEvalForkBudgetLimit() {
6284
- return _evalForkBudgetLimit;
6285
- }
6286
- function getEvalForkCount() {
6287
- return _evalForkCount;
6288
- }
6289
- function resetEvalForkBudget() {
6290
- _evalForkCount = 0;
6291
- _evalForkTruncNoted = false;
6292
- }
6293
- function bumpEvalForkBudget() {
6294
- if (++_evalForkCount <= _evalForkBudgetLimit) return true;
6295
- if (!_evalForkTruncNoted) {
6296
- _evalForkTruncNoted = true;
6297
- noteEvalForkTruncation();
6298
- }
6299
- return false;
6300
- }
6301
-
6302
6391
  // src/algebra/builtins/promise.ts
6303
6392
  var promiseExecStack = [];
6304
6393
  function enterPromiseExecutorScope() {
@@ -8161,25 +8250,12 @@ function leqPred(src, tgt, phi2, depth) {
8161
8250
  if (!tp) return ok();
8162
8251
  if (!sp) {
8163
8252
  if (implies(phi2, tp)) return ok();
8164
- return fail(`pred \u22AD ${predBrief(tp)}`);
8253
+ return fail(`pred \u22AD ${predToString(tp)}`);
8165
8254
  }
8166
8255
  const combined = phi2.op === "true" ? sp : { op: "and", args: [phi2, sp] };
8167
8256
  if (implies(combined, tp)) return ok();
8168
8257
  if (numericBoundsImply(sp, tp)) return ok();
8169
- return fail(`pred \u22AD ${predBrief(tp)}`);
8170
- }
8171
- function predBrief(p) {
8172
- switch (p.op) {
8173
- case "gt":
8174
- case "ge":
8175
- case "lt":
8176
- case "le":
8177
- case "eq":
8178
- case "ne":
8179
- return p.op;
8180
- default:
8181
- return p.op;
8182
- }
8258
+ return fail(`pred \u22AD ${predToString(tp)}`);
8183
8259
  }
8184
8260
  function numericBoundsImply(src, tgt) {
8185
8261
  const one = (p) => p.op === "gt" || p.op === "ge" || p.op === "lt" || p.op === "le";
@@ -8203,7 +8279,7 @@ function numericBoundsImply(src, tgt) {
8203
8279
  return sb <= tb;
8204
8280
  }
8205
8281
  function sameTermSide(a, b) {
8206
- return a.a.op === b.a.op && termEquals(a.a, b.a);
8282
+ return termEquals(a.a, b.a);
8207
8283
  }
8208
8284
  function litGE(a, b) {
8209
8285
  if (a.op !== "lit" || b.op !== "lit") return false;
@@ -8511,25 +8587,87 @@ function formatShapeInner(a, budget) {
8511
8587
  }
8512
8588
  return parts.join(" | ");
8513
8589
  }
8514
- default:
8515
- return "\xB7";
8590
+ default:
8591
+ return "\xB7";
8592
+ }
8593
+ }
8594
+ function formatAbsMultiline(a, label) {
8595
+ const lines = [];
8596
+ if (label) lines.push(label);
8597
+ lines.push(` ${formatShape(a)}`);
8598
+ if (a.term && a.term.op !== "lit") {
8599
+ lines.push(` term: ${termToString(a.term)}`);
8600
+ }
8601
+ if (a.pred && a.pred.op !== "true") {
8602
+ lines.push(` pred: ${predToString(a.pred)}`);
8603
+ }
8604
+ lines.push(` conf: ${a.conf}`);
8605
+ return lines.join("\n");
8606
+ }
8607
+
8608
+ // src/algebra/lru-map.ts
8609
+ var BoundedLruMap = class {
8610
+ map = /* @__PURE__ */ new Map();
8611
+ max;
8612
+ constructor(max) {
8613
+ this.max = max;
8614
+ }
8615
+ get size() {
8616
+ return this.map.size;
8617
+ }
8618
+ getMax() {
8619
+ return this.max;
8620
+ }
8621
+ setMax(max) {
8622
+ this.max = max;
8623
+ this.trim();
8624
+ }
8625
+ has(key) {
8626
+ return this.map.has(key);
8627
+ }
8628
+ get(key) {
8629
+ const hit = this.map.get(key);
8630
+ if (hit === void 0) return void 0;
8631
+ this.map.delete(key);
8632
+ this.map.set(key, hit);
8633
+ return hit;
8634
+ }
8635
+ set(key, value) {
8636
+ if (this.max <= 0) return;
8637
+ while (this.map.size >= this.max && !this.map.has(key)) {
8638
+ const oldest = this.map.keys().next().value;
8639
+ if (oldest === void 0) break;
8640
+ this.map.delete(oldest);
8641
+ }
8642
+ this.map.delete(key);
8643
+ this.map.set(key, value);
8516
8644
  }
8517
- }
8518
- function formatAbsMultiline(a, label) {
8519
- const lines = [];
8520
- if (label) lines.push(label);
8521
- lines.push(` ${formatShape(a)}`);
8522
- if (a.term && a.term.op !== "lit") {
8523
- lines.push(` term: ${termToString(a.term)}`);
8645
+ delete(key) {
8646
+ return this.map.delete(key);
8524
8647
  }
8525
- if (a.pred && a.pred.op !== "true") {
8526
- lines.push(` pred: ${predToString(a.pred)}`);
8648
+ clear() {
8649
+ this.map.clear();
8527
8650
  }
8528
- lines.push(` conf: ${a.conf}`);
8529
- return lines.join("\n");
8530
- }
8651
+ trim() {
8652
+ while (this.map.size > this.max) {
8653
+ const oldest = this.map.keys().next().value;
8654
+ if (oldest === void 0) break;
8655
+ this.map.delete(oldest);
8656
+ }
8657
+ }
8658
+ };
8531
8659
 
8532
8660
  // src/algebra/code-text.ts
8661
+ var SOURCE_SCAN_CACHE_MAX = 256;
8662
+ var stripCommentsAndStringsCache = new BoundedLruMap(
8663
+ SOURCE_SCAN_CACHE_MAX
8664
+ );
8665
+ var stripStringsKeepCommentsCache = new BoundedLruMap(
8666
+ SOURCE_SCAN_CACHE_MAX
8667
+ );
8668
+ var maskCommentsAndStringsCache = new BoundedLruMap(
8669
+ SOURCE_SCAN_CACHE_MAX
8670
+ );
8533
8671
  var REGEX_KEYWORDS = /* @__PURE__ */ new Set([
8534
8672
  "await",
8535
8673
  "case",
@@ -8766,27 +8904,36 @@ function scanSource(source) {
8766
8904
  return { spans, literals };
8767
8905
  }
8768
8906
  function stripCommentsAndStrings(source) {
8907
+ const hit = stripCommentsAndStringsCache.get(source);
8908
+ if (hit !== void 0) return hit;
8769
8909
  let out = "";
8770
8910
  for (const span of scanSource(source).spans) {
8771
8911
  if (span.kind === "code") out += span.text;
8772
8912
  else if (span.kind === "comment") out += " ";
8773
8913
  else out += '""';
8774
8914
  }
8915
+ stripCommentsAndStringsCache.set(source, out);
8775
8916
  return out;
8776
8917
  }
8777
8918
  function stripStringsKeepComments(source) {
8919
+ const hit = stripStringsKeepCommentsCache.get(source);
8920
+ if (hit !== void 0) return hit;
8778
8921
  let out = "";
8779
8922
  for (const span of scanSource(source).spans) {
8780
8923
  out += span.kind === "string" ? '""' : span.text;
8781
8924
  }
8925
+ stripStringsKeepCommentsCache.set(source, out);
8782
8926
  return out;
8783
8927
  }
8784
8928
  function maskCommentsAndStrings(source) {
8929
+ const hit = maskCommentsAndStringsCache.get(source);
8930
+ if (hit !== void 0) return hit;
8785
8931
  let out = "";
8786
8932
  for (const span of scanSource(source).spans) {
8787
8933
  if (span.kind === "code") out += span.text;
8788
8934
  else out += span.text.replace(/[^\n]/g, " ");
8789
8935
  }
8936
+ maskCommentsAndStringsCache.set(source, out);
8790
8937
  return out;
8791
8938
  }
8792
8939
  function scanStringLiterals(source) {
@@ -9050,6 +9197,18 @@ function isStatefulMethodName(name) {
9050
9197
  // src/algebra/exec/transpile/intrinsics.ts
9051
9198
  var HOST_INTRINSIC_NAMES = ["undefined", "NaN", "Infinity"];
9052
9199
  var HOST_INTRINSIC_SET = new Set(HOST_INTRINSIC_NAMES);
9200
+ var ENV_SHADOW_SKIP_GLOBALS = /* @__PURE__ */ new Set([
9201
+ ...HOST_INTRINSIC_NAMES,
9202
+ "Math",
9203
+ "Number",
9204
+ "JSON",
9205
+ "Object",
9206
+ "Array",
9207
+ "String",
9208
+ "Date",
9209
+ "Promise",
9210
+ "BigInt"
9211
+ ]);
9053
9212
  var UNDEF_LIT = "$lit(void 0)";
9054
9213
  function hostIntrinsicLit(name) {
9055
9214
  switch (name) {
@@ -9323,6 +9482,18 @@ function collectLexicalDeclNames(node, acc) {
9323
9482
  else if (child && typeof child === "object") collectLexicalDeclNames(child, acc);
9324
9483
  }
9325
9484
  }
9485
+ function collectLoopBodyTopLevelDeclNames(body, acc) {
9486
+ const n = body;
9487
+ if (!n || n.type !== "BlockStatement" || !Array.isArray(n.body)) return;
9488
+ for (const s of n.body) {
9489
+ const stmt = s;
9490
+ if (stmt.type === "VariableDeclaration" && stmt.kind !== "var") {
9491
+ for (const d of stmt.declarations ?? []) collectPatternNames2(d.id, acc);
9492
+ } else if (stmt.type === "FunctionDeclaration" || stmt.type === "ClassDeclaration") {
9493
+ collectPatternNames2(stmt.id, acc);
9494
+ }
9495
+ }
9496
+ }
9326
9497
  function computeConstScope(stmts, parentConsts) {
9327
9498
  const consts = /* @__PURE__ */ new Set();
9328
9499
  const mutables = /* @__PURE__ */ new Set();
@@ -10529,7 +10700,9 @@ ${pad}export default ${name};`;
10529
10700
  collectAssignedIds(stmt.test, assigned2);
10530
10701
  collectAssignedIds(stmt.update, assigned2);
10531
10702
  collectArrMutatorReceivers(stmt.body, assigned2);
10532
- const names2 = [...assigned2].filter((n) => !HOST_INTRINSIC_SET.has(n));
10703
+ const bodyLocalDecls2 = /* @__PURE__ */ new Set();
10704
+ collectLoopBodyTopLevelDeclNames(stmt.body, bodyLocalDecls2);
10705
+ const names2 = [...assigned2].filter((n) => !HOST_INTRINSIC_SET.has(n) && !bodyLocalDecls2.has(n));
10533
10706
  const packSrc2 = names2.length === 0 ? null : `$obj({ ${names2.map((n) => `${JSON.stringify(n)}: $copy(${n})`).join(", ")} })`;
10534
10707
  const unpackSrc2 = names2.length === 0 ? null : `(__lp) => { ${names2.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }`;
10535
10708
  const optsSrc2 = (() => {
@@ -10569,7 +10742,9 @@ ${pad}export default ${name};`;
10569
10742
  collectAssignedIds(stmt.test, assigned);
10570
10743
  collectAssignedIds(stmt.update, assigned);
10571
10744
  collectArrMutatorReceivers(stmt.body, assigned);
10572
- const names = [...assigned].filter((n) => n !== initName && !HOST_INTRINSIC_SET.has(n));
10745
+ const bodyLocalDecls = /* @__PURE__ */ new Set();
10746
+ collectLoopBodyTopLevelDeclNames(stmt.body, bodyLocalDecls);
10747
+ const names = [...assigned].filter((n) => n !== initName && !HOST_INTRINSIC_SET.has(n) && !bodyLocalDecls.has(n));
10573
10748
  const packSrc = names.length === 0 ? null : `$obj({ ${names.map((n) => `${JSON.stringify(n)}: $copy(${n})`).join(", ")} })`;
10574
10749
  const unpackSrc = names.length === 0 ? null : `(__lp) => { ${names.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }`;
10575
10750
  const optsSrc = (() => {
@@ -10878,7 +11053,9 @@ ${indent(depth + 1)}]${dflt})`;
10878
11053
  const assigned = /* @__PURE__ */ new Set();
10879
11054
  collectAssignedIds(stmt.body, assigned);
10880
11055
  collectArrMutatorReceivers(stmt.body, assigned);
10881
- const names = [...assigned].filter((n) => n !== bindName && !HOST_INTRINSIC_SET.has(n));
11056
+ const bodyLocalDecls = /* @__PURE__ */ new Set();
11057
+ collectLoopBodyTopLevelDeclNames(stmt.body, bodyLocalDecls);
11058
+ const names = [...assigned].filter((n) => n !== bindName && !HOST_INTRINSIC_SET.has(n) && !bodyLocalDecls.has(n));
10882
11059
  const loopOpts = opts.loopLabel ? `label: ${JSON.stringify(opts.loopLabel)}` : "";
10883
11060
  const optsSrc = names.length === 0 ? loopOpts ? `, { ${loopOpts} }` : "" : `, { pack: () => $obj({ ${names.map((n) => `${JSON.stringify(n)}: $copy(${n})`).join(", ")} }), unpack: (__lp) => { ${names.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }${loopOpts ? `, ${loopOpts}` : ""} }`;
10884
11061
  return [
@@ -10900,7 +11077,9 @@ ${indent(depth + 1)}]${dflt})`;
10900
11077
  const assigned = /* @__PURE__ */ new Set();
10901
11078
  collectAssignedIds(stmt.body, assigned);
10902
11079
  collectAssignedIds(stmt.test, assigned);
10903
- const names = [...assigned].filter((n) => !HOST_INTRINSIC_SET.has(n));
11080
+ const bodyLocalDecls = /* @__PURE__ */ new Set();
11081
+ collectLoopBodyTopLevelDeclNames(stmt.body, bodyLocalDecls);
11082
+ const names = [...assigned].filter((n) => !HOST_INTRINSIC_SET.has(n) && !bodyLocalDecls.has(n));
10904
11083
  const loopOpts = opts.loopLabel ? `label: ${JSON.stringify(opts.loopLabel)}` : "";
10905
11084
  if (names.length === 0) {
10906
11085
  return [
@@ -10932,7 +11111,9 @@ ${indent(depth + 1)}]${dflt})`;
10932
11111
  collectAssignedIds(stmt.body, assigned);
10933
11112
  collectAssignedIds(stmt.test, assigned);
10934
11113
  collectArrMutatorReceivers(stmt.body, assigned);
10935
- const names = [...assigned].filter((n) => !HOST_INTRINSIC_SET.has(n));
11114
+ const bodyLocalDecls = /* @__PURE__ */ new Set();
11115
+ collectLoopBodyTopLevelDeclNames(stmt.body, bodyLocalDecls);
11116
+ const names = [...assigned].filter((n) => !HOST_INTRINSIC_SET.has(n) && !bodyLocalDecls.has(n));
10936
11117
  const packSrc = names.length === 0 ? null : `$obj({ ${names.map((n) => `${JSON.stringify(n)}: $copy(${n})`).join(", ")} })`;
10937
11118
  const unpackSrc = names.length === 0 ? null : `(__lp) => { ${names.map((n) => `${n} = $get(__lp, ${JSON.stringify(n)});`).join(" ")} }`;
10938
11119
  const loopOpts = opts.loopLabel ? `label: ${JSON.stringify(opts.loopLabel)}` : "";
@@ -11418,10 +11599,11 @@ function transpileExpression(expr, opts = {}) {
11418
11599
  return transpileShortCircuitExpr(opts, {
11419
11600
  alwaysNodes: [lNode],
11420
11601
  alwaysSrc: l,
11421
- // 测试用 nullish;返回侧:nullish → right,否则 → left
11602
+ // 测试用 nullish;返回侧:nullish → right,否则 → left 的**非 nullish 部分**
11603
+ // (索引访问/可选字段的左值常携带 undefined 臂,不去则 ?? 的 alt 仍含 undefined)
11422
11604
  consSrc: r,
11423
11605
  consNodes: [rNode],
11424
- altSrc: l,
11606
+ altSrc: `$removeNullish(${l})`,
11425
11607
  altNodes: [lNode],
11426
11608
  testSrc: `$nullishTest(${l})`
11427
11609
  });
@@ -11811,7 +11993,7 @@ ${mBodyInner}
11811
11993
  alwaysSrc: targetSrc,
11812
11994
  consSrc: right,
11813
11995
  consNodes: [rNode],
11814
- altSrc: targetSrc,
11996
+ altSrc: `$removeNullish(${targetSrc})`,
11815
11997
  altNodes: [],
11816
11998
  testSrc: `$nullishTest(${targetSrc})`
11817
11999
  });
@@ -12066,13 +12248,13 @@ function transpileSource(source, opts = {}) {
12066
12248
  return transpileFile(file, { ...opts, source: opts.source ?? source });
12067
12249
  }
12068
12250
  function runtimeImportOf(runtime) {
12069
- return `import { $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $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, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo } from ${JSON.stringify(runtime)};`;
12251
+ return `import { $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $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, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $removeNullish, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo } from ${JSON.stringify(runtime)};`;
12070
12252
  }
12071
12253
  function transpileFile(file, opts = {}) {
12072
12254
  const runtime = opts.runtimeImport ?? "@nudojs/core/exec";
12073
12255
  const lines = [
12074
12256
  `// nudo evaluator transpile \u2014 values are Abs; operators are overloaded calls`,
12075
- `import { $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $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, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo } from ${JSON.stringify(runtime)};`,
12257
+ `import { $add, $sub, $mul, $div, $mod, $bitand, $bitor, $bitxor, $bitnot, $shl, $shr, $ushr, $pow, $toNumber, $toNumeric, $updateAdd, $updateSub, $in, $instanceof, $instanceofNonIdent, $classExpr, $del, $delRes, $objAccessor, $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, $super, $async, $copy, $await, $asyncReturn, $orDefault, $callNamed, $optionalGet, $optionalInvoke, $spread, $concat, $forOf, $forInKeys, $catchVal, $switch, $staticInvoke, $setKey, $gen, $yield, $fnVal, $regex, $reStateCall, $rethrowIfNudoReturn, $nullishTest, $removeNullish, $tryMark, $assignRecord, $recordBinding, $unknown, $importMeta, $dynamicImport, $tryTakeSince, $tryCurrentMark, $tryPopMark, $tryDigestSoftCatch, $tryReleaseSoftOut, $tryDetachSoftCatch, $tryDiscardSoft, $tryOrphanSoft, $pushLoopExit, $objRest, $arrRest, $elems, $arguments, $isForkExit, $rawThis, $isBreakTo } from ${JSON.stringify(runtime)};`,
12076
12258
  ``
12077
12259
  ];
12078
12260
  for (const stmt of file.program.body) {
@@ -12204,8 +12386,9 @@ function $join(a, b) {
12204
12386
  }
12205
12387
 
12206
12388
  // src/algebra/exec/member-diag.ts
12207
- import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
12208
- var memberDiagCollector = null;
12389
+ import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
12390
+ var memberDiagCollectorSlot = createScopedSlot(() => null);
12391
+ registerCollectorScopeParticipant((body) => memberDiagCollectorSlot.runScoped(body));
12209
12392
  var callLocStack = [];
12210
12393
  var absOrigins = /* @__PURE__ */ new WeakMap();
12211
12394
  function tagAbsOrigin(a, loc) {
@@ -12216,8 +12399,8 @@ function getAbsOrigin(a) {
12216
12399
  return absOrigins.get(a);
12217
12400
  }
12218
12401
  function setMemberDiagCollector(c) {
12219
- const prev = memberDiagCollector;
12220
- memberDiagCollector = c;
12402
+ const prev = memberDiagCollectorSlot.get();
12403
+ memberDiagCollectorSlot.set(c);
12221
12404
  return prev;
12222
12405
  }
12223
12406
  function pushCallLoc(loc) {
@@ -12227,6 +12410,7 @@ function popCallLoc() {
12227
12410
  callLocStack.pop();
12228
12411
  }
12229
12412
  function recordMemberDiag(d) {
12413
+ const memberDiagCollector = memberDiagCollectorSlot.get();
12230
12414
  if (!memberDiagCollector) return;
12231
12415
  const origin = d.origin ?? callLocStack[callLocStack.length - 1];
12232
12416
  try {
@@ -12370,7 +12554,7 @@ function definitelyUncallableMember(recv, name) {
12370
12554
  }
12371
12555
  return false;
12372
12556
  }
12373
- var evalMissingSlotAls = new AsyncLocalStorage3();
12557
+ var evalMissingSlotAls = new AsyncLocalStorage4();
12374
12558
  var evalMissingSlotFallback = false;
12375
12559
  function setEvalMissingSlotEnabled(enabled) {
12376
12560
  evalMissingSlotFallback = enabled;
@@ -12515,6 +12699,7 @@ __export(runtime_exports, {
12515
12699
  $pushLoopExit: () => $pushLoopExit,
12516
12700
  $rawThis: () => $rawThis,
12517
12701
  $regex: () => $regex,
12702
+ $removeNullish: () => $removeNullish,
12518
12703
  $rethrowIfNudoReturn: () => $rethrowIfNudoReturn,
12519
12704
  $set: () => $set,
12520
12705
  $setProto: () => $setProto,
@@ -12546,12 +12731,15 @@ __export(runtime_exports, {
12546
12731
  $whileSeq: () => $whileSeq,
12547
12732
  $yield: () => $yield,
12548
12733
  DEFAULT_MAX_LOOP_ITERS: () => DEFAULT_MAX_LOOP_ITERS,
12734
+ LOOP_TRUNCATION_LABEL: () => LOOP_TRUNCATION_LABEL,
12735
+ MAX_CONCRETE_LOOP_ITERS: () => MAX_CONCRETE_LOOP_ITERS,
12549
12736
  NudoLoopSignal: () => NudoLoopSignal,
12550
12737
  NudoReturn: () => NudoReturn,
12551
12738
  NudoThrow: () => NudoThrow,
12552
12739
  asAbsVal: () => asAbsVal,
12553
12740
  callAtFunctionBoundary: () => callAtFunctionBoundary,
12554
12741
  clearStaleTermPred: () => clearStaleTermPred,
12742
+ confPartial: () => confPartial,
12555
12743
  currentExecPhi: () => currentExecPhi,
12556
12744
  fillTuple: () => fillTuple,
12557
12745
  isArrMutator: () => isArrMutator,
@@ -12574,6 +12762,8 @@ __export(runtime_exports, {
12574
12762
 
12575
12763
  // src/algebra/exec/runtime/loop-budget.ts
12576
12764
  var DEFAULT_MAX_LOOP_ITERS = 8;
12765
+ var MAX_CONCRETE_LOOP_ITERS = 1024;
12766
+ var LOOP_TRUNCATION_LABEL = "#loop-iterations";
12577
12767
 
12578
12768
  // src/algebra/exec/runtime/containers.ts
12579
12769
  function tupleOrWiden(els, conf) {
@@ -13310,7 +13500,9 @@ function $forOf(iterable, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
13310
13500
  const knownLen = shape.k === "tuple" ? shape.elements.length : typeof sv === "string" ? [...sv].length : collectionExactLen(iterable);
13311
13501
  const unbounded = knownLen === void 0;
13312
13502
  if (unbounded) snapExit();
13313
- const n = knownLen !== void 0 ? Math.min(knownLen, maxIters) : items.length > 0 ? 1 : 0;
13503
+ const concreteCap = Math.max(maxIters, MAX_CONCRETE_LOOP_ITERS);
13504
+ const n = knownLen !== void 0 ? Math.min(knownLen, concreteCap) : items.length > 0 ? 1 : 0;
13505
+ const concreteOverrun = knownLen !== void 0 && knownLen > concreteCap;
13314
13506
  for (let i = 0; i < n; i++) {
13315
13507
  const item = items.length > 0 ? items[Math.min(i, items.length - 1)] : unknown;
13316
13508
  try {
@@ -13335,19 +13527,29 @@ function $forOf(iterable, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
13335
13527
  if (unbounded) snapExit();
13336
13528
  }
13337
13529
  if (unbounded && n === 0) snapExit();
13530
+ if (concreteOverrun) {
13531
+ noteAbsTruncation(LOOP_TRUNCATION_LABEL);
13532
+ if (pack && unpack) unpack(confPartialPacked(pack()));
13533
+ return;
13534
+ }
13338
13535
  applyExitJoin();
13339
13536
  }
13537
+ var NAMESPACE_GLOBALS = [
13538
+ ["Math", Math],
13539
+ ["Number", Number],
13540
+ ["JSON", JSON],
13541
+ ["Object", Object],
13542
+ ["Array", Array],
13543
+ ["String", String],
13544
+ ["Date", Date],
13545
+ ["Promise", Promise],
13546
+ ["BigInt", BigInt]
13547
+ ];
13340
13548
  function namespaceNameOf(v2) {
13341
13549
  if (typeof v2 !== "object" && typeof v2 !== "function") return void 0;
13342
- if (v2 === Math) return "Math";
13343
- if (v2 === Number) return "Number";
13344
- if (v2 === JSON) return "JSON";
13345
- if (v2 === Object) return "Object";
13346
- if (v2 === Array) return "Array";
13347
- if (v2 === String) return "String";
13348
- if (v2 === Date) return "Date";
13349
- if (v2 === Promise) return "Promise";
13350
- if (v2 === BigInt) return "BigInt";
13550
+ for (const [name, host] of NAMESPACE_GLOBALS) {
13551
+ if (v2 === host) return name;
13552
+ }
13351
13553
  return void 0;
13352
13554
  }
13353
13555
  function $regex(pattern, flags = "") {
@@ -13929,7 +14131,10 @@ function $for(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
13929
14131
  if (!extJoin || !pack || !unpack) return;
13930
14132
  unpack(joinAbs(extJoin, pack()));
13931
14133
  };
13932
- for (let i = 0; i < maxIters; i++) {
14134
+ let limit = maxIters;
14135
+ let extended = false;
14136
+ let concreteExhausted = false;
14137
+ for (let i = 0; i < limit; i++) {
13933
14138
  const t = test(state);
13934
14139
  if (isDefinitelyFalse(t)) {
13935
14140
  snapCounter();
@@ -13939,6 +14144,7 @@ function $for(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
13939
14144
  }
13940
14145
  const abstractTest = !isDefinitelyTrue(t);
13941
14146
  if (abstractTest) {
14147
+ if (extended) break;
13942
14148
  snapCounter();
13943
14149
  snapExt();
13944
14150
  }
@@ -13978,21 +14184,39 @@ function $for(init, test, step, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
13978
14184
  }
13979
14185
  }
13980
14186
  state = next;
14187
+ if (i + 1 === limit && isDefinitelyTrue(test(state))) {
14188
+ if (limit < MAX_CONCRETE_LOOP_ITERS) {
14189
+ limit = MAX_CONCRETE_LOOP_ITERS;
14190
+ extended = true;
14191
+ } else {
14192
+ concreteExhausted = true;
14193
+ }
14194
+ }
13981
14195
  }
13982
14196
  snapCounter();
13983
14197
  snapExt();
14198
+ if (concreteExhausted) {
14199
+ noteAbsTruncation(LOOP_TRUNCATION_LABEL);
14200
+ if (extJoin && pack && unpack) unpack(confPartialPacked(joinAbs(extJoin, pack())));
14201
+ return confPartial(exitJoin ?? state);
14202
+ }
13984
14203
  applyExtJoin();
13985
14204
  return exitJoin ?? state;
13986
14205
  }
13987
14206
  function $while(init, test, step, maxIters = DEFAULT_MAX_LOOP_ITERS) {
13988
14207
  let state = init;
13989
14208
  let exitJoin;
13990
- for (let i = 0; i < maxIters; i++) {
14209
+ let limit = maxIters;
14210
+ let extended = false;
14211
+ let concreteExhausted = false;
14212
+ for (let i = 0; i < limit; i++) {
13991
14213
  const t = test(state);
13992
14214
  if (isDefinitelyFalse(t)) {
13993
14215
  return exitJoin ? joinAbs(exitJoin, state) : state;
13994
14216
  }
13995
- if (!isDefinitelyTrue(t)) {
14217
+ const abstractTest = !isDefinitelyTrue(t);
14218
+ if (abstractTest) {
14219
+ if (extended) break;
13996
14220
  exitJoin = exitJoin ? joinAbs(exitJoin, state) : state;
13997
14221
  }
13998
14222
  const next = step(state);
@@ -14005,6 +14229,18 @@ function $while(init, test, step, maxIters = DEFAULT_MAX_LOOP_ITERS) {
14005
14229
  }
14006
14230
  }
14007
14231
  state = next;
14232
+ if (i + 1 === limit && isDefinitelyTrue(test(state))) {
14233
+ if (limit < MAX_CONCRETE_LOOP_ITERS) {
14234
+ limit = MAX_CONCRETE_LOOP_ITERS;
14235
+ extended = true;
14236
+ } else {
14237
+ concreteExhausted = true;
14238
+ }
14239
+ }
14240
+ }
14241
+ if (concreteExhausted) {
14242
+ noteAbsTruncation(LOOP_TRUNCATION_LABEL);
14243
+ return confPartial(exitJoin ? joinAbs(exitJoin, state) : state);
14008
14244
  }
14009
14245
  return exitJoin ? joinAbs(exitJoin, state) : state;
14010
14246
  }
@@ -14021,13 +14257,28 @@ function $whileSeq(test, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
14021
14257
  if (!exitJoin || !pack || !unpack) return;
14022
14258
  unpack(joinAbs(exitJoin, pack()));
14023
14259
  };
14024
- for (let i = 0; i < maxIters; i++) {
14260
+ let limit = maxIters;
14261
+ let extended = false;
14262
+ let concreteExhausted = false;
14263
+ const boundaryGate = (i) => {
14264
+ if (i + 1 !== limit || !isDefinitelyTrue(test())) return;
14265
+ if (limit < MAX_CONCRETE_LOOP_ITERS) {
14266
+ limit = MAX_CONCRETE_LOOP_ITERS;
14267
+ extended = true;
14268
+ } else {
14269
+ concreteExhausted = true;
14270
+ }
14271
+ };
14272
+ for (let i = 0; i < limit; i++) {
14025
14273
  const t = test();
14026
14274
  if (isDefinitelyFalse(t)) {
14027
14275
  applyExitJoin();
14028
14276
  return;
14029
14277
  }
14030
- if (!isDefinitelyTrue(t)) snapExit();
14278
+ if (!isDefinitelyTrue(t)) {
14279
+ if (extended) break;
14280
+ snapExit();
14281
+ }
14031
14282
  try {
14032
14283
  body();
14033
14284
  } catch (e) {
@@ -14035,12 +14286,21 @@ function $whileSeq(test, body, maxIters = DEFAULT_MAX_LOOP_ITERS, opts) {
14035
14286
  applyExitJoin();
14036
14287
  return;
14037
14288
  }
14038
- if (isNudoContinue(e, opts?.label)) continue;
14289
+ if (isNudoContinue(e, opts?.label)) {
14290
+ boundaryGate(i);
14291
+ continue;
14292
+ }
14039
14293
  if (isNudoReturn(e) || isNudoThrow(e)) throw e;
14040
14294
  throw e;
14041
14295
  }
14296
+ boundaryGate(i);
14042
14297
  }
14043
14298
  snapExit();
14299
+ if (concreteExhausted) {
14300
+ noteAbsTruncation(LOOP_TRUNCATION_LABEL);
14301
+ if (exitJoin && pack && unpack) unpack(confPartialPacked(joinAbs(exitJoin, pack())));
14302
+ return;
14303
+ }
14044
14304
  applyExitJoin();
14045
14305
  }
14046
14306
  function $switch(disc, cases, dflt) {
@@ -14195,6 +14455,19 @@ function $yield(v2) {
14195
14455
  if (top) top.push(v2);
14196
14456
  return unknown;
14197
14457
  }
14458
+ function $removeNullish(a) {
14459
+ if (!a || typeof a !== "object" || !("shape" in a)) return a;
14460
+ if (definitelyNotNullishShape(a.shape)) return a;
14461
+ if (isNullishLitAbs(a)) return a;
14462
+ if (a.shape.k === "sum") {
14463
+ const members = a.shape.members;
14464
+ const kept = members.filter((m) => !isNullishLitAbs(m));
14465
+ if (kept.length === members.length) return a;
14466
+ if (kept.length === 0) return a;
14467
+ return kept.length === 1 ? kept[0] : { ...a, shape: { k: "sum", members: kept } };
14468
+ }
14469
+ return a;
14470
+ }
14198
14471
  function $nullishTest(v2) {
14199
14472
  if (definitelyNotNullishShape(v2.shape)) return boolLit(false);
14200
14473
  if (isNullishLitAbs(v2)) return boolLit(true);
@@ -14250,60 +14523,6 @@ __export(calls_exports, {
14250
14523
  setEvalCallCollector: () => setEvalCallCollector,
14251
14524
  withEvalBudgetOverride: () => withEvalBudgetOverride
14252
14525
  });
14253
-
14254
- // src/algebra/lru-map.ts
14255
- var BoundedLruMap = class {
14256
- map = /* @__PURE__ */ new Map();
14257
- max;
14258
- constructor(max) {
14259
- this.max = max;
14260
- }
14261
- get size() {
14262
- return this.map.size;
14263
- }
14264
- getMax() {
14265
- return this.max;
14266
- }
14267
- setMax(max) {
14268
- this.max = max;
14269
- this.trim();
14270
- }
14271
- has(key) {
14272
- return this.map.has(key);
14273
- }
14274
- get(key) {
14275
- const hit = this.map.get(key);
14276
- if (hit === void 0) return void 0;
14277
- this.map.delete(key);
14278
- this.map.set(key, hit);
14279
- return hit;
14280
- }
14281
- set(key, value) {
14282
- if (this.max <= 0) return;
14283
- while (this.map.size >= this.max && !this.map.has(key)) {
14284
- const oldest = this.map.keys().next().value;
14285
- if (oldest === void 0) break;
14286
- this.map.delete(oldest);
14287
- }
14288
- this.map.delete(key);
14289
- this.map.set(key, value);
14290
- }
14291
- delete(key) {
14292
- return this.map.delete(key);
14293
- }
14294
- clear() {
14295
- this.map.clear();
14296
- }
14297
- trim() {
14298
- while (this.map.size > this.max) {
14299
- const oldest = this.map.keys().next().value;
14300
- if (oldest === void 0) break;
14301
- this.map.delete(oldest);
14302
- }
14303
- }
14304
- };
14305
-
14306
- // src/algebra/exec/calls.ts
14307
14526
  var PURE_CALL_MEMO_MAX = 256;
14308
14527
  var pureCallMemo = /* @__PURE__ */ new WeakMap();
14309
14528
  function clearPureCallMemo() {
@@ -14315,14 +14534,17 @@ function joinThrowsSince(mark) {
14315
14534
  if (items.length === 1) return items[0];
14316
14535
  return items.reduce((a, b) => joinAbs(a, b));
14317
14536
  }
14318
- var evalCallCollector = null;
14319
- var evalAssignCollector = null;
14320
- function setEvalAssignCollector(collector2) {
14321
- const prev = evalAssignCollector;
14322
- evalAssignCollector = collector2;
14537
+ var evalCallCollectorSlot = createScopedSlot(() => null);
14538
+ registerCollectorScopeParticipant((body) => evalCallCollectorSlot.runScoped(body));
14539
+ var evalAssignCollectorSlot = createScopedSlot(() => null);
14540
+ registerCollectorScopeParticipant((body) => evalAssignCollectorSlot.runScoped(body));
14541
+ function setEvalAssignCollector(collector) {
14542
+ const prev = evalAssignCollectorSlot.get();
14543
+ evalAssignCollectorSlot.set(collector);
14323
14544
  return prev;
14324
14545
  }
14325
14546
  function $assignRecord(name, prev, next, line, column, conditional) {
14547
+ const evalAssignCollector = evalAssignCollectorSlot.get();
14326
14548
  if (!evalAssignCollector) return;
14327
14549
  try {
14328
14550
  evalAssignCollector({
@@ -14336,11 +14558,13 @@ function $assignRecord(name, prev, next, line, column, conditional) {
14336
14558
  } catch {
14337
14559
  }
14338
14560
  }
14339
- var bindingSink = null;
14561
+ var bindingSinkSlot = createScopedSlot(() => null);
14562
+ registerCollectorScopeParticipant((body) => bindingSinkSlot.runScoped(body));
14340
14563
  function setEvalBindingSink(sink) {
14341
- bindingSink = sink;
14564
+ bindingSinkSlot.set(sink);
14342
14565
  }
14343
14566
  function $recordBinding(name, value) {
14567
+ const bindingSink = bindingSinkSlot.get();
14344
14568
  if (bindingSink) bindingSink.set(name, value);
14345
14569
  }
14346
14570
  var GLOBAL_FNS = /* @__PURE__ */ new Set([
@@ -14399,19 +14623,20 @@ function blockHostSideEffect(fn) {
14399
14623
  return abs({ k: "unknown" }, void 0, void 0, "opaque");
14400
14624
  }
14401
14625
  function noteEvalCallRecord(r) {
14626
+ const evalCallCollector = evalCallCollectorSlot.get();
14402
14627
  if (!evalCallCollector) return;
14403
14628
  try {
14404
14629
  evalCallCollector(r);
14405
14630
  } catch {
14406
14631
  }
14407
14632
  }
14408
- function setEvalCallCollector(collector2) {
14409
- const prev = evalCallCollector;
14410
- evalCallCollector = collector2;
14633
+ function setEvalCallCollector(collector) {
14634
+ const prev = evalCallCollectorSlot.get();
14635
+ evalCallCollectorSlot.set(collector);
14411
14636
  return prev;
14412
14637
  }
14413
14638
  function getEvalCallCollector() {
14414
- return evalCallCollector;
14639
+ return evalCallCollectorSlot.get();
14415
14640
  }
14416
14641
  var MAX_EVAL_CALL_DEPTH = 64;
14417
14642
  var MAX_EVAL_TOTAL_CALLS = 2e4;
@@ -14575,6 +14800,7 @@ function $callNamed(name, fn, args, loc, argLocs) {
14575
14800
  }
14576
14801
  m.set(pk, makeAbsApplyResult(result, joinThrowsSince(throwMark)));
14577
14802
  }
14803
+ const evalCallCollector = evalCallCollectorSlot.get();
14578
14804
  if (evalCallCollector) {
14579
14805
  try {
14580
14806
  evalCallCollector({
@@ -15411,13 +15637,24 @@ function invokeArrMethod(arr, method, args) {
15411
15637
  kept.push(el2);
15412
15638
  });
15413
15639
  if (kept.length === 0) {
15414
- return abs({ k: "arr", element: unknown }, void 0, void 0, "path");
15640
+ return abs({ k: "tuple", elements: [] }, void 0, void 0, confJoin(arr.conf, "path"));
15415
15641
  }
15416
15642
  if (!anyUncertain) {
15417
15643
  return abs({ k: "tuple", elements: kept }, void 0, void 0, confJoin(arr.conf, "path"));
15418
15644
  }
15645
+ const conf = confJoin(arr.conf, "path");
15646
+ if (kept.length <= 3) {
15647
+ let acc;
15648
+ const total = 1 << kept.length;
15649
+ for (let mask = 0; mask < total; mask++) {
15650
+ const els = kept.filter((_, bit) => (mask & 1 << bit) !== 0);
15651
+ const sub2 = abs({ k: "tuple", elements: els }, void 0, void 0, conf);
15652
+ acc = acc === void 0 ? sub2 : joinAbs(acc, sub2);
15653
+ }
15654
+ return acc;
15655
+ }
15419
15656
  const el = kept.reduce((a, b) => joinAbs(a, b));
15420
- return abs({ k: "arr", element: el }, void 0, void 0, confJoin(arr.conf, "path"));
15657
+ return abs({ k: "arr", element: el }, void 0, void 0, conf);
15421
15658
  }
15422
15659
  return arr;
15423
15660
  }
@@ -15784,6 +16021,9 @@ function rtAllBindings() {
15784
16021
  return cached;
15785
16022
  }
15786
16023
 
16024
+ // src/algebra/exec/run.ts
16025
+ import { parse as babelParse2 } from "@babel/parser";
16026
+
15787
16027
  // src/algebra/abs-modules.ts
15788
16028
  function namespaceAbsOf(mod2) {
15789
16029
  const slots = {};
@@ -15969,76 +16209,87 @@ function rewriteUserImports(js) {
15969
16209
  );
15970
16210
  }
15971
16211
  function stripEffectfulTopLevel(js) {
16212
+ let body;
16213
+ try {
16214
+ body = babelParse2(js, {
16215
+ sourceType: "module",
16216
+ allowReturnOutsideFunction: true,
16217
+ attachComment: false
16218
+ }).program.body;
16219
+ } catch {
16220
+ return js;
16221
+ }
15972
16222
  const declared = /* @__PURE__ */ new Set();
15973
- for (const m of js.matchAll(/^(?:export\s+)?(?:async\s+)?function\s*\*?\s*([A-Za-z_$][\w$]*)/gm)) {
15974
- declared.add(m[1]);
16223
+ for (const stmt of body) collectTopLevelDeclared(stmt, declared);
16224
+ const cuts = [];
16225
+ for (const stmt of body) {
16226
+ if (isEffectfulTopLevelStmt(stmt, declared)) cuts.push([stmt.start, stmt.end]);
15975
16227
  }
15976
- for (const m of js.matchAll(/^(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)/gm)) {
15977
- declared.add(m[1]);
16228
+ if (cuts.length === 0) return js;
16229
+ let out = "";
16230
+ let pos = 0;
16231
+ for (const [start, end] of cuts) {
16232
+ out += js.slice(pos, start);
16233
+ pos = end;
16234
+ while (pos < js.length && js[pos] === ";") pos++;
16235
+ const nl = js.indexOf("\n", pos);
16236
+ const lineRest = js.slice(pos, nl === -1 ? js.length : nl);
16237
+ if (/^\s*$/.test(lineRest)) pos = nl === -1 ? js.length : nl + 1;
16238
+ }
16239
+ return out + js.slice(pos);
16240
+ }
16241
+ function collectTopLevelDeclared(stmt, declared) {
16242
+ const decl = stmt.type === "ExportNamedDeclaration" || stmt.type === "ExportDefaultDeclaration" ? stmt.declaration : stmt;
16243
+ if (!decl) return;
16244
+ if ((decl.type === "FunctionDeclaration" || decl.type === "ClassDeclaration") && decl.id) {
16245
+ declared.add(decl.id.name);
16246
+ return;
15978
16247
  }
15979
- for (const m of js.matchAll(/^import\s*\{([^}]+)\}\s*from/gm)) {
15980
- for (const part of m[1].split(",")) {
15981
- const local = part.split(/\s+as\s+/).pop()?.trim();
15982
- if (local) declared.add(local);
16248
+ if (decl.type === "VariableDeclaration") {
16249
+ for (const d of decl.declarations) {
16250
+ if (d.id.type === "Identifier") declared.add(d.id.name);
15983
16251
  }
16252
+ return;
15984
16253
  }
15985
- for (const m of js.matchAll(/^import\s+\*\s+as\s+([A-Za-z_$][\w$]*)/gm)) {
15986
- declared.add(m[1]);
16254
+ if (decl.type === "ImportDeclaration") {
16255
+ for (const spec of decl.specifiers) declared.add(spec.local.name);
15987
16256
  }
15988
- for (const m of js.matchAll(/^import\s+([A-Za-z_$][\w$]*)\s*,/gm)) {
15989
- declared.add(m[1]);
16257
+ }
16258
+ function isEffectfulTopLevelStmt(stmt, declared) {
16259
+ switch (stmt.type) {
16260
+ case "ExpressionStatement":
16261
+ return isEffectfulTopLevelExpr(stmt.expression, declared);
16262
+ // 源形态控制流(transpile 后不出现,兜底口径与旧正则一致;do-while 旧正则不剥,保持)
16263
+ case "IfStatement":
16264
+ case "ForStatement":
16265
+ case "ForInStatement":
16266
+ case "ForOfStatement":
16267
+ case "WhileStatement":
16268
+ return true;
16269
+ default:
16270
+ return false;
15990
16271
  }
15991
- const lines = js.split("\n");
15992
- const out = [];
15993
- let i = 0;
15994
- while (i < lines.length) {
15995
- const line = lines[i];
15996
- const isTop = /^\S/.test(line) && line.trim().length > 0;
15997
- const t = line.trim();
15998
- if (isTop) {
15999
- if (/^(console\.|fetch\s*\(|setTimeout\s*\(|setInterval\s*\()/.test(t)) {
16000
- while (i < lines.length && !lines[i].trim().endsWith(";") && !lines[i].trim().endsWith("}")) i++;
16001
- i++;
16002
- continue;
16003
- }
16004
- const namedCall = t.match(/^\$callNamed\(\s*"([^"]+)"/);
16005
- if (namedCall && !declared.has(namedCall[1])) {
16006
- while (i < lines.length && !lines[i].trim().endsWith(";") && !lines[i].trim().endsWith("}")) i++;
16007
- i++;
16008
- continue;
16009
- }
16010
- const callMatch = t.match(/^([A-Za-z_$][\w$]*)\s*\(/);
16011
- if (callMatch && !callMatch[1].startsWith("$") && callMatch[1] !== "__nudoExport" && callMatch[1] !== "__nudoExportStar" && callMatch[1] !== "__nudoRecordBinding" && callMatch[1] !== "__nudoRecordAssign" && !declared.has(callMatch[1]) && !/^(const|let|var|function|export|import|return|if|for|while|switch|try|throw|class)\b/.test(t)) {
16012
- while (i < lines.length && !lines[i].trim().endsWith(";") && !lines[i].trim().endsWith("}")) i++;
16013
- i++;
16014
- continue;
16015
- }
16016
- if (/^(if\s*\(|for\s*\(|while\s*\(|\$fork\s*\(|\$for\s*\(|\$while)/.test(t)) {
16017
- i++;
16018
- if (/^\$/.test(t)) {
16019
- let depth = (t.match(/\(/g) || []).length - (t.match(/\)/g) || []).length;
16020
- while (i < lines.length && depth > 0) {
16021
- const l = lines[i];
16022
- depth += (l.match(/\(/g) || []).length;
16023
- depth -= (l.match(/\)/g) || []).length;
16024
- i++;
16025
- }
16026
- } else {
16027
- let depth = t.includes("{") ? 1 : 0;
16028
- while (i < lines.length && depth > 0) {
16029
- const l = lines[i];
16030
- depth += (l.match(/\{/g) || []).length;
16031
- depth -= (l.match(/\}/g) || []).length;
16032
- i++;
16033
- }
16034
- }
16035
- continue;
16036
- }
16037
- }
16038
- out.push(line);
16039
- i++;
16272
+ }
16273
+ function isEffectfulTopLevelExpr(expr, declared) {
16274
+ if (expr.type !== "CallExpression") return false;
16275
+ const callee = expr.callee;
16276
+ if (callee.type === "MemberExpression" && memberChainRoot(callee) === "console") {
16277
+ return true;
16040
16278
  }
16041
- return out.join("\n");
16279
+ if (callee.type !== "Identifier") return false;
16280
+ const name = callee.name;
16281
+ if (name === "fetch" || name === "setTimeout" || name === "setInterval") return true;
16282
+ if (name === "$callNamed") {
16283
+ const first = expr.arguments[0];
16284
+ return first?.type === "StringLiteral" && !declared.has(first.value);
16285
+ }
16286
+ if (name === "$for" || name === "$fork" || name.startsWith("$while")) return true;
16287
+ return !name.startsWith("$") && name !== "__nudoExport" && name !== "__nudoExportStar" && name !== "__nudoRecordBinding" && name !== "__nudoRecordAssign" && !declared.has(name);
16288
+ }
16289
+ function memberChainRoot(member) {
16290
+ let node = member.object;
16291
+ while (node.type === "MemberExpression") node = node.object;
16292
+ return node.type === "Identifier" ? node.name : void 0;
16042
16293
  }
16043
16294
  function runtimeArgNames() {
16044
16295
  return Object.keys(rtAllBindings()).filter((k) => k.startsWith("$"));
@@ -16123,17 +16374,19 @@ function rewriteExportStatements(js) {
16123
16374
  );
16124
16375
  }
16125
16376
  var runBindings = /* @__PURE__ */ new WeakMap();
16126
- var ENV_SHADOW_SKIP = HOST_INTRINSIC_SET;
16377
+ var ENV_SHADOW_SKIP = ENV_SHADOW_SKIP_GLOBALS;
16127
16378
  function bindingsOf(run) {
16128
16379
  return runBindings.get(run);
16129
16380
  }
16130
16381
  function runTranspiled(source, opts = {}) {
16131
- enterEvalCallBudgetSession();
16132
- try {
16133
- return runTranspiledInner(source, opts);
16134
- } finally {
16135
- exitEvalCallBudgetSession();
16136
- }
16382
+ return runWithCollectorScope(() => {
16383
+ enterEvalCallBudgetSession();
16384
+ try {
16385
+ return runTranspiledInner(source, opts);
16386
+ } finally {
16387
+ exitEvalCallBudgetSession();
16388
+ }
16389
+ });
16137
16390
  }
16138
16391
  function runTranspiledInner(source, opts) {
16139
16392
  const modules = opts.modules ?? {};
@@ -16256,9 +16509,10 @@ function noteDrainedClassCollisions() {
16256
16509
  );
16257
16510
  }
16258
16511
  }
16259
- var evalFallbackCollector = null;
16260
- function setEvalFallbackCollector(collector2) {
16261
- evalFallbackCollector = collector2;
16512
+ var evalFallbackCollectorSlot = createScopedSlot(() => null);
16513
+ registerCollectorScopeParticipant((body) => evalFallbackCollectorSlot.runScoped(body));
16514
+ function setEvalFallbackCollector(collector) {
16515
+ evalFallbackCollectorSlot.set(collector);
16262
16516
  }
16263
16517
  function evalExprAbs(expr, bindings = {}) {
16264
16518
  const src = transpileExpression(expr, {});
@@ -16296,6 +16550,7 @@ function noteEvalFallback(e) {
16296
16550
  if (f.reason === "internal") _fbInternal++;
16297
16551
  else if (f.reason === "module-throw") _fbModuleThrow++;
16298
16552
  else if (f.reason.startsWith("unsupported:")) _fbUnsupported++;
16553
+ const evalFallbackCollector = evalFallbackCollectorSlot.get();
16299
16554
  if (!evalFallbackCollector) return;
16300
16555
  try {
16301
16556
  evalFallbackCollector(f);
@@ -16314,20 +16569,22 @@ function isAbsVal(v2) {
16314
16569
  return !!v2 && typeof v2 === "object" && "shape" in v2 && "conf" in v2;
16315
16570
  }
16316
16571
  function callTranspiledExportFull(exports, name, args, opts) {
16317
- enterEvalCallBudgetSession();
16318
- beginClassEpoch();
16319
- try {
16320
- return callTranspiledExportFullInner(exports, name, args, opts);
16321
- } finally {
16322
- exitEvalCallBudgetSession();
16323
- noteDrainedClassCollisions();
16324
- }
16572
+ return runWithCollectorScope(() => {
16573
+ enterEvalCallBudgetSession();
16574
+ beginClassEpoch();
16575
+ try {
16576
+ return callTranspiledExportFullInner(exports, name, args, opts);
16577
+ } finally {
16578
+ exitEvalCallBudgetSession();
16579
+ noteDrainedClassCollisions();
16580
+ }
16581
+ });
16325
16582
  }
16326
16583
  function callTranspiledExportFullInner(exports, name, args, opts) {
16327
16584
  const fn = Object.hasOwn(exports, name) ? exports[name] : void 0;
16328
16585
  if (typeof fn === "function") {
16329
16586
  const callArgs = args.map(
16330
- (a) => a && typeof a === "object" && "shape" in a ? $copy(a) : a
16587
+ (a) => a && typeof a === "object" && "shape" in a ? $copy(a) : asAbsVal(a)
16331
16588
  );
16332
16589
  return runWithLoopExits(() => {
16333
16590
  try {
@@ -16999,6 +17256,9 @@ export {
16999
17256
  litKeyString,
17000
17257
  termToString,
17001
17258
  simplifyTerm,
17259
+ createScopedSlot,
17260
+ registerCollectorScopeParticipant,
17261
+ runWithCollectorScope,
17002
17262
  TYPEOF_NAMES,
17003
17263
  primToTypeof,
17004
17264
  pTrue,
@@ -17053,6 +17313,10 @@ export {
17053
17313
  isBigPrim,
17054
17314
  isExactLit,
17055
17315
  litValue,
17316
+ absNumLit,
17317
+ absStrLit,
17318
+ allAbsStr,
17319
+ absLit,
17056
17320
  stripTypes,
17057
17321
  resetParseSourceCache,
17058
17322
  getParseSourceCacheSize,
@@ -17210,6 +17474,31 @@ export {
17210
17474
  isNudoContinue,
17211
17475
  $isBreakTo,
17212
17476
  $rethrowIfNudoReturn,
17477
+ MAX_CALL_DEPTH,
17478
+ MAX_TOTAL_CALLS,
17479
+ getAbsCallBudgetStats,
17480
+ resetAbsCallBudget,
17481
+ withFnBudgetOverride,
17482
+ stableCallId,
17483
+ truncatedAbs,
17484
+ callBudgetKey,
17485
+ setAbsTruncationCollector,
17486
+ noteAbsTruncation,
17487
+ enterCall,
17488
+ exitCall,
17489
+ MAX_EVAL_TOTAL_FORKS,
17490
+ FORK_TRUNCATION_LABEL,
17491
+ HOST_EFFECT_LABEL_PREFIX,
17492
+ PROMISE_MICRO_OVERFLOW_LABEL,
17493
+ PROMISE_MICRO_ERROR_LABEL,
17494
+ MATH_FOLD_ERROR_LABEL,
17495
+ noteHostEffectBlocked,
17496
+ noteEvalForkTruncation,
17497
+ setEvalForkBudgetLimit,
17498
+ getEvalForkBudgetLimit,
17499
+ getEvalForkCount,
17500
+ resetEvalForkBudget,
17501
+ bumpEvalForkBudget,
17213
17502
  evalMathMethod,
17214
17503
  builtinCtorAbs,
17215
17504
  builtinCtorNameOf,
@@ -17275,30 +17564,6 @@ export {
17275
17564
  regexBrandAbsFrom,
17276
17565
  tryMakeRegexAbs,
17277
17566
  evalRegExpMethod,
17278
- MAX_CALL_DEPTH,
17279
- MAX_TOTAL_CALLS,
17280
- getAbsCallBudgetStats,
17281
- resetAbsCallBudget,
17282
- withFnBudgetOverride,
17283
- stableCallId,
17284
- truncatedAbs,
17285
- callBudgetKey,
17286
- setAbsTruncationCollector,
17287
- noteAbsTruncation,
17288
- enterCall,
17289
- exitCall,
17290
- MAX_EVAL_TOTAL_FORKS,
17291
- FORK_TRUNCATION_LABEL,
17292
- HOST_EFFECT_LABEL_PREFIX,
17293
- PROMISE_MICRO_OVERFLOW_LABEL,
17294
- PROMISE_MICRO_ERROR_LABEL,
17295
- noteHostEffectBlocked,
17296
- noteEvalForkTruncation,
17297
- setEvalForkBudgetLimit,
17298
- getEvalForkBudgetLimit,
17299
- getEvalForkCount,
17300
- resetEvalForkBudget,
17301
- bumpEvalForkBudget,
17302
17567
  enterPromiseExecutorScope,
17303
17568
  leavePromiseExecutorScope,
17304
17569
  notePromiseExecutorFork,
@@ -17479,6 +17744,7 @@ export {
17479
17744
  $asyncReturn,
17480
17745
  $gen,
17481
17746
  $yield,
17747
+ $removeNullish,
17482
17748
  $nullishTest,
17483
17749
  $reStateCall,
17484
17750
  $class,