@antdv-next/x-sdk 0.0.2 → 0.0.4

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/LICENSE +21 -0
  2. package/dist/chat-providers/types/model.d.ts +1 -1
  3. package/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +76 -0
  4. package/dist/node_modules/{vitest/dist/@vitest/expect → .pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist}/index.js +76 -51
  5. package/dist/node_modules/{vitest/dist/@vitest/pretty-format → .pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist}/index.js +11 -10
  6. package/dist/node_modules/{vitest/dist/@vitest/runner → .pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist}/chunk-artifact.js +18 -41
  7. package/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +2 -0
  8. package/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +2 -0
  9. package/dist/node_modules/{vitest/dist/@vitest/snapshot → .pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist}/index.js +455 -195
  10. package/dist/node_modules/{vitest/dist/@vitest/spy → .pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist}/index.js +3 -3
  11. package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/chunk-pathe.M-eThtNZ.js +2 -2
  12. package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/diff.js +40 -30
  13. package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/display.js +3 -3
  14. package/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +34 -0
  15. package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/helpers.js +3 -3
  16. package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/offset.js +1 -1
  17. package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/serialize.js +1 -1
  18. package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/source-map.js +6 -6
  19. package/dist/node_modules/{vitest/dist/@vitest/utils → .pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist}/timers.js +1 -1
  20. package/dist/node_modules/{vitest/dist/vendor/chai.js → .pnpm/chai@6.2.2/node_modules/chai/index.js} +103 -3
  21. package/dist/node_modules/{vitest/dist/vendor/magic-string.js → .pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js} +4 -76
  22. package/dist/node_modules/.pnpm/tinyrainbow@3.1.1/node_modules/tinyrainbow/dist/index.js +84 -0
  23. package/dist/node_modules/.pnpm/vitest@4.1.10_@types_node@24.12.0_@vitest_browser-preview@4.1.10_@vitest_coverage-v8@4._55bf307888d746e7433721e12ae091d9/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +4 -0
  24. package/dist/node_modules/{vitest → .pnpm/vitest@4.1.10_@types_node@24.12.0_@vitest_browser-preview@4.1.10_@vitest_coverage-v8@4._55bf307888d746e7433721e12ae091d9/node_modules/vitest}/dist/chunks/rpc.MzXet3jl.js +2 -2
  25. package/dist/node_modules/{vitest/dist/chunks/test.CBQUpOM3.js → .pnpm/vitest@4.1.10_@types_node@24.12.0_@vitest_browser-preview@4.1.10_@vitest_coverage-v8@4._55bf307888d746e7433721e12ae091d9/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js} +383 -327
  26. package/dist/node_modules/{vitest → .pnpm/vitest@4.1.10_@types_node@24.12.0_@vitest_browser-preview@4.1.10_@vitest_coverage-v8@4._55bf307888d746e7433721e12ae091d9/node_modules/vitest}/dist/chunks/utils.BX5Fg8C4.js +3 -3
  27. package/dist/x-chat/__tests__/index.test.js +3 -2
  28. package/dist/x-chat/index.js +3 -2
  29. package/dist/x-conversations/__tests__/index.test.js +2 -2
  30. package/dist/x-request/__tests__/index.test.js +2 -2
  31. package/dist/x-stream/__tests__/index.test.d.ts +1 -0
  32. package/dist/x-stream/__tests__/index.test.js +62 -0
  33. package/dist/x-stream/index.js +16 -5
  34. package/package.json +2 -1
  35. package/dist/node_modules/vitest/dist/@vitest/utils/error.js +0 -27
  36. package/dist/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -4
  37. package/dist/node_modules/vitest/dist/vendor/tinyrainbow.js +0 -84
