vitest-pool-assemblyscript 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/BINARYEN_VERSION +1 -1
  2. package/assembly/compare.ts +11 -12
  3. package/assembly/describe.ts +4 -4
  4. package/assembly/expect.ts +44 -26
  5. package/assembly/test.ts +9 -9
  6. package/assembly/utils.ts +218 -62
  7. package/binding.gyp +4 -4
  8. package/dist/{addon-interface-CYFXMbK7.mjs → addon-interface-DJB-K27u.mjs} +12 -12
  9. package/dist/addon-interface-DJB-K27u.mjs.map +1 -0
  10. package/dist/{ast-visitor-CWEOd3UH.mjs → ast-visitor-w1HMbuJR.mjs} +2 -2
  11. package/dist/{ast-visitor-CWEOd3UH.mjs.map → ast-visitor-w1HMbuJR.mjs.map} +1 -1
  12. package/dist/compile-runner-D4SJWhMh.mjs +82 -0
  13. package/dist/compile-runner-D4SJWhMh.mjs.map +1 -0
  14. package/dist/compiler/transforms/deep-equals.d.mts.map +1 -1
  15. package/dist/compiler/transforms/deep-equals.mjs +61 -22
  16. package/dist/compiler/transforms/deep-equals.mjs.map +1 -1
  17. package/dist/compiler/transforms/strip-inline.mjs +2 -2
  18. package/dist/{compiler-hUlDr5vL.mjs → compiler-DSKhQ5--.mjs} +58 -28
  19. package/dist/compiler-DSKhQ5--.mjs.map +1 -0
  20. package/dist/config/index-v3.d.mts +1 -1
  21. package/dist/config/index-v3.d.mts.map +1 -1
  22. package/dist/config/index-v3.mjs.map +1 -1
  23. package/dist/config/index.d.mts +2 -2
  24. package/dist/config/index.mjs +5 -7
  25. package/dist/{constants-DbxJ3hzg.mjs → constants-Bq5KNxXJ.mjs} +4 -2
  26. package/dist/constants-Bq5KNxXJ.mjs.map +1 -0
  27. package/dist/{coverage-merge-CBXkpM1O.mjs → coverage-merge-0WqdC-dq.mjs} +1 -1
  28. package/dist/{coverage-merge-CBXkpM1O.mjs.map → coverage-merge-0WqdC-dq.mjs.map} +1 -1
  29. package/dist/coverage-provider/index.mjs +36 -36
  30. package/dist/coverage-provider/index.mjs.map +1 -1
  31. package/dist/{feature-check-Bje3ntpV.mjs → feature-check-DLfJqIrE.mjs} +4 -4
  32. package/dist/{feature-check-Bje3ntpV.mjs.map → feature-check-DLfJqIrE.mjs.map} +1 -1
  33. package/dist/index-internal.d.mts +3 -3
  34. package/dist/index-internal.d.mts.map +1 -1
  35. package/dist/index-internal.mjs +5 -4
  36. package/dist/index-v3.d.mts.map +1 -1
  37. package/dist/index-v3.mjs +19 -33
  38. package/dist/index-v3.mjs.map +1 -1
  39. package/dist/index.d.mts +1 -1
  40. package/dist/index.mjs +5 -7
  41. package/dist/{load-user-imports-Bx5ZlhSm.mjs → load-user-imports-6Pv-9hRg.mjs} +103 -229
  42. package/dist/load-user-imports-6Pv-9hRg.mjs.map +1 -0
  43. package/dist/pool-errors-GWfwrsD7.mjs +631 -0
  44. package/dist/pool-errors-GWfwrsD7.mjs.map +1 -0
  45. package/dist/{pool-runner-init-CNpRdA5u.d.mts → pool-runner-init-CCvnKt5o.d.mts} +2 -2
  46. package/dist/pool-runner-init-CCvnKt5o.d.mts.map +1 -0
  47. package/dist/{pool-runner-init-BqkwQ2tk.mjs → pool-runner-init-Cta6aVJ6.mjs} +15 -30
  48. package/dist/pool-runner-init-Cta6aVJ6.mjs.map +1 -0
  49. package/dist/pool-thread/compile-worker-thread.d.mts +1 -1
  50. package/dist/pool-thread/compile-worker-thread.d.mts.map +1 -1
  51. package/dist/pool-thread/compile-worker-thread.mjs +29 -19
  52. package/dist/pool-thread/compile-worker-thread.mjs.map +1 -1
  53. package/dist/pool-thread/test-worker-thread.d.mts +1 -1
  54. package/dist/pool-thread/test-worker-thread.d.mts.map +1 -1
  55. package/dist/pool-thread/test-worker-thread.mjs +25 -18
  56. package/dist/pool-thread/test-worker-thread.mjs.map +1 -1
  57. package/dist/pool-thread/v3-tinypool-thread.d.mts +1 -1
  58. package/dist/pool-thread/v3-tinypool-thread.d.mts.map +1 -1
  59. package/dist/pool-thread/v3-tinypool-thread.mjs +43 -33
  60. package/dist/pool-thread/v3-tinypool-thread.mjs.map +1 -1
  61. package/dist/test-runner-M21HMDdH.mjs +147 -0
  62. package/dist/test-runner-M21HMDdH.mjs.map +1 -0
  63. package/dist/{types-DHVk5iAx.d.mts → types-CoroKYxB.d.mts} +39 -16
  64. package/dist/types-CoroKYxB.d.mts.map +1 -0
  65. package/dist/vitest-file-tasks-Coc4btUw.mjs +473 -0
  66. package/dist/vitest-file-tasks-Coc4btUw.mjs.map +1 -0
  67. package/dist/wasm-memory-C8Nkl2Sz.mjs +134 -0
  68. package/dist/wasm-memory-C8Nkl2Sz.mjs.map +1 -0
  69. package/dist/{worker-rpc-channel-CZZIxtv5.mjs → worker-rpc-channel-CvCrc8aa.mjs} +1 -1
  70. package/dist/{worker-rpc-channel-CZZIxtv5.mjs.map → worker-rpc-channel-CvCrc8aa.mjs.map} +1 -1
  71. package/package.json +2 -2
  72. package/prebuilds/darwin-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  73. package/prebuilds/darwin-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  74. package/prebuilds/linux-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  75. package/prebuilds/linux-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  76. package/prebuilds/linux-x64/vitest-pool-assemblyscript.musl.node +0 -0
  77. package/prebuilds/win32-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  78. package/prebuilds/win32-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  79. package/src/instrumentation/native/addon.cpp +71 -32
  80. package/dist/addon-interface-CYFXMbK7.mjs.map +0 -1
  81. package/dist/compile-runner-BGQhBkBo.mjs +0 -85
  82. package/dist/compile-runner-BGQhBkBo.mjs.map +0 -1
  83. package/dist/compiler-hUlDr5vL.mjs.map +0 -1
  84. package/dist/constants-DbxJ3hzg.mjs.map +0 -1
  85. package/dist/debug-DtRAL4rM.mjs +0 -232
  86. package/dist/debug-DtRAL4rM.mjs.map +0 -1
  87. package/dist/load-user-imports-Bx5ZlhSm.mjs.map +0 -1
  88. package/dist/path-utils-t9OzjXYF.mjs +0 -24
  89. package/dist/path-utils-t9OzjXYF.mjs.map +0 -1
  90. package/dist/pool-runner-init-BqkwQ2tk.mjs.map +0 -1
  91. package/dist/pool-runner-init-CNpRdA5u.d.mts.map +0 -1
  92. package/dist/resolve-config-s9gSJSMc.mjs +0 -85
  93. package/dist/resolve-config-s9gSJSMc.mjs.map +0 -1
  94. package/dist/test-runner-BGqc9uCK.mjs +0 -138
  95. package/dist/test-runner-BGqc9uCK.mjs.map +0 -1
  96. package/dist/types-DHVk5iAx.d.mts.map +0 -1
  97. package/dist/vitest-file-tasks-D8sOClGX.mjs +0 -149
  98. package/dist/vitest-file-tasks-D8sOClGX.mjs.map +0 -1
  99. package/dist/vitest-tasks-BZ24sghI.mjs +0 -321
  100. package/dist/vitest-tasks-BZ24sghI.mjs.map +0 -1
  101. package/dist/wasm-names-BFtzQCH4.mjs +0 -124
  102. package/dist/wasm-names-BFtzQCH4.mjs.map +0 -1
