supercov 2.0.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +19 -22
  2. package/docs/agent-loop.md +8 -13
  3. package/docs/assertions.md +161 -75
  4. package/docs/cli.md +111 -59
  5. package/docs/coverage-model.md +5 -6
  6. package/docs/evidence.md +0 -11
  7. package/docs/getting-started.md +1 -1
  8. package/docs/performance.md +6 -14
  9. package/docs/quality.md +1 -1
  10. package/docs/security.md +43 -12
  11. package/docs/supported-suites.md +44 -48
  12. package/docs/troubleshooting.md +12 -5
  13. package/docs/workspace-isolation.md +23 -2
  14. package/package.json +33 -21
  15. package/runtime/javascript/atomic.mjs +46 -2
  16. package/runtime/javascript/ava.mjs +82 -0
  17. package/runtime/javascript/bootstrap.cjs +43 -0
  18. package/runtime/javascript/jest.cjs +52 -15
  19. package/runtime/javascript/jest.config.mjs +9 -1
  20. package/runtime/javascript/jestReporter.mjs +5 -6
  21. package/runtime/javascript/launchSupervisor.mjs +127 -15
  22. package/runtime/javascript/mocha.mjs +180 -0
  23. package/runtime/javascript/nodeTest.mjs +57 -3
  24. package/runtime/javascript/playwright.mjs +241 -32
  25. package/runtime/javascript/provenance.mjs +1 -1
  26. package/runtime/javascript/register.mjs +290 -2
  27. package/runtime/javascript/resolve-loader.mjs +40 -1
  28. package/runtime/javascript/runnerEvidence.mjs +3 -5
  29. package/runtime/javascript/runtime.mjs +551 -61
  30. package/runtime/javascript/tap.mjs +130 -0
  31. package/runtime/javascript/transport.mjs +7 -2
  32. package/runtime/javascript/vitest.mjs +5 -8
  33. package/runtime/javascript/vitestReporter.mjs +3 -10
  34. package/docs/assertion-agent.md +0 -150
  35. package/docs/assertion-evidence.md +0 -103
  36. package/docs/assertion-maps.md +0 -316
  37. package/schemas/assertions.schema.json +0 -276
@@ -1,10 +1,13 @@
1
1
  var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
2
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
3
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
4
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
+ // The runtime runs inside the application under test, and its tests may
6
+ // pollute Object.prototype on purpose: axios's set `Object.prototype.get`, and
7
+ // a descriptor that inherits `get` makes defineProperty throw "Getter must be a
8
+ // function", failing tests that pass without Supercov. Every descriptor here has
9
+ // no prototype, and spreading copies values rather than descriptors.
10
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { __proto__: null, enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
11
  var __spreadValues = (a, b) => {
9
12
  for (var prop in b || (b = {}))
10
13
  if (__hasOwnProp.call(b, prop))
@@ -16,7 +19,15 @@ var __spreadValues = (a, b) => {
16
19
  }
17
20
  return a;
18
21
  };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
22
+ var __spreadProps = (a, b) => __spreadValues(a, b);
23
+
24
+ // Buffer as it was when Supercov loaded. Tests replace globals -- axios's set
25
+ // `globalThis.Buffer = undefined` to check it copes -- and the runtime runs
26
+ // inside those tests; it must not fail where the application does not.
27
+ var capturedBuffer = typeof Buffer === "undefined" ? void 0 : Buffer;
28
+ // Likewise the timer: a test that installs fake timers would otherwise hold
29
+ // the browser's evidence back until it advanced its clock.
30
+ var capturedSetTimeout = setTimeout;
20
31
 
21
32
  // dist/transport.js
22
33
  var COVERAGE_SCOPE_HEADER = "x-supercov-scope";
@@ -77,13 +88,13 @@ function decodeCoverageScope(encoded) {
77
88
  }
78
89
  }
79
90
  function encodeCoverageCarrier(carrier) {
80
- return Buffer.from(JSON.stringify(carrier), "utf8").toString("base64url");
91
+ return capturedBuffer.from(JSON.stringify(carrier), "utf8").toString("base64url");
81
92
  }