@@ -1,114 +1,8 @@
1
- import { format, plugins } from "../pretty-format/index.js";
2
- import { getCallLastIndex, isObject } from "../utils/helpers.js";
3
- import { parseErrorStacktrace } from "../utils/source-map.js";
4
- import { lineSplitRE, offsetToLineNumber, positionToOffset } from "../utils/offset.js";
5
- //#region ../../node_modules/vitest/dist/@vitest/snapshot/index.js
6
- async function saveInlineSnapshots(environment, snapshots) {
7
- const MagicString = (await import("../../vendor/magic-string.js")).default;
8
- const files = new Set(snapshots.map((i) => i.file));
9
- await Promise.all(Array.from(files).map(async (file) => {
10
- const snaps = snapshots.filter((i) => i.file === file);
11
- const code = await environment.readSnapshotFile(file);
12
- if (code == null) throw new Error(`cannot read ${file} when saving inline snapshot`);
13
- const s = new MagicString(code);
14
- for (const snap of snaps) replaceInlineSnap(code, s, positionToOffset(code, snap.line, snap.column), snap.snapshot);
15
- const transformed = s.toString();
16
- if (transformed !== code) await environment.saveSnapshotFile(file, transformed);
17
- }));
18
- }
19
- var startObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*\{/;
20
- function replaceObjectSnap(code, s, index, newSnap) {
21
- let _code = code.slice(index);
22
- const startMatch = startObjectRegex.exec(_code);
23
- if (!startMatch) return false;
24
- _code = _code.slice(startMatch.index);
25
- let callEnd = getCallLastIndex(_code);
26
- if (callEnd === null) return false;
27
- callEnd += index + startMatch.index;
28
- const shapeEnd = getObjectShapeEndIndex(code, index + startMatch.index + startMatch[0].length);
29
- const snap = `, ${prepareSnapString(newSnap, code, index)}`;
30
- if (shapeEnd === callEnd) s.appendLeft(callEnd, snap);
31
- else s.overwrite(shapeEnd, callEnd, snap);
32
- return true;
33
- }
34
- function getObjectShapeEndIndex(code, index) {
35
- let startBraces = 1;
36
- let endBraces = 0;
37
- while (startBraces !== endBraces && index < code.length) {
38
- const s = code[index++];
39
- if (s === "{") startBraces++;
40
- else if (s === "}") endBraces++;
41
- }
42
- return index;
43
- }
44
- function prepareSnapString(snap, source, index) {
45
- const lineNumber = offsetToLineNumber(source, index);
46
- const indent = source.split(lineSplitRE)[lineNumber - 1].match(/^\s*/)[0] || "";
47
- const indentNext = indent.includes(" ") ? `${indent}\t` : `${indent} `;
48
- const lines = snap.trim().replace(/\\/g, "\\\\").split(/\n/g);
49
- const isOneline = lines.length <= 1;
50
- const quote = "`";
51
- if (isOneline) return `${quote}${lines.join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}${quote}`;
52
- return `${quote}\n${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}\n${indent}${quote}`;
53
- }
54
- var toMatchInlineName = "toMatchInlineSnapshot";
55
- var toThrowErrorMatchingInlineName = "toThrowErrorMatchingInlineSnapshot";
56
- function getCodeStartingAtIndex(code, index) {
57
- const indexInline = index - 21;
58
- if (code.slice(indexInline, index) === toMatchInlineName) return {
59
- code: code.slice(indexInline),
60
- index: indexInline
61
- };
62
- const indexThrowInline = index - 34;
63
- if (code.slice(index - indexThrowInline, index) === toThrowErrorMatchingInlineName) return {
64
- code: code.slice(index - indexThrowInline),
65
- index: index - indexThrowInline
66
- };
67
- return {
68
- code: code.slice(index),
69
- index
70
- };
71
- }
72
- var startRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*[\w$]*(['"`)])/;
73
- function replaceInlineSnap(code, s, currentIndex, newSnap) {
74
- const { code: codeStartingAtIndex, index } = getCodeStartingAtIndex(code, currentIndex);
75
- const startMatch = startRegex.exec(codeStartingAtIndex);
76
- const firstKeywordMatch = /toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot/.exec(codeStartingAtIndex);
77
- if (!startMatch || startMatch.index !== firstKeywordMatch?.index) return replaceObjectSnap(code, s, index, newSnap);
78
- const quote = startMatch[1];
79
- const startIndex = index + startMatch.index + startMatch[0].length;
80
- const snapString = prepareSnapString(newSnap, code, index);
81
- if (quote === ")") {
82
- s.appendRight(startIndex - 1, snapString);
83
- return true;
84
- }
85
- const endMatch = new RegExp(`(?:^|[^\\\\])${quote}`).exec(code.slice(startIndex));
86
- if (!endMatch) return false;
87
- const endIndex = startIndex + endMatch.index + endMatch[0].length;
88
- s.overwrite(startIndex - 1, endIndex, snapString);
89
- return true;
90
- }
91
- var INDENTATION_REGEX = /^([^\S\n]*)\S/m;
92
- function stripSnapshotIndentation(inlineSnapshot) {
93
- const match = inlineSnapshot.match(INDENTATION_REGEX);
94
- if (!match || !match[1]) return inlineSnapshot;
95
- const indentation = match[1];
96
- const lines = inlineSnapshot.split(/\n/g);
97
- if (lines.length <= 2) return inlineSnapshot;
98
- if (lines[0].trim() !== "" || lines.at(-1)?.trim() !== "") return inlineSnapshot;
99
- for (let i = 1; i < lines.length - 1; i++) if (lines[i] !== "") {
100
- if (lines[i].indexOf(indentation) !== 0) return inlineSnapshot;
101
- lines[i] = lines[i].substring(indentation.length);
102
- }
103
- lines[lines.length - 1] = "";
104
- inlineSnapshot = lines.join("\n");
105
- return inlineSnapshot;
106
- }
107
- async function saveRawSnapshots(environment, snapshots) {
108
- await Promise.all(snapshots.map(async (snap) => {
109
- if (!snap.readonly) await environment.saveSnapshotFile(snap.file, snap.snapshot);
110
- }));
111
- }
1
+ import { format, plugins } from "../../../../../@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js";
2
+ import { getCallLastIndex, isObject } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js";
3
+ import { parseErrorStacktrace } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js";
4
+ import { lineSplitRE, offsetToLineNumber, positionToOffset } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js";
5
+ //#region ../../node_modules/.pnpm/@vitest+snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js
112
6
  function getDefaultExportFromCjs(x) {
113
7
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
114
8
  }
@@ -153,7 +47,7 @@ function requireNaturalCompare() {
153
47
  }
154
48
  return naturalCompare$1.exports;
155
49
  }
156
- var naturalCompare = /* @__PURE__ */ getDefaultExportFromCjs(requireNaturalCompare());
50
+ var naturalCompare = /*@__PURE__*/ getDefaultExportFromCjs(requireNaturalCompare());
157
51
  var serialize$1 = (val, config, indentation, depth, refs, printer) => {
158
52
  const name = val.getMockName();
159
53
  const nameString = name === "vi.fn()" ? "" : ` ${name}`;
@@ -304,6 +198,127 @@ var CounterMap = class extends DefaultMap {
304
198
  return total;
305
199
  }
306
200
  };
201
+ /* @__NO_SIDE_EFFECTS__ */
202
+ function memo(fn) {
203
+ const cache = /* @__PURE__ */ new Map();
204
+ return (arg) => {
205
+ if (!cache.has(arg)) cache.set(arg, fn(arg));
206
+ return cache.get(arg);
207
+ };
208
+ }
209
+ async function saveInlineSnapshots(environment, snapshots) {
210
+ const MagicString = (await import("../../../../../magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js")).default;
211
+ const files = new Set(snapshots.map((i) => i.file));
212
+ await Promise.all(Array.from(files).map(async (file) => {
213
+ const snaps = snapshots.filter((i) => i.file === file);
214
+ const code = await environment.readSnapshotFile(file);
215
+ if (code == null) throw new Error(`cannot read ${file} when saving inline snapshot`);
216
+ const s = new MagicString(code);
217
+ for (const snap of snaps) replaceInlineSnap(code, s, positionToOffset(code, snap.line, snap.column), snap.snapshot, snap.assertionName);
218
+ const transformed = s.toString();
219
+ if (transformed !== code) await environment.saveSnapshotFile(file, transformed);
220
+ }));
221
+ }
222
+ var defaultStartObjectRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*\{/;
223
+ function escapeRegExp(s) {
224
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
225
+ }
226
+ var buildStartObjectRegex = /* @__PURE__ */ memo((assertionName) => {
227
+ const replaced = defaultStartObjectRegex.source.replace("toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot", escapeRegExp(assertionName));
228
+ return new RegExp(replaced);
229
+ });
230
+ function replaceObjectSnap(code, s, index, newSnap, assertionName) {
231
+ let _code = code.slice(index);
232
+ const startMatch = (assertionName ? buildStartObjectRegex(assertionName) : defaultStartObjectRegex).exec(_code);
233
+ if (!startMatch) return false;
234
+ _code = _code.slice(startMatch.index);
235
+ let callEnd = getCallLastIndex(_code);
236
+ if (callEnd === null) return false;
237
+ callEnd += index + startMatch.index;
238
+ const shapeEnd = getObjectShapeEndIndex(code, index + startMatch.index + startMatch[0].length);
239
+ const snap = `, ${prepareSnapString(newSnap, code, index)}`;
240
+ if (shapeEnd === callEnd) s.appendLeft(callEnd, snap);
241
+ else s.overwrite(shapeEnd, callEnd, snap);
242
+ return true;
243
+ }
244
+ function getObjectShapeEndIndex(code, index) {
245
+ let startBraces = 1;
246
+ let endBraces = 0;
247
+ while (startBraces !== endBraces && index < code.length) {
248
+ const s = code[index++];
249
+ if (s === "{") startBraces++;
250
+ else if (s === "}") endBraces++;
251
+ }
252
+ return index;
253
+ }
254
+ function prepareSnapString(snap, source, index) {
255
+ const lineNumber = offsetToLineNumber(source, index);
256
+ const indent = source.split(lineSplitRE)[lineNumber - 1].match(/^\s*/)[0] || "";
257
+ const indentNext = indent.includes(" ") ? `${indent}\t` : `${indent} `;
258
+ const lines = snap.trim().replace(/\\/g, "\\\\").split(/\n/g);
259
+ const isOneline = lines.length <= 1;
260
+ const quote = "`";
261
+ if (isOneline) return `${quote}${lines.join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}${quote}`;
262
+ return `${quote}\n${lines.map((i) => i ? indentNext + i : "").join("\n").replace(/`/g, "\\`").replace(/\$\{/g, "\\${")}\n${indent}${quote}`;
263
+ }
264
+ var defaultMethodNames = ["toMatchInlineSnapshot", "toThrowErrorMatchingInlineSnapshot"];
265
+ function getCodeStartingAtIndex(code, index, methodNames) {
266
+ for (const name of methodNames) {
267
+ const adjusted = index - name.length;
268
+ if (adjusted >= 0 && code.slice(adjusted, index) === name) return {
269
+ code: code.slice(adjusted),
270
+ index: adjusted
271
+ };
272
+ }
273
+ return {
274
+ code: code.slice(index),
275
+ index
276
+ };
277
+ }
278
+ var defaultStartRegex = /(?:toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot)\s*\(\s*(?:\/\*[\s\S]*\*\/\s*|\/\/.*(?:[\n\r\u2028\u2029]\s*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF]))*[\w$]*(['"`)])/;
279
+ var buildStartRegex = /* @__PURE__ */ memo((assertionName) => {
280
+ const replaced = defaultStartRegex.source.replace("toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot", escapeRegExp(assertionName));
281
+ return new RegExp(replaced);
282
+ });
283
+ function replaceInlineSnap(code, s, currentIndex, newSnap, assertionName) {
284
+ const { code: codeStartingAtIndex, index } = getCodeStartingAtIndex(code, currentIndex, assertionName ? [assertionName] : defaultMethodNames);
285
+ const startMatch = (assertionName ? buildStartRegex(assertionName) : defaultStartRegex).exec(codeStartingAtIndex);
286
+ const firstKeywordMatch = (assertionName ? new RegExp(escapeRegExp(assertionName)) : /toMatchInlineSnapshot|toThrowErrorMatchingInlineSnapshot/).exec(codeStartingAtIndex);
287
+ if (!startMatch || startMatch.index !== firstKeywordMatch?.index) return replaceObjectSnap(code, s, index, newSnap, assertionName);
288
+ const quote = startMatch[1];
289
+ const startIndex = index + startMatch.index + startMatch[0].length;
290
+ const snapString = prepareSnapString(newSnap, code, index);
291
+ if (quote === ")") {
292
+ s.appendRight(startIndex - 1, snapString);
293
+ return true;
294
+ }
295
+ const endMatch = new RegExp(`(?:^|[^\\\\])${quote}`).exec(code.slice(startIndex));
296
+ if (!endMatch) return false;
297
+ const endIndex = startIndex + endMatch.index + endMatch[0].length;
298
+ s.overwrite(startIndex - 1, endIndex, snapString);
299
+ return true;
300
+ }
301
+ var INDENTATION_REGEX = /^([^\S\n]*)\S/m;
302
+ function stripSnapshotIndentation(inlineSnapshot) {
303
+ const match = inlineSnapshot.match(INDENTATION_REGEX);
304
+ if (!match || !match[1]) return inlineSnapshot;
305
+ const indentation = match[1];
306
+ const lines = inlineSnapshot.split(/\n/g);
307
+ if (lines.length <= 2) return inlineSnapshot;
308
+ if (lines[0].trim() !== "" || lines.at(-1)?.trim() !== "") return inlineSnapshot;
309
+ for (let i = 1; i < lines.length - 1; i++) if (lines[i] !== "") {
310
+ if (lines[i].indexOf(indentation) !== 0) return inlineSnapshot;
311
+ lines[i] = lines[i].substring(indentation.length);
312
+ }
313
+ lines[lines.length - 1] = "";
314
+ inlineSnapshot = lines.join("\n");
315
+ return inlineSnapshot;
316
+ }
317
+ async function saveRawSnapshots(environment, snapshots) {
318
+ await Promise.all(snapshots.map(async (snap) => {
319
+ if (!snap.readonly) await environment.saveSnapshotFile(snap.file, snap.snapshot);
320
+ }));
321
+ }
307
322
  function isSameStackPosition(x, y) {
308
323
  return x.file === y.file && x.column === y.column && x.line === y.line;
309
324
  }