@@ -0,0 +1,631 @@
1
+ import { POOL_ERROR_NAMES, POOL_INTERNAL_PATHS, TEST_ERROR_NAMES } from "./constants-Bq5KNxXJ.mjs";
2
+ import { relative } from "node:path";
3
+ import { readFile } from "node:fs/promises";
4
+ import { stripVTControlCharacters } from "node:util";
5
+ import { fileURLToPath } from "node:url";
6
+ import c from "tinyrainbow";
7
+ import { highlight } from "tinyhighlight";
8
+ import { diff } from "@vitest/utils/diff";
9
+ import { SourceMapConsumer } from "source-map";
10
+
11
+ //#region src/util/path-utils.ts
12
+ /**
13
+ * Path Utilities
14
+ *
15
+ * Cross-platform path normalization for consistent path comparisons.
16
+ * All internal paths use forward slashes.
17
+ */
18
+ /**
19
+ * Convert path to forward slashes for consistent cross-platform comparison.
20
+ *
21
+ * Source maps always use forward slashes regardless of OS. By normalizing
22
+ * all paths to forward slashes, we ensure consistent matching between:
23
+ * - Source map paths (already forward slashes)
24
+ * - Glob results (OS-native, need conversion on Windows)
25
+ * - Relative paths from Node's path.relative() (OS-native)
26
+ * - Resolved paths from Node's path.resolve() (OS-native)
27
+ */
28
+ function toForwardSlash(path) {
29
+ return path.replace(/\\/g, "/");
30
+ }
31
+
32
+ //#endregion
33
+ //#region src/util/debug.ts
34
+ globalThis.AS_POOL_DEBUG = false;
35
+ const DEBUG_ENV_ENABLED_VALUE = "vitest_as_pool";
36
+ function isEnabled() {
37
+ return globalThis.AS_POOL_DEBUG === true || process.env.DEBUG === DEBUG_ENV_ENABLED_VALUE;
38
+ }
39
+ /**
40
+ * Initialize debug mode for current async context (called by worker at task start)
41
+ * @param {boolean} debugEnabled - Enable verbose debug logging
42
+ */
43
+ function setGlobalDebugMode(debugEnabled) {
44
+ globalThis.AS_POOL_DEBUG = debugEnabled;
45
+ }
46
+ function debugLog(...args) {
47
+ if (args?.length > 0 && typeof args[0] === "function") {
48
+ const result = args[0]();
49
+ const rest = args.length > 1 ? args.slice(1) : [];
50
+ console.log(Date.now(), String(result), ...rest);
51
+ } else console.log(Date.now(), ...args);
52
+ }
53
+ /**
54
+ * Log debug message (only when debug enabled in current global context)
55
+ * or when environment has a given DEBUG variable set.
56
+ */
57
+ function debug(...args) {
58
+ if (isEnabled()) debugLog(...args);
59
+ }
60
+ /**
61
+ * Log debug message (caller expected to determine if enabled)
62
+ */
63
+ function debugOverride(...args) {
64
+ debugLog(...args);
65
+ }
66
+
67
+ //#endregion
68
+ //#region src/util/highlight-code.ts
69
+ /**
70
+ * Adapted from vitest. The internal function was changed between vitest 3.2.x and 4.0.x,
71
+ * and then removed from public exposure in 4.1.x, so now instead we recreate the same
72
+ * highlighting color rules.
73
+ *
74
+ * @see https://github.com/vitest-dev/vitest/blob/v4.1.0/packages/vitest/src/utils/colors.ts#L18
75
+ *
76
+ * Vitest is released under the MIT license, included in this project's root.
77
+ * Copyright (c) 2021-Present Vitest Team
78
+ */
79
+ const colors = {
80
+ Keyword: c.magenta,
81
+ IdentifierCapitalized: c.yellow,
82
+ Punctuator: c.yellow,
83
+ StringLiteral: c.green,
84
+ NoSubstitutionTemplate: c.green,
85
+ MultiLineComment: c.gray,
86
+ SingleLineComment: c.gray,
87
+ RegularExpressionLiteral: c.cyan,
88
+ NumericLiteral: c.blue,
89
+ TemplateHead: (text) => c.green(text.slice(0, text.length - 2)) + c.cyan(text.slice(-2)),
90
+ TemplateTail: (text) => c.cyan(text.slice(0, 1)) + c.green(text.slice(1)),
91
+ TemplateMiddle: (text) => c.cyan(text.slice(0, 1)) + c.green(text.slice(1, text.length - 2)) + c.cyan(text.slice(-2)),
92
+ IdentifierCallable: c.blue,
93
+ PrivateIdentifierCallable: (text) => `#${c.blue(text.slice(1))}`,
94
+ Invalid: (text) => c.white(c.bgRed(c.bold(text)))
95
+ };
96
+ function highlightCode(source) {
97
+ return highlight(source, { colors });
98
+ }
99
+
100
+ //#endregion
101
+ //#region src/util/test-error-formatting.ts
102
+ const FRAME_POINTER = "❯";
103
+ const CODE_FRAME_INDENT_SPACES = 4;
104
+ const MAX_CODE_HIGHLIGHT_LENGTH = 1e5;
105
+ function getYellowString(str) {
106
+ return c.yellow(str);
107
+ }
108
+ function toPlaintextStackFrameString(frame) {
109
+ return ` at ${frame.method} ${frame.file}:${frame.line}:${frame.column}`;
110
+ }
111
+ function toVitestLikeStackFrameString(frame) {
112
+ return c.cyan(` ${c.dim(FRAME_POINTER)} ${frame.method} ${frame.file}:${c.dim(`${frame.line}:${frame.column}`)}`);
113
+ }
114
+ async function getSourceCodeFrameString(sourceMap, frame) {
115
+ let source;
116
+ if (!sourceMap) return;
117
+ const fileIndex = sourceMap.sources.indexOf(frame.file);
118
+ if (fileIndex < 0 || !sourceMap.sourcesContent) source = await readFile(fileURLToPath(frame.file), "utf-8");
119
+ else source = sourceMap.sourcesContent[fileIndex];
120
+ if (!source) return;
121
+ return generateCodeFrame(source.length < MAX_CODE_HIGHLIGHT_LENGTH ? highlightCode(source) : source, CODE_FRAME_INDENT_SPACES, frame);
122
+ }
123
+ /**
124
+ * Vitest doesn't expose generateCodeFrame as a util, so we have
125
+ * recreated it here with minimal changes.
126
+ *
127
+ * @see https://github.com/vitest-dev/vitest/blob/v3.2.4/packages/vitest/src/node/printError.ts#L424
128
+ *
129
+ * Vitest is released under the MIT license, included in this project's root.
130
+ * Copyright (c) 2021-Present Vitest Team
131
+ */
132
+ const lineSplitRE = /\r?\n/;
133
+ function generateCodeFrame(source, indent = 0, loc, range = 2) {
134
+ const start = typeof loc === "object" ? positionToOffset(source, loc.line, loc.column) : loc;
135
+ const end = start;
136
+ const lines = source.split(lineSplitRE);
137
+ const nl = /\r\n/.test(source) ? 2 : 1;
138
+ let count = 0;
139
+ let res = [];
140
+ const columns = process.stdout?.columns || 80;
141
+ for (let i = 0; i < lines.length; i++) {
142
+ count += lines[i].length + nl;
143
+ if (count >= start) {
144
+ for (let j = i - range; j <= i + range || end > count; j++) {
145
+ if (j < 0 || j >= lines.length) continue;
146
+ const lineLength = lines[j].length;
147
+ if (stripVTControlCharacters(lines[j]).length > 200) return "";
148
+ res.push(lineNo(j + 1) + truncateString(lines[j].replace(/\t/g, " "), columns - 5 - indent));
149
+ if (j === i) {
150
+ const pad = start - (count - lineLength) + (nl - 1);
151
+ const length = Math.max(1, end > count ? lineLength - pad : end - start);
152
+ res.push(lineNo() + " ".repeat(pad) + c.red("^".repeat(length)));
153
+ } else if (j > i) {
154
+ if (end > count) {
155
+ const length = Math.max(1, Math.min(end - count, lineLength));
156
+ res.push(lineNo() + c.red("^".repeat(length)));
157
+ }
158
+ count += lineLength + 1;
159
+ }
160
+ }
161
+ break;
162
+ }
163
+ }
164
+ if (indent) res = res.map((line) => " ".repeat(indent) + line);
165
+ return res.join("\n");
166
+ }
167
+ function positionToOffset(source, lineNumber, columnNumber) {
168
+ const lines = source.split(lineSplitRE);
169
+ const nl = /\r\n/.test(source) ? 2 : 1;
170
+ let start = 0;
171
+ if (lineNumber > lines.length) return source.length;
172
+ for (let i = 0; i < lineNumber - 1; i++) start += lines[i].length + nl;
173
+ return start + columnNumber;
174
+ }
175
+ function lineNo(no = "") {
176
+ return c.gray(`${String(no).padStart(3, " ")}| `);
177
+ }
178
+ function truncateString(text, maxLength) {
179
+ const plainText = stripVTControlCharacters(text);
180
+ if (plainText.length <= maxLength) return text;
181
+ return `${plainText.slice(0, maxLength - 1)}…`;
182
+ }
183
+
184
+ //#endregion
185
+ //#region src/wasm-executor/source-maps.ts
186
+ function parseSourceMap(sourceMap) {
187
+ const sourceMapObj = JSON.parse(sourceMap);
188
+ delete sourceMapObj.sourceRoot;
189
+ return sourceMapObj;
190
+ }
191
+ /**
192
+ * Extract structured call stack from V8 using Error.prepareStackTrace
193
+ *
194
+ * V8 provides a special API to access structured stack traces with line:column info.
195
+ * This gives us WAT text positions which can be mapped to AS source via source maps.
196
+ *
197
+ * @param capturedError - Error object to extract stack from
198
+ * @returns Array of V8 CallSite objects
199
+ */
200
+ function extractCallStack(capturedError) {
201
+ let stackTrace = [];
202
+ const originalPrepareStackTrace = Error.prepareStackTrace;
203
+ Error.prepareStackTrace = (_err, structuredStackTrace) => {
204
+ stackTrace = structuredStackTrace;
205
+ return "";
206
+ };
207
+ capturedError.stack;
208
+ Error.prepareStackTrace = originalPrepareStackTrace;
209
+ return stackTrace;
210
+ }
211
+ /**
212
+ * Create WebAssembly call site with source mapping
213
+ *
214
+ * Takes a V8 CallSite and maps it to AS source location if possible.
215
+ *
216
+ * @param callSite - V8 CallSite object from Error.prepareStackTrace
217
+ * @param sourceMapJson - Source map consumer initialized with WASM source map
218
+ * @returns Mapped call site or null if not a WASM call site
219
+ */
220
+ function createWebAssemblyCallSite(callSite, sourceMapConsumer, loggingPrefix, allowJS) {
221
+ const fileName = callSite.getFileName();
222
+ const watLine = callSite.getLineNumber();
223
+ const watColumn = callSite.getColumnNumber();
224
+ const functionName = callSite.getFunctionName() ?? "function[unknown]";
225
+ const debugString = `function: "${functionName}" | file: ${fileName}:${watLine}:${watColumn}`;
226
+ if (!fileName) {
227
+ debug(`${loggingPrefix} - Skipping source-mapping of invalid frame (no file): ${debugString}`);
228
+ return null;
229
+ }
230
+ if (!fileName.startsWith("wasm://")) if (allowJS) {
231
+ if (!watLine || !watColumn) {
232
+ debug(`${loggingPrefix} - Failed to pass through invalid JS stack location: ${debugString}`);
233
+ return null;
234
+ }
235
+ debug(`${loggingPrefix} - Passing through JS stack location: ${debugString}`);
236
+ return {
237
+ functionName,
238
+ location: {
239
+ filePath: fileName,
240
+ line: watLine,
241
+ column: watColumn
242
+ }
243
+ };
244
+ } else {
245
+ debug(`${loggingPrefix} - Skipping source-mapping of non-WASM stack location: ${debugString}`);
246
+ return null;
247
+ }
248
+ if (watLine && watColumn) {
249
+ const original = sourceMapConsumer.originalPositionFor({
250
+ line: watLine,
251
+ column: watColumn
252
+ });
253
+ if (!original.source || original.line === null || original.column === null) {
254
+ debug(`${loggingPrefix} - Failed to source-map stack location: ${debugString}`);
255
+ return null;
256
+ }
257
+ debug(`${loggingPrefix} - Source-mapped stack location: ${debugString} → ${original.source}:${original.line}:${original.column}`);
258
+ return {
259
+ functionName,
260
+ location: {
261
+ filePath: original.source,
262
+ line: original.line,
263
+ column: original.column
264
+ }
265
+ };
266
+ }
267
+ debug(`${loggingPrefix} - Cannot source-map stack-location: ${debugString}`);
268
+ return null;
269
+ }
270
+
271
+ //#endregion
272
+ //#region src/wasm-executor/wasm-names.ts
273
+ /**
274
+ * Extracts the short name from a WASM function table name identifier.
275
+ */
276
+ function getShortFunctionName(fullName) {
277
+ if (!fullName) return "";
278
+ let decoded;
279
+ try {
280
+ decoded = decodeURIComponent(fullName);
281
+ decoded = decoded.replace("\\2c", ",");
282
+ } catch {
283
+ decoded = fullName;
284
+ }
285
+ let angleBracketDepth = 0;
286
+ let parenDepth = 0;
287
+ let lastSlashOutsideBrackets = -1;
288
+ for (let i = 0; i < decoded.length; i++) {
289
+ const char = decoded[i];
290
+ if (char === "<") angleBracketDepth++;
291
+ else if (char === ">" && decoded[i - 1] !== "=") angleBracketDepth--;
292
+ else if (char === "(") parenDepth++;
293
+ else if (char === ")") parenDepth--;
294
+ else if (char === "/" && angleBracketDepth === 0 && parenDepth === 0) lastSlashOutsideBrackets = i;
295
+ }
296
+ const functionPart = lastSlashOutsideBrackets >= 0 ? decoded.substring(lastSlashOutsideBrackets + 1) : decoded;
297
+ const anonymousMatch = functionPart.match(/^.+~(anonymous\|\d+)$/);
298
+ if (anonymousMatch) return anonymousMatch[1];
299
+ return shortenTypePart(functionPart);
300
+ }
301
+ /**
302
+ * Finds the index of the closing '>' that matches the opening '<' at openIndex.
303
+ */
304
+ function findMatchingCloseBracket(str, openIndex) {
305
+ let angleBracketDepth = 1;
306
+ for (let i = openIndex + 1; i < str.length; i++) {
307
+ const char = str[i];
308
+ if (char === "<") angleBracketDepth++;
309
+ else if (char === ">" && str[i - 1] !== "=") {
310
+ angleBracketDepth--;
311
+ if (angleBracketDepth === 0) return i;
312
+ }
313
+ }
314
+ return str.length - 1;
315
+ }
316
+ /**
317
+ * Finds the index of the closing ')' that matches the opening '(' at openIndex.
318
+ */
319
+ function findMatchingCloseParen(str, openIndex) {
320
+ let parenDepth = 1;
321
+ let angleBracketDepth = 0;
322
+ for (let i = openIndex + 1; i < str.length; i++) {
323
+ const char = str[i];
324
+ if (char === "(") parenDepth++;
325
+ else if (char === ")") {
326
+ parenDepth--;
327
+ if (parenDepth === 0) return i;
328
+ } else if (char === "<") angleBracketDepth++;
329
+ else if (char === ">" && str[i - 1] !== "=") angleBracketDepth--;
330
+ }
331
+ return str.length - 1;
332
+ }
333
+ /**
334
+ * Splits a string by commas at the top level (not inside <> or ()).
335
+ */
336
+ function splitByTopLevelComma(str) {
337
+ const parts = [];
338
+ let current = "";
339
+ let angleBracketDepth = 0;
340
+ let parenDepth = 0;
341
+ for (let i = 0; i < str.length; i++) {
342
+ const char = str[i];
343
+ if (char === "<") angleBracketDepth++;
344
+ else if (char === ">" && str[i - 1] !== "=") angleBracketDepth--;
345
+ else if (char === "(") parenDepth++;
346
+ else if (char === ")") parenDepth--;
347
+ else if (char === "," && angleBracketDepth === 0 && parenDepth === 0) {
348
+ parts.push(current);
349
+ current = "";
350
+ continue;
351
+ }
352
+ current += char;
353
+ }
354
+ parts.push(current);
355
+ return parts;
356
+ }
357
+ /**
358
+ * Processes the content inside generic brackets or function args.
359
+ */
360
+ function shortenGenericContent(content) {
361
+ return splitByTopLevelComma(content).map((part) => shortenTypePart(part.trim())).join(",");
362
+ }
363
+ /**
364
+ * Shortens a function type like (args)=>returnType.
365
+ */
366
+ function shortenFunctionType(part) {
367
+ const closeParenIndex = findMatchingCloseParen(part, 0);
368
+ const argsContent = part.substring(1, closeParenIndex);
369
+ const afterParen = part.substring(closeParenIndex + 1);
370
+ const shortenedArgs = argsContent ? shortenGenericContent(argsContent) : "";
371
+ let returnPart = afterParen;
372
+ if (afterParen.startsWith("=>") && afterParen.length > 2) returnPart = "=>" + shortenTypePart(afterParen.substring(2));
373
+ return "(" + shortenedArgs + ")" + returnPart;
374
+ }
375
+ /**
376
+ * Shortens a type/function part, processing paths and generics recursively.
377
+ */
378
+ function shortenTypePart(part) {
379
+ if (part.startsWith("(")) return shortenFunctionType(part);
380
+ const openBracket = part.indexOf("<");
381
+ if (openBracket === -1) {
382
+ if (!part.includes("/")) return part;
383
+ return part.substring(part.lastIndexOf("/") + 1);
384
+ }
385
+ const namePart = part.substring(0, openBracket);
386
+ const closeBracket = findMatchingCloseBracket(part, openBracket);
387
+ const genericContent = part.substring(openBracket + 1, closeBracket);
388
+ const name = namePart.includes("/") ? namePart.substring(namePart.lastIndexOf("/") + 1) : namePart;
389
+ const shortenedContent = shortenGenericContent(genericContent);
390
+ return name + "<" + shortenedContent + ">";
391
+ }
392
+
393
+ //#endregion
394
+ //#region src/wasm-executor/wasm-errors.ts
395
+ /**
396
+ * Error Enhancement and Source Mapping
397
+ *
398
+ * This module handles mapping WASM errors to AssemblyScript source locations
399
+ * using source maps. It enhances error messages and stack traces with accurate
400
+ * file:line:column information for better developer experience.
401
+ */
402
+ const POOL_INTERNAL_PATHS_SET = new Set(POOL_INTERNAL_PATHS);
403
+ function passthroughCallSite(callSite) {
404
+ const fileName = callSite.getFileName();
405
+ const watLine = callSite.getLineNumber();
406
+ const watColumn = callSite.getColumnNumber();
407
+ return {
408
+ method: callSite.getFunctionName() || "wasm-function[unknown]",
409
+ file: fileName ?? "unknown-file",
410
+ line: watLine || -1,
411
+ column: watColumn || -1
412
+ };
413
+ }
414
+ async function sourceMapRawCallStack(rawCallStack, sourceMap, loggingPrefix, allowJS) {
415
+ const mappedStack = [];
416
+ if (!rawCallStack || rawCallStack.length === 0) return mappedStack;
417
+ if (sourceMap) {
418
+ const sourceMapConsumer = await new SourceMapConsumer(sourceMap);
419
+ rawCallStack.forEach((callSite) => {
420
+ const mappedCallSite = createWebAssemblyCallSite(callSite, sourceMapConsumer, loggingPrefix, allowJS);
421
+ if (mappedCallSite) mappedStack.push(mappedCallSite);
422
+ });
423
+ sourceMapConsumer.destroy();
424
+ }
425
+ return mappedStack;
426
+ }
427
+ function parseMappedStack(mappedStack) {
428
+ return mappedStack.filter((frame) => !POOL_INTERNAL_PATHS_SET.has(frame.location.filePath)).map((frame) => ({
429
+ method: getShortFunctionName(frame.functionName),
430
+ file: frame.location.filePath,
431
+ line: frame.location.line,
432
+ column: frame.location.filePath.startsWith("file") ? frame.location.column : frame.location.column + 1
433
+ }));
434
+ }
435
+ async function processWASMErrorStack(rawCallStack, sourceMap, loggingPrefix, allowJS) {
436
+ const sourceMappedStack = await sourceMapRawCallStack(rawCallStack, sourceMap, loggingPrefix, allowJS);
437
+ debug(`${loggingPrefix} - Mapped ${rawCallStack.length} call sites to ${sourceMappedStack.length} source locations`);
438
+ const parsedStack = parseMappedStack(sourceMappedStack);
439
+ if (parsedStack.length === 0) rawCallStack.forEach((callSite) => {
440
+ parsedStack.push(passthroughCallSite(callSite));
441
+ });
442
+ return parsedStack;
443
+ }
444
+ /**
445
+ * Enhance reportable test error on the provided test result with source mapped stack locations
446
+ * and a formatted diff based on the error type
447
+ */
448
+ async function enhanceTestError(testError, task, sourceMap, logPrefix, allowJS, projectRoot, applyStackToTestErrorCause, rawCallStack, diffOptions) {
449
+ let expectedVsActualDiffString;
450
+ const isAssertionFailure = testError.name === TEST_ERROR_NAMES.AssertionError;
451
+ const valuesProvided = testError.expected !== void 0 && testError.actual !== void 0;
452
+ if (isAssertionFailure && valuesProvided) expectedVsActualDiffString = diff(testError.expected, testError.actual, diffOptions) ?? "";
453
+ if (!rawCallStack || rawCallStack.length === 0) {
454
+ testError.diff = expectedVsActualDiffString;
455
+ testError.stack = `${task.name} - ${testError.message}`;
456
+ return;
457
+ }
458
+ const testErrorToUpdate = applyStackToTestErrorCause && testError.cause ? testError.cause : testError;
459
+ const parsedStack = await processWASMErrorStack(rawCallStack, sourceMap, logPrefix, allowJS);
460
+ let primaryStackFrameString;
461
+ let highlightedSourceCodeFrameString;
462
+ if (parsedStack.length > 0) {
463
+ parsedStack.forEach((frame) => {
464
+ if (frame.file.startsWith("file://")) {
465
+ frame.file = toForwardSlash(relative(projectRoot, fileURLToPath(frame.file)));
466
+ testErrorToUpdate.stack += toPlaintextStackFrameString(frame) + "\n";
467
+ }
468
+ });
469
+ const primaryStackFrame = parsedStack[0];
470
+ testErrorToUpdate.stacks = parsedStack.slice(1);
471
+ testErrorToUpdate.stack = parsedStack.map(toPlaintextStackFrameString).join("\n");
472
+ try {
473
+ highlightedSourceCodeFrameString = await getSourceCodeFrameString(sourceMap, primaryStackFrame);
474
+ } catch (err) {
475
+ debug(`${logPrefix} - Error reading source for primary stack frame file "${primaryStackFrame.file}":`, err);
476
+ }
477
+ primaryStackFrameString = toVitestLikeStackFrameString(primaryStackFrame);
478
+ debug(`${logPrefix} - Enhanced ${testError.name} error with parsed source stack`);
479
+ } else testErrorToUpdate.stack = `${task.name} - ${testError.message}`;
480
+ testErrorToUpdate.diff = [
481
+ expectedVsActualDiffString,
482
+ expectedVsActualDiffString ? "\n\n" : "",
483
+ primaryStackFrameString ?? "",
484
+ highlightedSourceCodeFrameString ? "\n" : "",
485
+ highlightedSourceCodeFrameString ?? ""
486
+ ].join("");
487
+ debug(`[${logPrefix} - Enhanced error with diffs`);
488
+ }
489
+
490
+ //#endregion
491
+ //#region src/util/pool-errors.ts
492
+ function abortWASMExecutionOnSuccess() {
493
+ return {
494
+ ["__as_pool_error__"]: true,
495
+ name: POOL_ERROR_NAMES.WASMExecutionAbortSuccess,
496
+ testError: {},
497
+ originalErrorMayContainJS: false,
498
+ originalErrorRawStack: [],
499
+ applyStackToTestErrorCause: false
500
+ };
501
+ }
502
+ function abortWASMExecution(testError, errorForStack) {
503
+ return {
504
+ ["__as_pool_error__"]: true,
505
+ name: POOL_ERROR_NAMES.WASMExecutionAbortError,
506
+ testError,
507
+ originalErrorMayContainJS: false,
508
+ originalErrorRawStack: errorForStack ? extractCallStack(errorForStack) : [],
509
+ applyStackToTestErrorCause: false
510
+ };
511
+ }
512
+ function wrapPoolError(name, originalError, originalErrorMayContainJS = false) {
513
+ let originalErrorName;
514
+ let originalErrorMessage;
515
+ let originalErrorRawStack;
516
+ if (originalError && originalError instanceof Error) {
517
+ originalErrorName = originalError.name;
518
+ originalErrorMessage = originalError.message;
519
+ originalErrorRawStack = extractCallStack(originalError);
520
+ } else if (originalError) {
521
+ originalErrorMessage = String(originalError);
522
+ originalErrorRawStack = [];
523
+ } else {
524
+ originalErrorMessage = "Unknown Error";
525
+ originalErrorRawStack = [];
526
+ }
527
+ const testError = {
528
+ name,
529
+ message: `${originalErrorName ? `${originalErrorName}: ` : ""}${originalErrorMessage}`
530
+ };
531
+ return {
532
+ ["__as_pool_error__"]: true,
533
+ name,
534
+ message: "Wrapped error",
535
+ originalErrorRawStack,
536
+ originalErrorMayContainJS,
537
+ testError,
538
+ applyStackToTestErrorCause: false
539
+ };
540
+ }
541
+ function createPoolError(name, message, originalError, originalErrorMayContainJS = true) {
542
+ if (originalError && originalError["__as_pool_error__"]) return originalError;
543
+ let originalErrorRawStack = [];
544
+ let applyStackToTestErrorCause = false;
545
+ const testError = {
546
+ name,
547
+ message
548
+ };
549
+ if (originalError && originalError instanceof Error) {
550
+ testError.cause = {
551
+ name: originalError.name,
552
+ message: `${originalError.message}`
553
+ };
554
+ originalErrorRawStack = extractCallStack(originalError);
555
+ applyStackToTestErrorCause = true;
556
+ } else if (originalError) testError.cause = {
557
+ name: POOL_ERROR_NAMES.PoolError,
558
+ message: String(originalError)
559
+ };
560
+ return {
561
+ ["__as_pool_error__"]: true,
562
+ name,
563
+ message,
564
+ originalErrorRawStack,
565
+ originalErrorMayContainJS,
566
+ testError,
567
+ applyStackToTestErrorCause
568
+ };
569
+ }
570
+ function createTestTimeoutError(test) {
571
+ const message = `Test timed out after ${test.timeout}ms`;
572
+ return {
573
+ name: POOL_ERROR_NAMES.WASMExecutionTimeoutError,
574
+ message,
575
+ stack: `${test.id}_${message}`,
576
+ diff: getYellowString(` Test Timeout Exceeded (${test.timeout}ms)`)
577
+ };
578
+ }
579
+ function createTestExpectedToFailError(test) {
580
+ const message = `Test is expected to fail, but all assertion(s) passed`;
581
+ return {
582
+ name: TEST_ERROR_NAMES.AssertionError,
583
+ message,
584
+ stack: `${test.id}_${message}`,
585
+ diff: getYellowString(` Expected to fail, but all assertion(s) passed`)
586
+ };
587
+ }
588
+ function isAbortErrorString(item) {
589
+ return item === POOL_ERROR_NAMES.PoolRunAbortedError || item === "AbortError";
590
+ }
591
+ function isAbortError(error) {
592
+ return isAbortErrorString(error) || isAbortErrorString(error?.name) || error?.message === "Terminating worker thread";
593
+ }
594
+ function getExpectedMessageOrAny(expectedMsgStr) {
595
+ return expectedMsgStr ? `"${expectedMsgStr}"` : "<any>";
596
+ }
597
+ async function buildEnhancedFileError(error, task, sourceMap, logPrefix, projectRoot, unexpectedContext, diffOptions) {
598
+ let testError;
599
+ let stack;
600
+ let applyStackToTestErrorCause;
601
+ let allowStackJS;
602
+ if (error && error["__as_pool_error__"]) {
603
+ const wrapper = error;
604
+ testError = wrapper.testError;
605
+ stack = wrapper.originalErrorRawStack;
606
+ applyStackToTestErrorCause = wrapper.applyStackToTestErrorCause;
607
+ allowStackJS = wrapper.originalErrorMayContainJS;
608
+ } else if (error instanceof Error) {
609
+ testError = {
610
+ name: POOL_ERROR_NAMES.PoolError,
611
+ message: `${error.name}: ${error.message}`
612
+ };
613
+ stack = extractCallStack(error);
614
+ allowStackJS = true;
615
+ applyStackToTestErrorCause = false;
616
+ } else {
617
+ testError = {
618
+ name: POOL_ERROR_NAMES.PoolError,
619
+ message: `Unexpected error (${unexpectedContext}): ${String(error)}`
620
+ };
621
+ stack = extractCallStack(/* @__PURE__ */ new Error());
622
+ allowStackJS = true;
623
+ applyStackToTestErrorCause = false;
624
+ }
625
+ await enhanceTestError(testError, task, sourceMap, logPrefix, allowStackJS, projectRoot, applyStackToTestErrorCause, stack, diffOptions);
626
+ return testError;
627
+ }
628
+
629
+ //#endregion
630
+ export { abortWASMExecution, abortWASMExecutionOnSuccess, buildEnhancedFileError, createPoolError, createTestExpectedToFailError, createTestTimeoutError, debug, debugOverride, enhanceTestError, extractCallStack, getExpectedMessageOrAny, getShortFunctionName, isAbortError, parseSourceMap, setGlobalDebugMode, toForwardSlash, wrapPoolError };
631
+ //# sourceMappingURL=pool-errors-GWfwrsD7.mjs.map