82
93
  function decodeCoverageCarrier(encoded) {
83
94
  if (!encoded)
84
95
  return void 0;
85
96
  try {
86
- const value = JSON.parse(Buffer.from(encoded, "base64url").toString("utf8"));
97
+ const value = JSON.parse(capturedBuffer.from(encoded, "base64url").toString("utf8"));
87
98
  if (value.version !== 1)
88
99
  return void 0;
89
100
  if (value.scope) {
@@ -154,6 +165,8 @@ function createState() {
154
165
  backgroundBuffers: /* @__PURE__ */ new Map(),
155
166
  backgroundWriters: /* @__PURE__ */ new Map(),
156
167
  backgroundShardSizes: /* @__PURE__ */ new Map(),
168
+ backgroundDescriptors: /* @__PURE__ */ new Map(),
169
+ pendingBackgroundAppends: /* @__PURE__ */ new Map(),
157
170
  backgroundSequence: 0,
158
171
  runtimeSnapshots: false,
159
172
  assertionPhases: /* @__PURE__ */ new Map(),
@@ -330,6 +343,80 @@ function resetCoverage(testId2) {
330
343
  runtimeGlobal.__SUPERCOV_MCDC_SNAPSHOT__ = decisionSnapshot;
331
344
  runtimeGlobal.__SUPERCOV_COVERAGE_SNAPSHOT__ = coverageSnapshot;
332
345
  runtimeGlobal.__SUPERCOV_RESET__ = resetCoverage;
346
+ // A dedicated worker blocked in `Atomics.wait` runs no evaluation, so the
347
+ // test runner could not read its evidence and reported the test as a lower
348
+ // bound: Actual's database worker waits that way between every query. The
349
+ // worker pushes its evidence to its pages instead, on a BroadcastChannel,
350
+ // each time it is about to block with something recorded since its last
351
+ // push; a worker that wakes and records something new says its push is no
352
+ // longer current. A page keeps the latest push of each worker, and the runner
353
+ // reads that when the worker itself does not answer: complete when current.
354
+ var workerEvidenceChannelName = "__supercov_worker_evidence__";
355
+ var workerEvidence = null;
356
+ function workerEvidenceChanged() {
357
+ if (workerEvidence === null || workerEvidence.changed)
358
+ return;
359
+ workerEvidence.changed = true;
360
+ if (!workerEvidence.pushed)
361
+ return;
362
+ workerEvidence.pushed = false;
363
+ try {
364
+ workerEvidence.channel.postMessage({ token: workerEvidence.token, current: false });
365
+ } catch (e) {
366
+ }
367
+ }
368
+ function pushWorkerEvidence() {
369
+ if (workerEvidence === null || workerEvidence.pushed)
370
+ return;
371
+ workerEvidence.changed = false;
372
+ workerEvidence.pushed = true;
373
+ try {
374
+ workerEvidence.channel.postMessage({ token: workerEvidence.token, url: workerEvidence.url, current: true, snapshot: coverageSnapshot() });
375
+ } catch (e) {
376
+ workerEvidence.pushed = false;
377
+ }
378
+ }
379
+ (function installWorkerEvidenceTransport() {
380
+ if (!isBrowser || typeof BroadcastChannel !== "function")
381
+ return;
382
+ if (typeof WorkerGlobalScope === "function" && runtimeGlobal instanceof WorkerGlobalScope) {
383
+ if (typeof Atomics !== "object" || typeof Atomics.wait !== "function" || runtimeGlobal.__SUPERCOV_WORKER_TOKEN__)
384
+ return;
385
+ try {
386
+ const token = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
387
+ const url = runtimeGlobal.location ? String(runtimeGlobal.location.href) : "";
388
+ workerEvidence = { channel: new BroadcastChannel(workerEvidenceChannelName), token, url, changed: true, pushed: false };
389
+ runtimeGlobal.__SUPERCOV_WORKER_TOKEN__ = token;
390
+ const wait = Atomics.wait;
391
+ Atomics.wait = function wait2(typedArray, index, value, timeout) {
392
+ pushWorkerEvidence();
393
+ return Reflect.apply(wait, Atomics, arguments);
394
+ };
395
+ } catch (e) {
396
+ workerEvidence = null;
397
+ }
398
+ return;
399
+ }
400
+ if (typeof document === "undefined" || runtimeGlobal.__SUPERCOV_WORKER_EVIDENCE__)
401
+ return;
402
+ const received = /* @__PURE__ */ new Map();
403
+ try {
404
+ const channel = new BroadcastChannel(workerEvidenceChannelName);
405
+ channel.onmessage = (event) => {
406
+ const message = event.data;
407
+ if (!message || typeof message.token !== "string")
408
+ return;
409
+ const pushed = received.get(message.token);
410
+ if (message.current)
411
+ received.set(message.token, { url: message.url, snapshot: message.snapshot, current: true });
412
+ else if (pushed)
413
+ pushed.current = false;
414
+ };
415
+ } catch (e) {
416
+ return;
417
+ }
418
+ runtimeGlobal.__SUPERCOV_WORKER_EVIDENCE__ = () => Array.from(received, ([token, pushed]) => ({ token, url: pushed.url, current: pushed.current, snapshot: pushed.snapshot }));
419
+ })();
333
420
  var persistBrowserScheduled = false;
334
421
  var persistBrowserListenersInstalled = false;
335
422
  function persistBrowserNow() {
@@ -361,7 +448,7 @@ function persistBrowser() {
361
448
  if (persistBrowserScheduled)
362
449
  return;
363
450
  persistBrowserScheduled = true;
364
- setTimeout(() => {
451
+ capturedSetTimeout(() => {
365
452
  persistBrowserScheduled = false;
366
453
  persistBrowserNow();
367
454
  }, 0);
@@ -449,15 +536,54 @@ function backgroundWriterToken() {
449
536
  }
450
537
  return Math.floor(Math.random() * 4294967295).toString(16);
451
538
  }
539
+ // Background records -- every first hit under tap, AVA or Mocha, and code run
540
+ // outside any test -- are written once per event-loop turn, as a test's own
541
+ // records are, and on exit and the terminating signals. Written one by one
542
+ // they cost lru-cache's 10 ms TTL test a write and a stat for each of the 132
543
+ // first hits in its window, and the test missed its deadline under load. A
544
+ // process killed in the middle of a turn loses that turn's records.
452
545
  function appendDurableBackgroundRecord(fs, runId, record) {
453
- var _a8;
454
546
  const records = state.backgroundBuffers.get(runId) != null ? state.backgroundBuffers.get(runId) : /* @__PURE__ */ new Map();
455
547
  const key = serverRecordKey(record);
456
548
  if (records.has(key))
457
549
  return state.backgroundWriters.get(runId);
550
+ if (state.serverTransportFailure)
551
+ throw state.serverTransportFailure;
552
+ records.set(key, record);
553
+ state.backgroundBuffers.set(runId, records);
554
+ let pending = state.pendingBackgroundAppends.get(runId);
555
+ if (!pending) {
556
+ pending = [];
557
+ state.pendingBackgroundAppends.set(runId, pending);
558
+ }
559
+ pending.push(JSON.stringify(record) + "\n");
560
+ if (pending.length >= 2048)
561
+ flushServerAppends();
562
+ else
563
+ scheduleServerFlush();
564
+ return state.backgroundWriters.get(runId);
565
+ }
566
+ function flushBackgroundAppends(fs) {
567
+ for (const [runId, lines] of state.pendingBackgroundAppends) {
568
+ state.pendingBackgroundAppends.delete(runId);
569
+ try {
570
+ if (!fs)
571
+ throw new Error("node:fs is unavailable");
572
+ writeBackgroundLines(fs, runId, lines.join(""));
573
+ } catch (cause) {
574
+ const failure = cause instanceof Error && cause.code === "SUPERCOV_EVIDENCE_TRANSPORT_FAILED" ? cause : serverTransportError(runId, cause);
575
+ state.serverTransportFailure = failure;
576
+ throw failure;
577
+ }
578
+ }
579
+ }
580
+ function writeBackgroundLines(fs, runId, payload) {
581
+ var _a8;
458
582
  const directory = backgroundEvidenceDirectory(runId);
459
- const payload = JSON.stringify(record) + "\n";
460
- fs.mkdirSync(directory, { recursive: true });
583
+ if (!state.createdEvidenceDirectories.has(directory)) {
584
+ fs.mkdirSync(directory, { recursive: true });
585
+ state.createdEvidenceDirectories.add(directory);
586
+ }
461
587
  let path = state.backgroundWriters.get(runId);
462
588
  // A pid is not an identity: pool VMs restored from one snapshot run clones
463
589
  // of this very process, same pid and same cached shard path, and their
@@ -470,7 +596,8 @@ function appendDurableBackgroundRecord(fs, runId, record) {
470
596
  currentSize = fs.statSync(path).size;
471
597
  } catch (e) {
472
598
  }
473
- if (currentSize !== (state.backgroundShardSizes.get(path) ?? -1)) {
599
+ if (currentSize !== (state.backgroundShardSizes.has(path) ? state.backgroundShardSizes.get(path) : -1)) {
600
+ closeBackgroundShard(fs, path);
474
601
  path = void 0;
475
602
  }
476
603
  }
@@ -481,14 +608,28 @@ function appendDurableBackgroundRecord(fs, runId, record) {
481
608
  state.backgroundSequence = nextSequence;
482
609
  path = backgroundEvidencePath(runId, `${writer}-${nextSequence - 1}`);
483
610
  state.backgroundWriters.set(runId, path);
484
- state.backgroundShardSizes.set(path, Buffer.byteLength(payload));
485
- } else {
486
- fs.appendFileSync(path, payload);
487
- state.backgroundShardSizes.set(path, (state.backgroundShardSizes.get(path) ?? 0) + Buffer.byteLength(payload));
611
+ state.backgroundShardSizes.set(path, capturedBuffer.byteLength(payload));
612
+ return;
613
+ }
614
+ let descriptor = state.backgroundDescriptors.get(path);
615
+ if (descriptor === void 0) {
616
+ descriptor = fs.openSync(path, "a");
617
+ state.backgroundDescriptors.set(path, descriptor);
618
+ }
619
+ const bytes = capturedBuffer.from(payload);
620
+ for (let written = 0; written < bytes.length; )
621
+ written += fs.writeSync(descriptor, bytes, written, bytes.length - written);
622
+ state.backgroundShardSizes.set(path, (state.backgroundShardSizes.get(path) || 0) + bytes.length);
623
+ }
624
+ function closeBackgroundShard(fs, path) {
625
+ const descriptor = state.backgroundDescriptors.get(path);
626
+ if (descriptor === void 0)
627
+ return;
628
+ state.backgroundDescriptors.delete(path);
629
+ try {
630
+ fs.closeSync(descriptor);
631
+ } catch (e) {
488
632
  }
489
- records.set(key, record);
490
- state.backgroundBuffers.set(runId, records);
491
- return path;
492
633
  }
493
634
  var _a7;
494
635
  // Evidence buffered for the current turn is lost when a signal ends the
@@ -560,9 +701,10 @@ function serverTransportError(runId, cause) {
560
701
  }
561
702
  function flushServerAppends() {
562
703
  const pending = state.pendingServerAppends;
563
- if (pending.size === 0)
704
+ if (pending.size === 0 && state.pendingBackgroundAppends.size === 0)
564
705
  return;
565
706
  const fs = getFs();
707
+ flushBackgroundAppends(fs);
566
708
  for (const [path, entry] of pending) {
567
709
  pending.delete(path);
568
710
  try {
@@ -593,6 +735,9 @@ function enqueueServerAppend(directory, path, line, runId) {
593
735
  } else {
594
736
  state.pendingServerAppends.set(path, { directory, runId, lines: [line] });
595
737
  }
738
+ scheduleServerFlush();
739
+ }
740
+ function scheduleServerFlush() {
596
741
  if (!state.serverExitHookInstalled && typeof process !== "undefined") {
597
742
  state.serverExitHookInstalled = true;
598
743
  try {
@@ -676,11 +821,19 @@ function appendServer(record) {
676
821
  throw serverTransportError(runId, cause);
677
822
  }
678
823
  }
824
+ // Read on every probe outside a test, and the variable rarely changes: decode
825
+ // it once per value.
826
+ var decodedEnvironmentCarrier = { raw: void 0, context: void 0 };
679
827
  function environmentRequestContext() {
680
828
  if (isBrowser || typeof process === "undefined")
681
829
  return void 0;
682
- const carrier = decodeCoverageCarrier(process.env[COVERAGE_CARRIER_ENV]);
683
- return carrier ? __spreadValues(__spreadValues({}, carrier.scope ? { scope: carrier.scope } : {}), carrier.phaseId ? { phaseId: carrier.phaseId } : {}) : void 0;
830
+ const raw = process.env[COVERAGE_CARRIER_ENV];
831
+ if (raw === decodedEnvironmentCarrier.raw)
832
+ return decodedEnvironmentCarrier.context;
833
+ const carrier = decodeCoverageCarrier(raw);
834
+ const context = carrier ? __spreadValues(__spreadValues({}, carrier.scope ? { scope: carrier.scope } : {}), carrier.phaseId ? { phaseId: carrier.phaseId } : {}) : void 0;
835
+ decodedEnvironmentCarrier = { raw, context };
836
+ return context;
684
837
  }
685
838
  function currentRequestContext() {
686
839
  const stored = serverPhaseStorage == null ? void 0 : serverPhaseStorage.getStore();
@@ -718,7 +871,8 @@ function assertionPhaseState(scope) {
718
871
  const key = attemptKey(scope);
719
872
  const existing = state.assertionPhases.get(key);
720
873
  if (existing) {
721
- existing.phaseIds ??= new Set(existing.phases.filter(phase => phase.kind === "assertion").map(phase => phase.id));
874
+ if (existing.phaseIds == null)
875
+ existing.phaseIds = new Set(existing.phases.filter(phase => phase.kind === "assertion").map(phase => phase.id));
722
876
  return existing;
723
877
  }
724
878
  const created = { counter: 0, phases: [], phaseIds: new Set() };
@@ -806,6 +960,92 @@ function bindNodeAssertionPhase(operation, source, target, property = null) {
806
960
  const receiver = property === null ? undefined : target;
807
961
  return (...args) => withNodeAssertionPhase(operation, source, () => Reflect.apply(callback, receiver, args));
808
962
  }
963
+ // withCoverageCarrier for code that runs in place rather than in a callback:
964
+ // the carrier holds until the returned function restores what it replaced.
965
+ // Opened and restored within one synchronous run, it is what run() does.
966
+ function enterCoverageCarrier(carrier) {
967
+ if (!serverPhaseStorage)
968
+ return () => {
969
+ };
970
+ const previousStore = serverPhaseStorage.getStore();
971
+ const previousEpoch = state.probeV2Clock.epoch;
972
+ const context = __spreadValues(__spreadValues({}, carrier.scope ? { scope: carrier.scope } : {}), carrier.phaseId ? { phaseId: carrier.phaseId } : {});
973
+ serverPhaseStorage.enterWith(context);
974
+ activateProbeV2Context(context);
975
+ return () => {
976
+ serverPhaseStorage.enterWith(previousStore);
977
+ state.probeV2Clock.epoch = previousEpoch;
978
+ };
979
+ }
980
+ var inertAssertionPhase = { close: (value) => value, fail: (error) => error };
981
+ // The phase withNodeAssertionPhase runs its callback in, opened before a
982
+ // TypeScript assertion's operands and closed after its call. The rewrite calls
983
+ // the assertion in place because TypeScript narrows nothing into a callback:
984
+ // `prior < id` under `if (prior !== undefined)`, an evolving `const ids = []`
985
+ // and an `asserts` signature all failed to typecheck once wrapped in one.
986
+ function openNodeAssertionPhase(operation, source) {
987
+ var _a8;
988
+ const context = currentRequestContext();
989
+ const scope = context.scope;
990
+ if (!scope)
991
+ return inertAssertionPhase;
992
+ const nested = context.phaseId && assertionPhaseState(scope).phaseIds.has(context.phaseId);
993
+ if (nested && typeof source !== "string")
994
+ return inertAssertionPhase;
995
+ if (typeof source === "function")
996
+ source = source();
997
+ let carrier;
998
+ let finish;
999
+ let release;
1000
+ const bridged = (_a8 = runtimeGlobal.__SUPERCOV_ASSERTION_PHASE_OPENER__) == null ? void 0 : _a8.call(runtimeGlobal, operation, source);
1001
+ if (bridged) {
1002
+ ({ carrier, finish, release } = bridged);
1003
+ } else {
1004
+ const attempt = assertionPhaseState(scope);
1005
+ const phase = __spreadProps(__spreadValues({
1006
+ id: `${scope.attemptId}:assertion:${++attempt.counter}`,
1007
+ kind: "assertion",
1008
+ operation
1009
+ }, source ? { source } : {}), {
1010
+ startedAtMs: Date.now()
1011
+ });
1012
+ attempt.phases.push(phase);
1013
+ attempt.phaseIds.add(phase.id);
1014
+ carrier = { version: 1, scope, phaseId: phase.id };
1015
+ finish = (error) => finishAssertionPhase(phase, error);
1016
+ }
1017
+ const restore = enterCoverageCarrier(carrier);
1018
+ let open = true;
1019
+ const settle = () => {
1020
+ if (!open)
1021
+ return false;
1022
+ open = false;
1023
+ restore();
1024
+ release == null ? void 0 : release();
1025
+ return true;
1026
+ };
1027
+ return {
1028
+ close(value) {
1029
+ if (!settle())
1030
+ return value;
1031
+ if (value && typeof value.then === "function")
1032
+ return Promise.resolve(value).then((resolved) => {
1033
+ finish();
1034
+ return resolved;
1035
+ }, (error) => {
1036
+ finish(error);
1037
+ throw cleanInstrumentationStack(error);
1038
+ });
1039
+ finish();
1040
+ return value;
1041
+ },
1042
+ fail(error) {
1043
+ if (settle())
1044
+ finish(error);
1045
+ return cleanInstrumentationStack(error);
1046
+ }
1047
+ };
1048
+ }
809
1049
  function takeNodeAssertionPhases(scope) {
810
1050
  var _a8, _b;
811
1051
  const key = attemptKey(scope);
@@ -846,6 +1086,35 @@ function installServerFetchPropagation() {
846
1086
  runtimeGlobal.__SUPERCOV_FETCH_PATCHED__ = true;
847
1087
  }
848
1088
  installServerFetchPropagation();
1089
+ // util.promisify(exec) and util.promisify(execFile) resolve { stdout, stderr }
1090
+ // through a function Node keeps on the original, and that function calls the
1091
+ // original. A wrapper carries its own, which calls the wrapper, or a promisified
1092
+ // call resolves the bare stdout string and skips the wrapper.
1093
+ const promisifyCustom = Symbol.for("nodejs.util.promisify.custom");
1094
+ function keepPromisifiedShape(original, wrapper) {
1095
+ if (typeof original[promisifyCustom] !== "function")
1096
+ return wrapper;
1097
+ Object.defineProperty(wrapper, promisifyCustom, {
1098
+ configurable: true,
1099
+ value: (...args) => {
1100
+ let settle, reject;
1101
+ const promise = new Promise((ok, fail) => {
1102
+ settle = ok;
1103
+ reject = fail;
1104
+ });
1105
+ promise.child = wrapper(...args, (error, stdout, stderr) => {
1106
+ if (error !== null) {
1107
+ error.stdout = stdout;
1108
+ error.stderr = stderr;
1109
+ reject(error);
1110
+ } else
1111
+ settle({ stdout, stderr });
1112
+ });
1113
+ return promise;
1114
+ }
1115
+ });
1116
+ return wrapper;
1117
+ }
849
1118
  function installServerChildPropagation() {
850
1119
  var _a8;
851
1120
  if (isBrowser || runtimeGlobal.__SUPERCOV_CHILD_PATCHED__ || typeof process === "undefined")
@@ -855,9 +1124,12 @@ function installServerChildPropagation() {
855
1124
  if (!child)
856
1125
  return;
857
1126
  const mutableChild = child;
1127
+ // (file, args?, options?, callback?): options follow an argument list, or an
1128
+ // explicit null or undefined in its place. exec itself calls execFile as
1129
+ // (file, options, callback), and that object is the options, not a list.
858
1130
  const optionIndex = (method, args) => {
859
1131
  if (method === "spawn" || method === "spawnSync" || method === "fork" || method === "execFile" || method === "execFileSync")
860
- return Array.isArray(args[1]) || args.length > 2 && args[2] !== void 0 ? 2 : 1;
1132
+ return Array.isArray(args[1]) || args[1] == null && args.length > 2 ? 2 : 1;
861
1133
  return 1;
862
1134
  };
863
1135
  for (const method of [
@@ -872,12 +1144,15 @@ function installServerChildPropagation() {
872
1144
  const original = mutableChild[method];
873
1145
  if (typeof original !== "function")
874
1146
  continue;
875
- mutableChild[method] = function(...args) {
1147
+ mutableChild[method] = keepPromisifiedShape(original, function(...args) {
876
1148
  var _a9;
877
1149
  const index = optionIndex(method, args);
878
1150
  const existing = args[index] && typeof args[index] === "object" ? args[index] : {};
1151
+ // An env the caller passed is the child's whole environment -- execa's
1152
+ // extendEnv: false keeps the parent's CI out of chalk's fixtures -- so
1153
+ // only the carrier joins it. Without one, the child inherits ours.
879
1154
  const options = __spreadProps(__spreadValues({}, existing), {
880
- env: __spreadValues(__spreadValues(__spreadValues({}, process.env), (_a9 = existing.env) != null ? _a9 : {}), coverageContextEnvironment())
1155
+ env: __spreadValues(__spreadValues({}, (_a9 = existing.env) != null ? _a9 : process.env), coverageContextEnvironment())
881
1156
  });
882
1157
  const scoped = [...args];
883
1158
  if (typeof scoped[index] === "function")
@@ -885,7 +1160,7 @@ function installServerChildPropagation() {
885
1160
  else
886
1161
  scoped[index] = options;
887
1162
  return Reflect.apply(original, child, scoped);
888
- };
1163
+ });
889
1164
  }
890
1165
  const moduleBuiltin = getBuiltinModule == null ? void 0 : getBuiltinModule("node:module");
891
1166
  (_a8 = moduleBuiltin == null ? void 0 : moduleBuiltin.syncBuiltinESMExports) == null ? void 0 : _a8.call(moduleBuiltin);
@@ -897,13 +1172,26 @@ installServerChildPropagation();
897
1172
  * against the attempt it claims to belong to without a lookup.
898
1173
  */
899
1174
  function phaseBelongsToAttempt(phaseId, attemptId) {
900
- return typeof phaseId === "string" && typeof attemptId === "string" && attemptId.length > 0 && phaseId.startsWith(`${attemptId}:phase:`);
1175
+ return typeof phaseId === "string" && typeof attemptId === "string" && attemptId.length > 0 && phaseId.startsWith(`${attemptId}:`);
901
1176
  }
902
1177
  function currentPhaseId() {
903
1178
  if (runtimeGlobal.__SUPERCOV_PHASE_ID__)
904
1179
  return runtimeGlobal.__SUPERCOV_PHASE_ID__;
905
- if (!isBrowser)
906
- return currentRequestContext().phaseId;
1180
+ if (!isBrowser) {
1181
+ // Async work an earlier test started -- a stream, a socket, a timer --
1182
+ // keeps that test's context and can run after the next test has begun.
1183
+ // Its phase belongs to the earlier attempt, and tagging this test's
1184
+ // evidence with it made the whole run unreadable ("unknown frontend phase
1185
+ // reference"): axios's HTTP/2 upload tests did it three times in 2,201.
1186
+ // Where the process knows which test is running, only that test's phases
1187
+ // are honoured; a server process, which learns its test from the request,
1188
+ // keeps the carried phase.
1189
+ const context = currentRequestContext();
1190
+ const active = runtimeGlobal.__SUPERCOV_ACTIVE_SCOPE__;
1191
+ if (context.phaseId && active && !phaseBelongsToAttempt(context.phaseId, active.attemptId))
1192
+ return void 0;
1193
+ return context.phaseId;
1194
+ }
907
1195
  try {
908
1196
  // The stored phase is per origin, so in a browser context that outlives
909
1197
  // its test (a persistent profile shared by a whole worker) it still holds
@@ -976,15 +1264,23 @@ function requestCoverageContext(value) {
976
1264
  }
977
1265
  // Keep connection ownership on the emitter, without changing listener
978
1266
  // identity (removeListener/off and once still see the original callbacks).
979
- const emitterContextMaps = runtimeGlobal.__SUPERCOV_EMITTER_CONTEXT_MAPS__ ??= new Map();
980
- const emitterCoverageContexts = emitterContextMaps.get(runtimeInstance) ?? new WeakMap();
1267
+ if (runtimeGlobal.__SUPERCOV_EMITTER_CONTEXT_MAPS__ == null)
1268
+ runtimeGlobal.__SUPERCOV_EMITTER_CONTEXT_MAPS__ = new Map();
1269
+ const emitterContextMaps = runtimeGlobal.__SUPERCOV_EMITTER_CONTEXT_MAPS__;
1270
+ const emitterCoverageContexts = emitterContextMaps.get(runtimeInstance) || new WeakMap();
981
1271
  emitterContextMaps.set(runtimeInstance, emitterCoverageContexts);
982
- const patchedEmitterInstances = runtimeGlobal.__SUPERCOV_EMITTER_PATCHED_INSTANCES__ ??= new Set();
1272
+ if (runtimeGlobal.__SUPERCOV_EMITTER_PATCHED_INSTANCES__ == null)
1273
+ runtimeGlobal.__SUPERCOV_EMITTER_PATCHED_INSTANCES__ = new Set();
1274
+ const patchedEmitterInstances = runtimeGlobal.__SUPERCOV_EMITTER_PATCHED_INSTANCES__;
983
1275
  function installNodeRequestPropagation() {
984
1276
  if (isBrowser || patchedEmitterInstances.has(runtimeInstance) || typeof process === "undefined") return;
985
- const EventEmitter = process.getBuiltinModule?.("node:events")?.EventEmitter;
986
- const Server = process.getBuiltinModule?.("node:http")?.Server;
987
- const SecureServer = process.getBuiltinModule?.("node:https")?.Server;
1277
+ const builtin = (name) => typeof process.getBuiltinModule === "function" ? process.getBuiltinModule(name) : void 0;
1278
+ const events = builtin("node:events");
1279
+ const http = builtin("node:http");
1280
+ const https = builtin("node:https");
1281
+ const EventEmitter = events && events.EventEmitter;
1282
+ const Server = http && http.Server;
1283
+ const SecureServer = https && https.Server;
988
1284
  if (!EventEmitter) return;
989
1285
  const original = EventEmitter.prototype.emit;
990
1286
  EventEmitter.prototype.emit = function(event, ...args) {
@@ -994,7 +1290,7 @@ function installNodeRequestPropagation() {
994
1290
  // HTTP headers establish ownership even when Express/SDK listeners and
995
1291
  // the server process were created by a shared before hook.
996
1292
  const incoming = requestCoverageContext(args[0]);
997
- if (incoming) context = incoming.scope ? incoming : context ?? currentRequestContext();
1293
+ if (incoming) context = incoming.scope ? incoming : context != null ? context : currentRequestContext();
998
1294
  }
999
1295
  const invoke = () => Reflect.apply(original, this, [event, ...args]);
1000
1296
  try {
@@ -1016,7 +1312,7 @@ function withRequestPhase(handler, event) {
1016
1312
  const requestContext = args.map((argument) => requestCoverageContext(argument)).find((context2) => context2 !== void 0);
1017
1313
  // An untagged request to a test-owned server must not erase that server's
1018
1314
  // owner. Shared servers have no captured test scope and stay unattributed.
1019
- const inheritedContext = requestContext?.scope ? {} : registeredContext.scope ? registeredContext : requestContext === void 0 ? currentRequestContext() : {};
1315
+ const inheritedContext = requestContext && requestContext.scope ? {} : registeredContext.scope ? registeredContext : requestContext === void 0 ? currentRequestContext() : {};
1020
1316
  const context = __spreadValues(__spreadValues({}, ((_a8 = requestContext == null ? void 0 : requestContext.scope) != null ? _a8 : inheritedContext.scope) ? { scope: (_b = requestContext == null ? void 0 : requestContext.scope) != null ? _b : inheritedContext.scope } : {}), ((_c = requestContext == null ? void 0 : requestContext.phaseId) != null ? _c : inheritedContext.phaseId) ? { phaseId: (_d = requestContext == null ? void 0 : requestContext.phaseId) != null ? _d : inheritedContext.phaseId } : {});
1021
1317
  const invoke = () => {
1022
1318
  if (event === "connection" && context.scope && args[0] &&
@@ -1038,10 +1334,36 @@ function recordBrowserEvent(event) {
1038
1334
  return false;
1039
1335
  state.eventKeys.add(key);
1040
1336
  state.events.push(event);
1337
+ workerEvidenceChanged();
1041
1338
  return true;
1042
1339
  }
1340
+ // A hit is recorded once per context, as a statement probe's is: selections,
1341
+ // optional chains, defaults and loops reach here on every evaluation, and
1342
+ // each built and serialized its record before the transport dropped it as a
1343
+ // repeat.
1043
1344
  function coverageHit(id) {
1345
+ const clock = state.probeV2Clock;
1346
+ if (clock.fast && state.hitEpochs !== void 0 && state.hitEpochs.get(id) === clock.epoch)
1347
+ return;
1348
+ recordCoverageHit(id);
1349
+ }
1350
+ // resetCoverage forces a fresh epoch, so a hit skipped above was recorded in
1351
+ // this epoch after the last reset and is in state.hits already.
1352
+ function recordCoverageHit(id) {
1044
1353
  state.hits.add(id);
1354
+ const clock = state.probeV2Clock;
1355
+ let epoch = clock.epoch;
1356
+ if (!clock.fast) {
1357
+ const previousEpoch = clock.epoch;
1358
+ activateProbeV2Context(currentRequestContext());
1359
+ epoch = clock.epoch;
1360
+ clock.epoch = previousEpoch;
1361
+ }
1362
+ if (!state.hitEpochs)
1363
+ state.hitEpochs = /* @__PURE__ */ new Map();
1364
+ if (state.hitEpochs.get(id) === epoch)
1365
+ return;
1366
+ state.hitEpochs.set(id, epoch);
1045
1367
  const timestampMs = Date.now();
1046
1368
  const phaseId = currentPhaseId();
1047
1369
  if (isBrowser) {
@@ -1075,7 +1397,12 @@ function registerProbeV2(definition) {
1075
1397
  }),
1076
1398
  decisionObservationEpochs: new Uint32Array(definition.decisions.length),
1077
1399
  decisionObservationCounts: new Uint16Array(definition.decisions.length),
1078
- decisionCompleteEpochs: new Uint32Array(definition.decisions.length)
1400
+ decisionCompleteEpochs: new Uint32Array(definition.decisions.length),
1401
+ pendingDefaults: new Uint32Array(definition.defaultCount || 0),
1402
+ // A selection's outcomes -- short falsy, short truthy, right falsy, right
1403
+ // truthy -- are four consecutive points per site from the first index.
1404
+ selectionPoints: definition.selectionPoints,
1405
+ none: optionalCallEmptySpread
1079
1406
  };
1080
1407
  state.probeV2Files.add(file);
1081
1408
  if (isBrowser) {
@@ -1083,10 +1410,27 @@ function registerProbeV2(definition) {
1083
1410
  activateProbeV2Key(`browser\0${(_a8 = runtimeGlobal.__SUPERCOV_MCDC_TEST_ID__) != null ? _a8 : testId}\0${(_b = runtimeGlobal.__SUPERCOV_PHASE_ID__) != null ? _b : "unscoped"}`);
1084
1411
  } else {
1085
1412
  installProbeV2AsyncHook();
1413
+ // The hook sets the epoch when an async callback begins. Code that runs
1414
+ // before any did -- a script's own top level -- found it NaN, which no
1415
+ // epoch equals, so every probe there took the slow path every time: a
1416
+ // million-iteration loop ran 1,700 times slower than without Supercov.
1417
+ if (Number.isNaN(state.probeV2Clock.epoch))
1418
+ activateProbeV2Context(currentRequestContext());
1086
1419
  }
1087
1420
  return file;
1088
1421
  }
1422
+ // Every repeat of a probe in the same context ends at the first check, so it
1423
+ // stays small enough for V8 to inline into the instrumented function; the
1424
+ // rest runs once per context. minimatch's backtracking guard test needs a
1425
+ // pathological match inside a second, and the full body in every call put it
1426
+ // at ten times the uninstrumented time.
1089
1427
  function coverageHitV2(file, index) {
1428
+ const clock = file.clock;
1429
+ if (clock.fast && file.hitEpochs[index] === clock.epoch)
1430
+ return;
1431
+ recordCoverageHitV2(file, index);
1432
+ }
1433
+ function recordCoverageHitV2(file, index) {
1090
1434
  const id = file.pointIds[index];
1091
1435
  if (!id)
1092
1436
  return;
@@ -1100,6 +1444,9 @@ function coverageHitV2(file, index) {
1100
1444
  return;
1101
1445
  file.hitEpochs[index] = epoch;
1102
1446
  coverageHit(id);
1447
+ const selections = file.selectionPoints;
1448
+ if (selections !== void 0 && index >= selections[0] && index < selections[0] + 4 * selections[1])
1449
+ recordSelectionOutcome(id, index - selections[0] & 3);
1103
1450
  } finally {
1104
1451
  if (fallbackEpoch)
1105
1452
  file.clock.epoch = previousEpoch;
@@ -1118,6 +1465,15 @@ function decodeProbeV2Vector(conditionCount, encoded, outcome) {
1118
1465
  return remaining === 0 ? { values, outcome } : void 0;
1119
1466
  }
1120
1467
  function mcdcEndV2(file, decisionIndex, encoded, value) {
1468
+ const clock = file.clock;
1469
+ if (clock.fast) {
1470
+ const seen = file.decisionEpochs[decisionIndex];
1471
+ if (seen instanceof Uint32Array && seen[encoded * 2 + (value ? 1 : 0)] === clock.epoch)
1472
+ return value;
1473
+ }
1474
+ return recordMcdcEndV2(file, decisionIndex, encoded, value);
1475
+ }
1476
+ function recordMcdcEndV2(file, decisionIndex, encoded, value) {
1121
1477
  var _a8, _b;
1122
1478
  const meta = file.decisions[decisionIndex];
1123
1479
  if (!meta || !Number.isSafeInteger(encoded) || encoded < 0)
@@ -1170,6 +1526,7 @@ function selectionBegin(shortId, rightId) {
1170
1526
  function applyInferredName(value, inferredName) {
1171
1527
  if (inferredName && typeof value === "function" && value.name === "") {
1172
1528
  Object.defineProperty(value, "name", {
1529
+ __proto__: null,
1173
1530
  value: inferredName,
1174
1531
  configurable: true
1175
1532
  });
@@ -1189,24 +1546,38 @@ function selectionRight(frame, value, inferredName) {
1189
1546
  frame.rightEvaluated = true;
1190
1547
  return applyInferredName(value, inferredName);
1191
1548
  }
1549
+ var selectionOutcomeKeys = ["SF", "ST", "RF", "RT"];
1550
+ var selectionBranchIds = /* @__PURE__ */ new Map();
1192
1551
  function selectionEnd(frame, value) {
1193
- coverageHit(frame.rightEvaluated ? frame.rightId : frame.shortId);
1194
- // Per-operand outcomes for the verifier: which side was selected and whether the result is
1195
- // truthy. With the operator (known from the manifest) this gives each operand's outcome.
1196
- const separator = frame.shortId.lastIndexOf(":");
1197
- if (separator > 0) {
1198
- const branchId = frame.shortId.slice(0, separator);
1199
- const right = frame.rightEvaluated;
1200
- const truthy = Boolean(value);
1201
- let vectors = state.logicals.get(branchId);
1202
- if (!vectors) {
1203
- vectors = /* @__PURE__ */ new Map();
1204
- state.logicals.set(branchId, vectors);
1205
- }
1206
- vectors.set(`${right ? "R" : "S"}${truthy ? "T" : "F"}`, { right, truthy });
1207
- }
1552
+ const right = frame.rightEvaluated;
1553
+ coverageHit(right ? frame.rightId : frame.shortId);
1554
+ recordSelectionOutcome(frame.shortId, (right ? 2 : 0) + (value ? 1 : 0));
1208
1555
  return value;
1209
1556
  }
1557
+ // Per-operand outcomes for the verifier: which side was selected and whether
1558
+ // the result is truthy. With the operator (known from the manifest) this gives
1559
+ // each operand's outcome. The branch id is cut from the outcome's id -- its
1560
+ // short or right id, which share it -- once, not on every evaluation.
1561
+ function recordSelectionOutcome(id, outcome) {
1562
+ let branchId = selectionBranchIds.get(id);
1563
+ if (branchId === void 0) {
1564
+ const separator = id.lastIndexOf(":");
1565
+ branchId = separator > 0 ? id.slice(0, separator) : null;
1566
+ selectionBranchIds.set(id, branchId);
1567
+ }
1568
+ if (branchId === null)
1569
+ return;
1570
+ let vectors = state.logicals.get(branchId);
1571
+ if (!vectors) {
1572
+ vectors = /* @__PURE__ */ new Map();
1573
+ state.logicals.set(branchId, vectors);
1574
+ }
1575
+ const key = selectionOutcomeKeys[outcome];
1576
+ if (!vectors.has(key)) {
1577
+ vectors.set(key, { right: outcome >= 2, truthy: (outcome & 1) === 1 });
1578
+ workerEvidenceChanged();
1579
+ }
1580
+ }
1210
1581
  // A JSX expression container has nowhere to put a statement and cannot hold a
1211
1582
  // bare comma operator, so a rendered expression carries its probe as a call
1212
1583
  // that returns the value through. Like optionalSelect, it records after the
@@ -1220,6 +1591,75 @@ function optionalSelect(shortId, continuedId, value) {
1220
1591
  coverageHit(value === null || value === void 0 ? shortId : continuedId);
1221
1592
  return value;
1222
1593
  }
1594
+ // `a || b` (kind 0), `a && b` (1), `a ?? b` (2), with the program's own
1595
+ // operator between the two calls: the left operand records its short outcome
1596
+ // when it decides the result -- truthy, falsy, present -- and the right one
1597
+ // whether it came out truthy. The outcomes are the selection's four points.
1598
+ function selectShortV2(file, first, value, kind) {
1599
+ if (kind === 0 ? value : kind === 1 ? !value : value !== null && value !== void 0)
1600
+ coverageHitV2(file, value ? first + 1 : first);
1601
+ return value;
1602
+ }
1603
+ function selectRightV2(file, first, value) {
1604
+ coverageHitV2(file, value ? first + 3 : first + 2);
1605
+ return value;
1606
+ }
1607
+ // A leaf of nested selections, `(a && b) || c`: the program's operators stay
1608
+ // between the leaves, so a coverage tool the tests run flattens them into the
1609
+ // one branch it reads without Supercov. Each step after the value names a
1610
+ // selection above the leaf, nearest first, as `first * 4 + code`: code 3 when
1611
+ // the leaf is on its right side, which records that side's outcome, and the
1612
+ // operator's kind (0 `||`, 1 `&&`, 2 `??`) when on its left, which records the
1613
+ // short outcome when the value decides it; otherwise the selection goes on to
1614
+ // its right side, and the leaf decides nothing further up.
1615
+ function selectPathV2(file, value) {
1616
+ for (let index = 2; index < arguments.length; index += 1) {
1617
+ const step = arguments[index];
1618
+ const code = step & 3;
1619
+ const first = (step - code) / 4;
1620
+ if (code === 3)
1621
+ coverageHitV2(file, value ? first + 3 : first + 2);
1622
+ else if (code === 0 ? value : code === 1 ? !value : value !== null && value !== void 0)
1623
+ coverageHitV2(file, value ? first + 1 : first);
1624
+ else
1625
+ break;
1626
+ }
1627
+ return value;
1628
+ }
1629
+ // `x ||= y`, `x &&= y`, `x ??= y` keep their operator and their single
1630
+ // evaluation of the target: the right side goes through selectRightV2 (or the
1631
+ // named form, for an anonymous function the assignment would have named), and
1632
+ // a site temporary set to 1 after it tells the end whether the assignment was
1633
+ // skipped, which is then the short outcome for the value the target kept.
1634
+ function selectNamedRightV2(file, first, value, inferredName) {
1635
+ coverageHitV2(file, value ? first + 3 : first + 2);
1636
+ return applyInferredName(value, inferredName);
1637
+ }
1638
+ function selectAssignEndV2(file, first, value, right) {
1639
+ if (!right)
1640
+ coverageHitV2(file, value ? first + 1 : first);
1641
+ return value;
1642
+ }
1643
+ // `object?.member`: the short and continued outcomes are two V2 points.
1644
+ // Whether the previous optional link of the chain being evaluated cut it
1645
+ // short. In `a?.b?.c` the object of `?.c` is undefined when `a` is, though
1646
+ // `?.c` never ran: `?.b` says so here and `?.c` records nothing. `links` has
1647
+ // 1 when an earlier link of the chain runs first and 2 when a later one
1648
+ // follows. Every link with a later one writes this and that later one reads
1649
+ // and clears it, so code run in between -- a getter, a call -- that
1650
+ // evaluates chains of its own leaves it as it found it. 4 means the earlier
1651
+ // link is an optional call, whose frame `call` is 2 only if it went ahead.
1652
+ var optionalChainCut = false;
1653
+ function optionalSelectV2(file, first, value, links, call) {
1654
+ if (links & 1 && optionalChainCut || links & 4 && call !== 2) {
1655
+ optionalChainCut = (links & 2) !== 0;
1656
+ return value;
1657
+ }
1658
+ var nullish = value === null || value === void 0;
1659
+ coverageHitV2(file, nullish ? first : first + 1);
1660
+ optionalChainCut = nullish && (links & 2) !== 0;
1661
+ return value;
1662
+ }
1223
1663
  function optionalCallBegin(shortId, continuedId) {
1224
1664
  return { shortId, continuedId, reached: false, continued: false };
1225
1665
  }
@@ -1227,13 +1667,17 @@ function optionalCallReached(frame, value) {
1227
1667
  frame.reached = true;
1228
1668
  return value;
1229
1669
  }
1670
+ // Spread into an optional call's arguments to mark that the call went ahead:
1671
+ // it yields nothing, and allocates nothing per call.
1672
+ var optionalCallDone = { done: true, value: void 0 };
1673
+ var optionalCallEmptyIterator = {
1674
+ next() {
1675
+ return optionalCallDone;
1676
+ }
1677
+ };
1230
1678
  var optionalCallEmptySpread = {
1231
1679
  [Symbol.iterator]() {
1232
- return {
1233
- next() {
1234
- return { done: true, value: void 0 };
1235
- }
1236
- };
1680
+ return optionalCallEmptyIterator;
1237
1681
  }
1238
1682
  };
1239
1683
  function optionalCallContinued(frame) {
@@ -1245,6 +1689,13 @@ function optionalCallEnd(frame, value) {
1245
1689
  coverageHit(frame.continued ? frame.continuedId : frame.shortId);
1246
1690
  return value;
1247
1691
  }
1692
+ // The site's state, read after the chain: 0 not reached, 1 reached and
1693
+ // short-circuited, 2 called. Short and continued are two V2 points.
1694
+ function optionalCallEndV2(file, first, value, state) {
1695
+ if (state)
1696
+ coverageHitV2(file, state === 2 ? first + 1 : first);
1697
+ return value;
1698
+ }
1248
1699
  function defaultSelected(defaultId, value, inferredName) {
1249
1700
  var _a8;
1250
1701
  pendingDefaults.set(defaultId, ((_a8 = pendingDefaults.get(defaultId)) != null ? _a8 : 0) + 1);
@@ -1260,6 +1711,24 @@ function defaultEntered(defaultId, providedId) {
1260
1711
  coverageHit(providedId);
1261
1712
  }
1262
1713
  }
1714
+ // The same count per default, in a slot of the file's typed array instead of
1715
+ // a Map keyed by the default's id, and the outcome recorded through the V2
1716
+ // point check, which ends at one comparison once it fired in this context.
1717
+ // lru-cache's set and get destructure options with defaults: the Map and the
1718
+ // two calls behind each were a third of a hot loop.
1719
+ function defaultSelectedV2(file, slot, value, inferredName) {
1720
+ file.pendingDefaults[slot] += 1;
1721
+ return inferredName ? applyInferredName(value, inferredName) : value;
1722
+ }
1723
+ function defaultEnteredV2(file, slot, defaultPoint, providedPoint) {
1724
+ const pending = file.pendingDefaults;
1725
+ if (pending[slot] > 0) {
1726
+ pending[slot] -= 1;
1727
+ coverageHitV2(file, defaultPoint);
1728
+ } else {
1729
+ coverageHitV2(file, providedPoint);
1730
+ }
1731
+ }
1263
1732
  function tryBegin(successId, catchId) {
1264
1733
  return { successId, catchId, caught: false };
1265
1734
  }
@@ -1349,7 +1818,9 @@ const directRuntimeApi = {
1349
1818
  coverageSnapshot,
1350
1819
  decodeProbeV2Vector,
1351
1820
  defaultEntered,
1821
+ defaultEnteredV2,
1352
1822
  defaultSelected,
1823
+ defaultSelectedV2,
1353
1824
  enableRuntimeSnapshotEvidence,
1354
1825
  flushBufferedBackgroundEvidence,
1355
1826
  flushBufferedServerEvidence,
@@ -1364,7 +1835,9 @@ const directRuntimeApi = {
1364
1835
  optionalCallContinued,
1365
1836
  optionalCallEnd,
1366
1837
  optionalCallReached,
1838
+ optionalCallEndV2,
1367
1839
  optionalSelect,
1840
+ optionalSelectV2,
1368
1841
  renderedValueV2,
1369
1842
  parenthesizedAssignmentValue,
1370
1843
  phaseBelongsToAttempt,
@@ -1373,6 +1846,11 @@ const directRuntimeApi = {
1373
1846
  selectionBegin,
1374
1847
  selectionEnd,
1375
1848
  selectionRight,
1849
+ selectShortV2,
1850
+ selectRightV2,
1851
+ selectNamedRightV2,
1852
+ selectAssignEndV2,
1853
+ selectPathV2,
1376
1854
  takeNodeAssertionPhases,
1377
1855
  tryBegin,
1378
1856
  tryCatch,
@@ -1380,12 +1858,14 @@ const directRuntimeApi = {
1380
1858
  withCoverageCarrier,
1381
1859
  withNodeAssertionPhase,
1382
1860
  bindNodeAssertionPhase,
1861
+ openNodeAssertionPhase,
1383
1862
  withRequestPhase,
1384
1863
  writeExclusiveBackgroundRecord
1385
1864
  };
1386
- globalThis.__SUPERCOV_DIRECT_RUNTIME__ ??= directRuntimeApi;
1387
- if (typeof process !== "undefined")
1388
- process.__SUPERCOV_DIRECT_RUNTIME__ ??= directRuntimeApi;
1865
+ if (globalThis.__SUPERCOV_DIRECT_RUNTIME__ == null)
1866
+ globalThis.__SUPERCOV_DIRECT_RUNTIME__ = directRuntimeApi;
1867
+ if (typeof process !== "undefined" && process.__SUPERCOV_DIRECT_RUNTIME__ == null)
1868
+ process.__SUPERCOV_DIRECT_RUNTIME__ = directRuntimeApi;
1389
1869
  export {
1390
1870
  activateCoverageScope,
1391
1871
  beginBufferedServerEvidence,
@@ -1399,7 +1879,9 @@ export {
1399
1879
  coverageSnapshot,
1400
1880
  decodeProbeV2Vector,
1401
1881
  defaultEntered,
1882
+ defaultEnteredV2,
1402
1883
  defaultSelected,
1884
+ defaultSelectedV2,
1403
1885
  enableRuntimeSnapshotEvidence,
1404
1886
  flushBufferedBackgroundEvidence,
1405
1887
  flushBufferedServerEvidence,
@@ -1415,7 +1897,9 @@ export {
1415
1897
  optionalCallContinued,
1416
1898
  optionalCallEnd,
1417
1899
  optionalCallReached,
1900
+ optionalCallEndV2,
1418
1901
  optionalSelect,
1902
+ optionalSelectV2,
1419
1903
  renderedValueV2,
1420
1904
  parenthesizedAssignmentValue,
1421
1905
  phaseBelongsToAttempt,
@@ -1424,6 +1908,11 @@ export {
1424
1908
  selectionBegin,
1425
1909
  selectionEnd,
1426
1910
  selectionRight,
1911
+ selectShortV2,
1912
+ selectRightV2,
1913
+ selectNamedRightV2,
1914
+ selectAssignEndV2,
1915
+ selectPathV2,
1427
1916
  takeNodeAssertionPhases,
1428
1917
  tryBegin,
1429
1918
  tryCatch,
@@ -1431,6 +1920,7 @@ export {
1431
1920
  withCoverageCarrier,
1432
1921
  withNodeAssertionPhase,
1433
1922
  bindNodeAssertionPhase,
1923
+ openNodeAssertionPhase,
1434
1924
  withRequestPhase,
1435
1925
  writeExclusiveBackgroundRecord
1436
1926
  };