@@ -367,13 +382,18 @@ var SnapshotState = class SnapshotState {
367
382
  this._snapshotFormat = {
368
383
  printBasicPrototype: false,
369
384
  escapeString: false,
385
+ maxOutputLength: 2 ** 27,
370
386
  ...options.snapshotFormat
371
387
  };
372
388
  this._environment = options.snapshotEnvironment;
373
389
  }
374
390
  static async create(testFilePath, options) {
375
391
  const snapshotPath = await options.snapshotEnvironment.resolvePath(testFilePath);
376
- return new SnapshotState(testFilePath, snapshotPath, await options.snapshotEnvironment.readSnapshotFile(snapshotPath), options);
392
+ const content = await options.snapshotEnvironment.readSnapshotFile(snapshotPath);
393
+ return new SnapshotState(testFilePath, snapshotPath, content, options);
394
+ }
395
+ get snapshotUpdateState() {
396
+ return this._updateSnapshot;
377
397
  }
378
398
  get environment() {
379
399
  return this._environment;
@@ -403,19 +423,24 @@ var SnapshotState = class SnapshotState {
403
423
  _inferInlineSnapshotStack(stacks) {
404
424
  const promiseIndex = stacks.findIndex((i) => i.method.match(/__VITEST_(RESOLVES|REJECTS)__/));
405
425
  if (promiseIndex !== -1) return stacks[promiseIndex + 3];
426
+ const pollChainIndex = stacks.findIndex((i) => i.method.match(/__VITEST_POLL_CHAIN__/));
427
+ if (pollChainIndex !== -1) return stacks[pollChainIndex + 1];
406
428
  for (let i = 0; i < stacks.length; i++) {
407
429
  const match = stacks[i].method.match(/__INLINE_SNAPSHOT_OFFSET_(\d+)__/);
408
430
  if (match) return stacks[i + Number(match[1])] ?? null;
409
431
  }
432
+ const customMatcherIndex = stacks.findIndex((i) => i.method.includes("__VITEST_EXTEND_ASSERTION__"));
433
+ if (customMatcherIndex !== -1) return stacks[customMatcherIndex + 3] ?? null;
410
434
  const stackIndex = stacks.findIndex((i) => i.method.includes("__INLINE_SNAPSHOT__"));
411
435
  return stackIndex !== -1 ? stacks[stackIndex + 2] : null;
412
436
  }
413
437
  _addSnapshot(key, receivedSerialized, options) {
414
438
  this._dirty = true;
415
439
  if (options.stack) this._inlineSnapshots.push({
440
+ ...options.stack,
416
441
  snapshot: receivedSerialized,
417
442
  testId: options.testId,
418
- ...options.stack
443
+ assertionName: options.assertionName
419
444
  });
420
445
  else if (options.rawSnapshot) this._rawSnapshots.push({
421
446
  ...options.rawSnapshot,
@@ -423,6 +448,90 @@ var SnapshotState = class SnapshotState {
423
448
  });
424
449
  else this._snapshotData[key] = receivedSerialized;
425
450
  }
451
+ _resolveKey(testId, testName, key) {
452
+ this._counters.increment(testName);
453
+ const count = this._counters.get(testName);
454
+ if (!key) key = testNameToKey(testName, count);
455
+ this._testIdToKeys.get(testId).push(key);
456
+ return {
457
+ key,
458
+ count
459
+ };
460
+ }
461
+ _resolveInlineStack(options) {
462
+ const { testId, snapshot, assertionName, error } = options;
463
+ const stacks = parseErrorStacktrace(error, { ignoreStackEntries: [] });
464
+ const _stack = this._inferInlineSnapshotStack(stacks);
465
+ if (!_stack) {
466
+ const message = stacks.map((s) => ` ${s.file}:${s.line}:${s.column}${s.method ? ` (${s.method})` : ""}`).join("\n");
467
+ throw new Error(`@vitest/snapshot: Couldn't infer stack frame for inline snapshot.\n${message}`);
468
+ }
469
+ const stack = this.environment.processStackTrace?.(_stack) || _stack;
470
+ stack.column--;
471
+ const snapshotsWithSameStack = this._inlineSnapshotStacks.filter((s) => isSameStackPosition(s, stack));
472
+ if (snapshotsWithSameStack.length > 0) {
473
+ this._inlineSnapshots = this._inlineSnapshots.filter((s) => !isSameStackPosition(s, stack));
474
+ const differentSnapshot = snapshotsWithSameStack.find((s) => s.snapshot !== snapshot);
475
+ if (differentSnapshot) throw Object.assign(/* @__PURE__ */ new Error(`${assertionName} with different snapshots cannot be called at the same location`), {
476
+ actual: snapshot,
477
+ expected: differentSnapshot.snapshot
478
+ });
479
+ }
480
+ this._inlineSnapshotStacks.push({
481
+ ...stack,
482
+ testId,
483
+ snapshot
484
+ });
485
+ return stack;
486
+ }
487
+ _reconcile(opts) {
488
+ if (opts.hasSnapshot && this._updateSnapshot === "all" || (!opts.hasSnapshot || !opts.snapshotIsPersisted) && (this._updateSnapshot === "new" || this._updateSnapshot === "all")) {
489
+ if (this._updateSnapshot === "all") if (!opts.pass) {
490
+ if (opts.hasSnapshot) this.updated.increment(opts.testId);
491
+ else this.added.increment(opts.testId);
492
+ this._addSnapshot(opts.key, opts.addValue, {
493
+ stack: opts.stack,
494
+ testId: opts.testId,
495
+ rawSnapshot: opts.rawSnapshot,
496
+ assertionName: opts.assertionName
497
+ });
498
+ } else this.matched.increment(opts.testId);
499
+ else {
500
+ this._addSnapshot(opts.key, opts.addValue, {
501
+ stack: opts.stack,
502
+ testId: opts.testId,
503
+ rawSnapshot: opts.rawSnapshot,
504
+ assertionName: opts.assertionName
505
+ });
506
+ this.added.increment(opts.testId);
507
+ }
508
+ return {
509
+ actual: "",
510
+ count: opts.count,
511
+ expected: "",
512
+ key: opts.key,
513
+ pass: true
514
+ };
515
+ } else if (!opts.pass) {
516
+ this.unmatched.increment(opts.testId);
517
+ return {
518
+ actual: opts.actualDisplay,
519
+ count: opts.count,
520
+ expected: opts.expectedDisplay,
521
+ key: opts.key,
522
+ pass: false
523
+ };
524
+ } else {
525
+ this.matched.increment(opts.testId);
526
+ return {
527
+ actual: "",
528
+ count: opts.count,
529
+ expected: "",
530
+ key: opts.key,
531
+ pass: true
532
+ };
533
+ }
534
+ }
426
535
  async save() {
427
536
  const hasExternalSnapshots = Object.keys(this._snapshotData).length;
428
537
  const hasInlineSnapshots = this._inlineSnapshots.length;
@@ -462,11 +571,24 @@ var SnapshotState = class SnapshotState {
462
571
  this._uncheckedKeys.clear();
463
572
  }
464
573
  }
465
- match({ testId, testName, received, key, inlineSnapshot, isInline, error, rawSnapshot }) {
466
- this._counters.increment(testName);
467
- const count = this._counters.get(testName);
468
- if (!key) key = testNameToKey(testName, count);
469
- this._testIdToKeys.get(testId).push(key);
574
+ probeExpectedSnapshot(options) {
575
+ const count = this._counters.get(options.testName) + 1;
576
+ const key = testNameToKey(options.testName, count);
577
+ return {
578
+ key,
579
+ count,
580
+ data: options?.isInline ? options.inlineSnapshot : this._snapshotData[key],
581
+ markAsChecked: () => {
582
+ this._counters.increment(options.testName);
583
+ this._testIdToKeys.get(options.testId).push(key);
584
+ this._uncheckedKeys.delete(key);
585
+ }
586
+ };
587
+ }
588
+ match({ testId, testName, received, key, inlineSnapshot, isInline, error, rawSnapshot, assertionName }) {
589
+ const resolved = this._resolveKey(testId, testName, key);
590
+ key = resolved.key;
591
+ const count = resolved.count;
470
592
  if (!(isInline && this._snapshotData[key] !== void 0)) this._uncheckedKeys.delete(key);
471
593
  let receivedSerialized = rawSnapshot && typeof received === "string" ? received : serialize(received, void 0, this._snapshotFormat);
472
594
  if (!rawSnapshot) receivedSerialized = addExtraLineBreaks(receivedSerialized);
@@ -479,72 +601,49 @@ var SnapshotState = class SnapshotState {
479
601
  const hasSnapshot = expected !== void 0;
480
602
  const snapshotIsPersisted = isInline || this._fileExists || rawSnapshot && rawSnapshot.content != null;
481
603
  if (pass && !isInline && !rawSnapshot) this._snapshotData[key] = receivedSerialized;
482
- let stack;
483
- if (isInline) {
484
- const stacks = parseErrorStacktrace(error || /* @__PURE__ */ new Error("snapshot"), { ignoreStackEntries: [] });
485
- const _stack = this._inferInlineSnapshotStack(stacks);
486
- if (!_stack) throw new Error(`@vitest/snapshot: Couldn't infer stack frame for inline snapshot.\n${JSON.stringify(stacks)}`);
487
- stack = this.environment.processStackTrace?.(_stack) || _stack;
488
- stack.column--;
489
- const snapshotsWithSameStack = this._inlineSnapshotStacks.filter((s) => isSameStackPosition(s, stack));
490
- if (snapshotsWithSameStack.length > 0) {
491
- this._inlineSnapshots = this._inlineSnapshots.filter((s) => !isSameStackPosition(s, stack));
492
- const differentSnapshot = snapshotsWithSameStack.find((s) => s.snapshot !== receivedSerialized);
493
- if (differentSnapshot) throw Object.assign(/* @__PURE__ */ new Error("toMatchInlineSnapshot with different snapshots cannot be called at the same location"), {
494
- actual: receivedSerialized,
495
- expected: differentSnapshot.snapshot
496
- });
497
- }
498
- this._inlineSnapshotStacks.push({
499
- ...stack,
500
- testId,
501
- snapshot: receivedSerialized
502
- });
503
- }
504
- if (hasSnapshot && this._updateSnapshot === "all" || (!hasSnapshot || !snapshotIsPersisted) && (this._updateSnapshot === "new" || this._updateSnapshot === "all")) {
505
- if (this._updateSnapshot === "all") if (!pass) {
506
- if (hasSnapshot) this.updated.increment(testId);
507
- else this.added.increment(testId);
508
- this._addSnapshot(key, receivedSerialized, {
509
- stack,
510
- testId,
511
- rawSnapshot
512
- });
513
- } else this.matched.increment(testId);
514
- else {
515
- this._addSnapshot(key, receivedSerialized, {
516
- stack,
517
- testId,
518
- rawSnapshot
519
- });
520
- this.added.increment(testId);
521
- }
522
- return {
523
- actual: "",
524
- count,
525
- expected: "",
526
- key,
527
- pass: true
528
- };
529
- } else if (!pass) {
530
- this.unmatched.increment(testId);
531
- return {
532
- actual: rawSnapshot ? receivedSerialized : removeExtraLineBreaks(receivedSerialized),
533
- count,
534
- expected: expectedTrimmed !== void 0 ? rawSnapshot ? expectedTrimmed : removeExtraLineBreaks(expectedTrimmed) : void 0,
535
- key,
536
- pass: false
537
- };
538
- } else {
539
- this.matched.increment(testId);
540
- return {
541
- actual: "",
542
- count,
543
- expected: "",
544
- key,
545
- pass: true
546
- };
547
- }
604
+ const stack = isInline ? this._resolveInlineStack({
605
+ testId,
606
+ snapshot: receivedSerialized,
607
+ assertionName: assertionName || "toMatchInlineSnapshot",
608
+ error: error || /* @__PURE__ */ new Error("snapshot")
609
+ }) : void 0;
610
+ return this._reconcile({
611
+ testId,
612
+ key,
613
+ count,
614
+ pass,
615
+ hasSnapshot,
616
+ snapshotIsPersisted: !!snapshotIsPersisted,
617
+ addValue: receivedSerialized,
618
+ actualDisplay: rawSnapshot ? receivedSerialized : removeExtraLineBreaks(receivedSerialized),
619
+ expectedDisplay: expectedTrimmed !== void 0 ? rawSnapshot ? expectedTrimmed : removeExtraLineBreaks(expectedTrimmed) : void 0,
620
+ stack,
621
+ rawSnapshot,
622
+ assertionName
623
+ });
624
+ }
625
+ processDomainSnapshot({ testId, received, expectedSnapshot, matchResult, isInline, error, assertionName }) {
626
+ const stack = isInline ? this._resolveInlineStack({
627
+ testId,
628
+ snapshot: received,
629
+ assertionName,
630
+ error: error || /* @__PURE__ */ new Error("STACK_TRACE_ERROR")
631
+ }) : void 0;
632
+ const actualResolved = matchResult?.resolved ?? received;
633
+ const expectedResolved = matchResult?.expected ?? expectedSnapshot.data;
634
+ return this._reconcile({
635
+ testId,
636
+ key: expectedSnapshot.key,
637
+ count: expectedSnapshot.count,
638
+ pass: matchResult?.pass ?? false,
639
+ hasSnapshot: !!expectedSnapshot.data,
640
+ snapshotIsPersisted: isInline ? true : this._fileExists,
641
+ addValue: actualResolved,
642
+ actualDisplay: removeExtraLineBreaks(actualResolved),
643
+ expectedDisplay: expectedResolved !== void 0 ? removeExtraLineBreaks(expectedResolved) : void 0,
644
+ stack,
645
+ assertionName
646
+ });
548
647
  }
549
648
  async pack() {
550
649
  const snapshot = {
@@ -613,22 +712,41 @@ var SnapshotClient = class {
613
712
  if (!state) throw new Error(`The snapshot state for '${filepath}' is not found. Did you call 'SnapshotClient.setup()'?`);
614
713
  return state;
615
714
  }
616
- assert(options) {
617
- const { filepath, name, testId = name, message, isInline = false, properties, inlineSnapshot, error, errorMessage, rawSnapshot } = options;
715
+ match(options) {
716
+ const { filepath, name, testId = name, message, isInline = false, properties, inlineSnapshot, error, errorMessage, rawSnapshot, assertionName } = options;
618
717
  let { received } = options;
619
718
  if (!filepath) throw new Error("Snapshot cannot be used outside of test");
620
719
  const snapshotState = this.getSnapshotState(filepath);
720
+ const testName = [name, ...message ? [message] : []].join(" > ");
721
+ const expectedSnapshot = snapshotState.probeExpectedSnapshot({
722
+ testName,
723
+ testId,
724
+ isInline,
725
+ inlineSnapshot
726
+ });
621
727
  if (typeof properties === "object") {
622
- if (typeof received !== "object" || !received) throw new Error("Received value must be an object when the matcher has properties");
728
+ if (typeof received !== "object" || !received) {
729
+ expectedSnapshot.markAsChecked();
730
+ throw new Error("Received value must be an object when the matcher has properties");
731
+ }
732
+ let propertiesPass;
623
733
  try {
624
- if (!(this.options.isEqual?.(received, properties) ?? false)) throw createMismatchError("Snapshot properties mismatched", snapshotState.expand, received, properties);
625
- else received = deepMergeSnapshot(received, properties);
734
+ propertiesPass = this.options.isEqual?.(received, properties) ?? false;
626
735
  } catch (err) {
627
- err.message = errorMessage || "Snapshot mismatched";
736
+ expectedSnapshot.markAsChecked();
628
737
  throw err;
629
738
  }
739
+ if (!propertiesPass) {
740
+ expectedSnapshot.markAsChecked();
741
+ return {
742
+ pass: false,
743
+ message: () => errorMessage || "Snapshot properties mismatched",
744
+ actual: received,
745
+ expected: properties
746
+ };
747
+ }
748
+ received = deepMergeSnapshot(received, properties);
630
749
  }
631
- const testName = [name, ...message ? [message] : []].join(" > ");
632
750
  const { actual, expected, key, pass } = snapshotState.match({
633
751
  testId,
634
752
  testName,
@@ -636,9 +754,97 @@ var SnapshotClient = class {
636
754
  isInline,
637
755
  error,
638
756
  inlineSnapshot,
639
- rawSnapshot
757
+ rawSnapshot,
758
+ assertionName
640
759
  });
641
- if (!pass) throw createMismatchError(`Snapshot \`${key || "unknown"}\` mismatched`, snapshotState.expand, rawSnapshot ? actual : actual?.trim(), rawSnapshot ? expected : expected?.trim());
760
+ return {
761
+ pass,
762
+ message: () => `Snapshot \`${key || "unknown"}\` mismatched`,
763
+ actual: rawSnapshot ? actual : actual?.trim(),
764
+ expected: rawSnapshot ? expected : expected?.trim()
765
+ };
766
+ }
767
+ assert(options) {
768
+ const result = this.match(options);
769
+ if (!result.pass) {
770
+ const snapshotState = this.getSnapshotState(options.filepath);
771
+ throw createMismatchError(result.message(), snapshotState.expand, result.actual, result.expected);
772
+ }
773
+ }
774
+ matchDomain(options) {
775
+ const { received, filepath, name, testId = name, message, adapter, isInline = false, inlineSnapshot, error } = options;
776
+ if (!filepath) throw new Error("Snapshot cannot be used outside of test");
777
+ const captured = adapter.capture(received);
778
+ const rendered = adapter.render(captured);
779
+ const snapshotState = this.getSnapshotState(filepath);
780
+ const testName = [name, ...message ? [message] : []].join(" > ");
781
+ const expectedSnapshot = snapshotState.probeExpectedSnapshot({
782
+ testName,
783
+ testId,
784
+ isInline,
785
+ inlineSnapshot
786
+ });
787
+ expectedSnapshot.markAsChecked();
788
+ const matchResult = expectedSnapshot.data ? adapter.match(captured, adapter.parseExpected(expectedSnapshot.data)) : void 0;
789
+ const { actual, expected, key, pass } = snapshotState.processDomainSnapshot({
790
+ testId,
791
+ received: rendered,
792
+ expectedSnapshot,
793
+ matchResult,
794
+ isInline,
795
+ error,
796
+ assertionName: options.assertionName
797
+ });
798
+ return {
799
+ pass,
800
+ message: () => `Snapshot \`${key}\` mismatched`,
801
+ actual: actual?.trim(),
802
+ expected: expected?.trim()
803
+ };
804
+ }
805
+ async pollMatchDomain(options) {
806
+ const { poll, filepath, name, testId = name, message, adapter, isInline = false, inlineSnapshot, error, timeout = 1e3, interval = 50 } = options;
807
+ if (!filepath) throw new Error("Snapshot cannot be used outside of test");
808
+ const snapshotState = this.getSnapshotState(filepath);
809
+ const testName = [name, ...message ? [message] : []].join(" > ");
810
+ const expectedSnapshot = snapshotState.probeExpectedSnapshot({
811
+ testName,
812
+ testId,
813
+ isInline,
814
+ inlineSnapshot
815
+ });
816
+ const reference = expectedSnapshot.data && snapshotState.snapshotUpdateState !== "all" ? adapter.parseExpected(expectedSnapshot.data) : void 0;
817
+ const stableResult = await getStableSnapshot({
818
+ adapter,
819
+ poll,
820
+ interval,
821
+ timedOut: timeout > 0 ? new Promise((r) => setTimeout(r, timeout)) : void 0,
822
+ match: reference ? (captured) => adapter.match(captured, reference).pass : void 0
823
+ });
824
+ expectedSnapshot.markAsChecked();
825
+ if (!stableResult?.rendered) {
826
+ if (stableResult?.lastPollError) throw stableResult.lastPollError;
827
+ return {
828
+ pass: false,
829
+ message: () => `poll() did not produce a stable snapshot within the timeout`
830
+ };
831
+ }
832
+ const matchResult = expectedSnapshot.data ? adapter.match(stableResult.captured, adapter.parseExpected(expectedSnapshot.data)) : void 0;
833
+ const { actual, expected, key, pass } = snapshotState.processDomainSnapshot({
834
+ testId,
835
+ received: stableResult.rendered,
836
+ expectedSnapshot,
837
+ matchResult,
838
+ isInline,
839
+ error,
840
+ assertionName: options.assertionName
841
+ });
842
+ return {
843
+ pass,
844
+ message: () => `Snapshot \`${key}\` mismatched`,
845
+ actual: actual?.trim(),
846
+ expected: expected?.trim()
847
+ };
642
848
  }
643
849
  async assertRaw(options) {
644
850
  if (!options.rawSnapshot) throw new Error("Raw snapshot is required");
@@ -656,5 +862,59 @@ var SnapshotClient = class {
656
862
  this.snapshotStateMap.clear();
657
863
  }
658
864
  };
865
+ /**
866
+ * Polls repeatedly until the value reaches a stable state.
867
+ *
868
+ * Compares consecutive rendered outputs from the current session —
869
+ * when two consecutive polls produce the same rendered string,
870
+ * the value is considered stable.
871
+ *
872
+ * Every `await` (poll call, interval delay) races against `timedOut`
873
+ * so that hanging polls and delays are interrupted.
874
+ */
875
+ async function getStableSnapshot({ adapter, poll, interval, timedOut, match }) {
876
+ let lastRendered;
877
+ let lastPollError;
878
+ let lastStable;
879
+ while (true) {
880
+ try {
881
+ const pollResult = await raceWith(Promise.resolve(poll()), timedOut);
882
+ if (!pollResult.ok) break;
883
+ const captured = adapter.capture(pollResult.value);
884
+ const rendered = adapter.render(captured);
885
+ if (lastRendered !== void 0 && rendered === lastRendered) {
886
+ lastStable = {
887
+ captured,
888
+ rendered
889
+ };
890
+ if (!match || match(captured)) break;
891
+ } else {
892
+ lastRendered = rendered;
893
+ lastStable = void 0;
894
+ }
895
+ } catch (pollError) {
896
+ lastRendered = void 0;
897
+ lastStable = void 0;
898
+ lastPollError = pollError;
899
+ }
900
+ if (!(await raceWith(new Promise((r) => setTimeout(r, interval)), timedOut)).ok) break;
901
+ }
902
+ return {
903
+ ...lastStable,
904
+ lastPollError
905
+ };
906
+ }
907
+ /** Type-safe `Promise.race` — tells you which promise won. */
908
+ function raceWith(promise, other) {
909
+ const left = promise.then((value) => ({
910
+ ok: true,
911
+ value
912
+ }));
913
+ if (!other) return left;
914
+ return Promise.race([left, other.then((value) => ({
915
+ ok: false,
916
+ value
917
+ }))]);
918
+ }
659
919
  //#endregion
660
- export { SnapshotClient, addSerializer, stripSnapshotIndentation };
920
+ export { SnapshotClient, SnapshotState, addSerializer, getSerializers, stripSnapshotIndentation };