vitest-pool-assemblyscript 0.7.0 → 0.9.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 (93) hide show
  1. package/README.md +10 -13
  2. package/assembly/compare.ts +469 -76
  3. package/assembly/expect.ts +160 -67
  4. package/assembly/index.ts +0 -10
  5. package/assembly/utils.ts +168 -0
  6. package/dist/{addon-interface-_pNXcbib.mjs → addon-interface-CYFXMbK7.mjs} +4 -3
  7. package/dist/addon-interface-CYFXMbK7.mjs.map +1 -0
  8. package/dist/{ast-visitor-C5gQqWD2.mjs → ast-visitor-CWEOd3UH.mjs} +15 -2
  9. package/dist/ast-visitor-CWEOd3UH.mjs.map +1 -0
  10. package/dist/{compile-runner-DOMhsLQE.mjs → compile-runner-BGQhBkBo.mjs} +8 -7
  11. package/dist/compile-runner-BGQhBkBo.mjs.map +1 -0
  12. package/dist/compiler/transforms/deep-equals.d.mts +14 -0
  13. package/dist/compiler/transforms/deep-equals.d.mts.map +1 -0
  14. package/dist/compiler/transforms/deep-equals.mjs +245 -0
  15. package/dist/compiler/transforms/deep-equals.mjs.map +1 -0
  16. package/dist/compiler/transforms/strip-inline.mjs +2 -2
  17. package/dist/{compiler-CIXpfKq0.mjs → compiler-hUlDr5vL.mjs} +14 -6
  18. package/dist/compiler-hUlDr5vL.mjs.map +1 -0
  19. package/dist/config/index-v3.d.mts +33 -3
  20. package/dist/config/index-v3.d.mts.map +1 -1
  21. package/dist/config/index-v3.mjs.map +1 -1
  22. package/dist/config/index.d.mts +29 -4
  23. package/dist/config/index.d.mts.map +1 -0
  24. package/dist/config/index.mjs +6 -6
  25. package/dist/{constants-DuBLuMjt.mjs → constants-DbxJ3hzg.mjs} +10 -97
  26. package/dist/constants-DbxJ3hzg.mjs.map +1 -0
  27. package/dist/coverage-provider/index.mjs +30 -10
  28. package/dist/coverage-provider/index.mjs.map +1 -1
  29. package/dist/{debug-Cm1VFmaz.mjs → debug-DtRAL4rM.mjs} +38 -4
  30. package/dist/debug-DtRAL4rM.mjs.map +1 -0
  31. package/dist/{feature-check-ELxw_Mji.mjs → feature-check-Bje3ntpV.mjs} +2 -2
  32. package/dist/{feature-check-ELxw_Mji.mjs.map → feature-check-Bje3ntpV.mjs.map} +1 -1
  33. package/dist/index-internal.d.mts +1 -1
  34. package/dist/index-internal.d.mts.map +1 -1
  35. package/dist/index-internal.mjs +4 -4
  36. package/dist/index-v3.d.mts.map +1 -1
  37. package/dist/index-v3.mjs +8 -7
  38. package/dist/index-v3.mjs.map +1 -1
  39. package/dist/index.d.mts +1 -2
  40. package/dist/index.mjs +6 -6
  41. package/dist/{load-user-imports-B3Iy_K8k.mjs → load-user-imports-Bx5ZlhSm.mjs} +9 -9
  42. package/dist/load-user-imports-Bx5ZlhSm.mjs.map +1 -0
  43. package/dist/{pool-runner-init-BDQtAGwQ.mjs → pool-runner-init-BqkwQ2tk.mjs} +7 -7
  44. package/dist/pool-runner-init-BqkwQ2tk.mjs.map +1 -0
  45. package/dist/{pool-runner-init-CvnB0-iN.d.mts → pool-runner-init-CNpRdA5u.d.mts} +2 -2
  46. package/dist/pool-runner-init-CNpRdA5u.d.mts.map +1 -0
  47. package/dist/pool-thread/compile-worker-thread.d.mts +1 -1
  48. package/dist/pool-thread/compile-worker-thread.d.mts.map +1 -1
  49. package/dist/pool-thread/compile-worker-thread.mjs +10 -13
  50. package/dist/pool-thread/compile-worker-thread.mjs.map +1 -1
  51. package/dist/pool-thread/test-worker-thread.d.mts +1 -1
  52. package/dist/pool-thread/test-worker-thread.d.mts.map +1 -1
  53. package/dist/pool-thread/test-worker-thread.mjs +8 -11
  54. package/dist/pool-thread/test-worker-thread.mjs.map +1 -1
  55. package/dist/pool-thread/v3-tinypool-thread.d.mts +1 -1
  56. package/dist/pool-thread/v3-tinypool-thread.d.mts.map +1 -1
  57. package/dist/pool-thread/v3-tinypool-thread.mjs +12 -18
  58. package/dist/pool-thread/v3-tinypool-thread.mjs.map +1 -1
  59. package/dist/{resolve-config-DhZ4lOSK.mjs → resolve-config-s9gSJSMc.mjs} +14 -5
  60. package/dist/resolve-config-s9gSJSMc.mjs.map +1 -0
  61. package/dist/{test-runner-C4I9VknR.mjs → test-runner-BGqc9uCK.mjs} +4 -4
  62. package/dist/{test-runner-C4I9VknR.mjs.map → test-runner-BGqc9uCK.mjs.map} +1 -1
  63. package/dist/{types-D0nprJo1.d.mts → types-DHVk5iAx.d.mts} +17 -11
  64. package/dist/types-DHVk5iAx.d.mts.map +1 -0
  65. package/dist/vitest-file-tasks-D8sOClGX.mjs +149 -0
  66. package/dist/vitest-file-tasks-D8sOClGX.mjs.map +1 -0
  67. package/dist/{vitest-tasks--ow4pacR.mjs → vitest-tasks-BZ24sghI.mjs} +6 -4
  68. package/dist/vitest-tasks-BZ24sghI.mjs.map +1 -0
  69. package/package.json +11 -14
  70. package/prebuilds/darwin-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  71. package/prebuilds/darwin-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  72. package/prebuilds/linux-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  73. package/prebuilds/linux-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  74. package/prebuilds/linux-x64/vitest-pool-assemblyscript.musl.node +0 -0
  75. package/prebuilds/win32-arm64/vitest-pool-assemblyscript.glibc.node +0 -0
  76. package/prebuilds/win32-x64/vitest-pool-assemblyscript.glibc.node +0 -0
  77. package/src/instrumentation/native/addon.cpp +29 -3
  78. package/dist/addon-interface-_pNXcbib.mjs.map +0 -1
  79. package/dist/ast-visitor-C5gQqWD2.mjs.map +0 -1
  80. package/dist/compile-runner-DOMhsLQE.mjs.map +0 -1
  81. package/dist/compiler-CIXpfKq0.mjs.map +0 -1
  82. package/dist/constants-DuBLuMjt.mjs.map +0 -1
  83. package/dist/custom-provider-options-YTk1m7At.d.mts +0 -26
  84. package/dist/custom-provider-options-YTk1m7At.d.mts.map +0 -1
  85. package/dist/debug-Cm1VFmaz.mjs.map +0 -1
  86. package/dist/load-user-imports-B3Iy_K8k.mjs.map +0 -1
  87. package/dist/pool-runner-init-BDQtAGwQ.mjs.map +0 -1
  88. package/dist/pool-runner-init-CvnB0-iN.d.mts.map +0 -1
  89. package/dist/resolve-config-DhZ4lOSK.mjs.map +0 -1
  90. package/dist/types-D0nprJo1.d.mts.map +0 -1
  91. package/dist/vitest-file-tasks-Bn9CrWt_.mjs +0 -61
  92. package/dist/vitest-file-tasks-Bn9CrWt_.mjs.map +0 -1
  93. package/dist/vitest-tasks--ow4pacR.mjs.map +0 -1
@@ -2,12 +2,16 @@ import {
2
2
  closeTo,
3
3
  compareInequality,
4
4
  equals,
5
+ equalsPathClear,
6
+ equalsPathString,
7
+ equalsRefPairsClear,
8
+ equalsRtmNamesClear,
9
+ equalsRtmNamesSuffix,
5
10
  identical,
6
11
  InequalityOperation,
7
- isNull,
8
- nan,
9
- truthyOrFalsey
12
+ truthyOrFalsey,
10
13
  } from './compare';
14
+ import { isNull, nan, stringifyValue } from './utils';
11
15
 
12
16
  // @external functions are imported to the WASM execution environment from pool code
13
17
 
@@ -34,43 +38,6 @@ declare function __expect_throw(fnPtr: usize, errorMsg?: string): void;
34
38
  declare function __end_expect_throw(): void;
35
39
 
36
40
 
37
- function itemMessageString<T>(item: T): string {
38
- if (isNull(item)) return "null";
39
- if (nan(item)) return "NaN";
40
-
41
- if (isReference<T>()) {
42
- if (isString<T>()) return `"${item}"`;
43
- else if (item instanceof ArrayBuffer) return `ArrayBuffer[${item.byteLength}]`;
44
- else if (isArrayLike<T>(item)) return arrayMessageString(item);
45
- else if (item instanceof Set || item instanceof Map) return item.toString();
46
- else return nameof<T>(item);
47
- } else if (isBoolean<T>()){
48
- return bool(item).toString();
49
- } else if (isInteger<T>(item) || isFloat<T>(item)) {
50
- return item.toString();
51
- } else {
52
- return nameof<T>(item);
53
- }
54
- }
55
-
56
- function arrayMessageString<T extends ArrayLike<unknown>>(array: T): string {
57
- if (isNullable<T>(array) && array == null) {
58
- return "null";
59
- }
60
-
61
- let str = "[";
62
- for (let i = 0; i < array.length; i++) {
63
- str += itemMessageString(array[i]);
64
-
65
- if (i < array.length - 1) {
66
- str += ","
67
- }
68
- }
69
- str += "]";
70
-
71
- return str;
72
- }
73
-
74
41
  /**
75
42
  * Expect matcher
76
43
  */
@@ -96,7 +63,8 @@ abstract class BaseExpectMatcher<T> {
96
63
  /**
97
64
  * Checks that a value is what you expect using identity comparison. Primitives and strings
98
65
  * are compared by value, and references are checked for reference equality only (including
99
- * objects, arrays, etc).
66
+ * objects, arrays, etc). SIMD vectors use WASM's native `==` comparison, which compares at
67
+ * the bit level, ignoring lane type.
100
68
  *
101
69
  * Cross-type numeric comparisons are allowed where AssemblyScript's own `==` operator
102
70
  * permits them (e.g. `f64` vs `i32`). `toBeCloseTo()` is safer for any comparison
@@ -105,6 +73,8 @@ abstract class BaseExpectMatcher<T> {
105
73
  *
106
74
  * @throws When comparing float/integer types where the float's mantissa cannot losslessly
107
75
  * represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
76
+ * @throws When comparing fundamentally incompatible types: reference vs value type
77
+ * (e.g. `string` vs `i32`, unless one is null/zero), or `v128` vs non-vector type.
108
78
  *
109
79
  * @example
110
80
  * expect(1 + 1).toBe(2);
@@ -116,6 +86,9 @@ abstract class BaseExpectMatcher<T> {
116
86
  * // supported float/integer comparisons (small integer types)
117
87
  * expect(f64(42.0)).toBe(i32(42));
118
88
  *
89
+ * // SIMD vectors: different lane types with the same underlying bits are identical
90
+ * expect(i64x2(3, 7)).toBe(i32x4(3, 0, 7, 0));
91
+ *
119
92
  * // unsupported float/integer comparisons throw an error
120
93
  * // expect(f32(42.0)).toBe(i32(42)); // Error: float precision insufficient
121
94
  * // expect(f64(42.0)).toBe(i64(42)); // Error: float precision insufficient
@@ -133,10 +106,15 @@ abstract class BaseExpectMatcher<T> {
133
106
  *
134
107
  * Strings are compared by value equality as with `toBe`. Non-numeric, non-string types return false.
135
108
  *
136
- * @param precision - Specify the number of decimal places that must match for values to be
109
+ * SIMD `v128` vectors are not supported, as approximate comparison requires a lane type
110
+ * interpretation to extract numeric values. Extract lane values as needed and compare them individually.
111
+ *
112
+ * @param precision - Specify the number of decimal places that must match for values to be
137
113
  * considered close. Defaults to 2 digits, meaning effectively that values must be within 0.005 of
138
114
  * each other.
139
115
  *
116
+ * @throws When either value is a `v128` vector.
117
+ *
140
118
  * @example
141
119
  * expect(0.1 + 0.2).toBeCloseTo(0.3);
142
120
  * expect(1.005).toBeCloseTo(1.0, 1);
@@ -153,11 +131,14 @@ abstract class BaseExpectMatcher<T> {
153
131
  * (more permissive than AS's own `>` operator). Booleans are treated as numeric
154
132
  * (true=1, false=0).
155
133
  *
134
+ * SIMD `v128` vectors are not supported, as numeric lane-wise comparison requires a
135
+ * specific lane type interpretation. Extract lane values and compare them individually instead.
136
+ *
156
137
  * @throws When comparing float/integer types where the float's mantissa cannot losslessly
157
138
  * represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
158
139
  * @throws When comparing nullable strings where either value is null. Use `toBeNull()`
159
140
  * to check for null values.
160
- * @throws When comparing non-string reference types (objects, arrays, etc).
141
+ * @throws When comparing non-string reference types (objects, arrays, etc) or `v128` vectors.
161
142
  *
162
143
  * @example
163
144
  * expect(10).toBeGreaterThan(5);
@@ -179,11 +160,14 @@ abstract class BaseExpectMatcher<T> {
179
160
  * (more permissive than AS's own `>=` operator). Booleans are treated as numeric
180
161
  * (true=1, false=0).
181
162
  *
163
+ * SIMD `v128` vectors are not supported, as numeric lane-wise comparison requires a
164
+ * specific lane type interpretation. Extract lane values and compare them individually instead.
165
+ *
182
166
  * @throws When comparing float/integer types where the float's mantissa cannot losslessly
183
167
  * represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
184
168
  * @throws When comparing nullable strings where either value is null. Use `toBeNull()`
185
169
  * to check for null values.
186
- * @throws When comparing non-string reference types (objects, arrays, etc).
170
+ * @throws When comparing non-string reference types (objects, arrays, etc) or `v128` vectors.
187
171
  *
188
172
  * @example
189
173
  * expect(10).toBeGreaterThanOrEqual(10);
@@ -204,11 +188,14 @@ abstract class BaseExpectMatcher<T> {
204
188
  * (more permissive than AS's own `<` operator). Booleans are treated as numeric
205
189
  * (true=1, false=0).
206
190
  *
191
+ * SIMD `v128` vectors are not supported, as numeric lane-wise comparison requires a
192
+ * specific lane type interpretation. Extract lane values and compare them individually instead.
193
+ *
207
194
  * @throws When comparing float/integer types where the float's mantissa cannot losslessly
208
195
  * represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
209
196
  * @throws When comparing nullable strings where either value is null. Use `toBeNull()`
210
197
  * to check for null values.
211
- * @throws When comparing non-string reference types (objects, arrays, etc).
198
+ * @throws When comparing non-string reference types (objects, arrays, etc) or `v128` vectors.
212
199
  *
213
200
  * @example
214
201
  * expect(5).toBeLessThan(10);
@@ -230,11 +217,14 @@ abstract class BaseExpectMatcher<T> {
230
217
  * (more permissive than AS's own `<=` operator). Booleans are treated as numeric
231
218
  * (true=1, false=0).
232
219
  *
220
+ * SIMD `v128` vectors are not supported, as numeric lane-wise comparison requires a
221
+ * specific lane type interpretation. Extract lane values and compare them individually instead.
222
+ *
233
223
  * @throws When comparing float/integer types where the float's mantissa cannot losslessly
234
224
  * represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
235
225
  * @throws When comparing nullable strings where either value is null. Use `toBeNull()`
236
226
  * to check for null values.
237
- * @throws When comparing non-string reference types (objects, arrays, etc).
227
+ * @throws When comparing non-string reference types (objects, arrays, etc) or `v128` vectors.
238
228
  *
239
229
  * @example
240
230
  * expect(5).toBeLessThanOrEqual(5);
@@ -248,42 +238,119 @@ abstract class BaseExpectMatcher<T> {
248
238
  }
249
239
 
250
240
  /**
251
- * Checks that two values have the same value (deep equality). Currently supports
252
- * checking equality of Arrays, Sets, Maps, and nulls. Values inside arrays are
253
- * compared using `toEqual()` also, while Maps and Sets use their respective rules
254
- * for membership. Primitives, strings, and other object references are compared with
255
- * `toBe()` rules.
256
- *
241
+ * Checks that two values have the same value (deep equality). Primitives and strings
242
+ * are compared by value, and object references are tested for deep equality.
243
+ *
257
244
  * Like `toBe`, cross-type numeric comparisons follow AssemblyScript's own `==` operator
258
245
  * restrictions. `toBeCloseTo()` is safer for any comparison involving a float and
259
246
  * accurately handles precision-loss edge cases.
260
- *
261
- * ⚠️ IMPORTANT: Does not yet support user-defined object deep equality checking.
247
+ *
248
+ * Built-in object references are compared with the following deep equality rules:
249
+ * - `Array`, `StaticArray`, `TypedArray`: element-by-element comparison using `toEqual()` recursively
250
+ * - `Set`: deep element equality (same elements, order-independent) using `toEqual()`
251
+ * - `Map`: key-by-key comparison using `toEqual()` on values. Key types must match
252
+ * exactly; value types support cross-type comparison
253
+ * - `ArrayBuffer`: byte-level content comparison
254
+ *
255
+ * Arrays, Sets, and Maps support cross-type comparison where element/value types are
256
+ * compatible (e.g. `Array<i32>` vs `Array<f64>`, `Map<string, i32>` vs `Map<string, f64>`).
257
+ * For Maps, key types must match exactly - only value types can differ.
258
+ *
259
+ * User object references of the same runtime type are compared using a deep field-by-field
260
+ * comparison of all stored instance fields using `toEqual()` recursively.
261
+ * - Includes public, protected, and private fields
262
+ * - Getters are **excluded**
263
+ * - User-defined `@operator("==")` or `.equals()` methods are used if present, instead
264
+ * of field-by-field comparison
265
+ * - Supports inheritance, generics, and nullable fields
266
+ * - Objects with different runtime types are not equal even when they share
267
+ * the same fields & values, making behavior the same as `toStrictEqual` in the
268
+ * AssemblyScript pool. This differs from vitest's JavaScript `toEqual()`,
269
+ * which compares structurally regardless of constructor / runtime type
270
+ * - Note: If a user class extends a library class (from `node_modules` or AS stdlib),
271
+ * only the user class's own declared fields are compared. Inherited library fields
272
+ * are not included, as deep equality injection is scoped to user source files only
273
+ *
274
+ * SIMD vectors use WASM's native `==` comparison, which compares at the bit level,
275
+ * ignoring lane type.
262
276
  *
263
277
  * @throws When comparing float/integer types where the float's mantissa cannot losslessly
264
278
  * represent the integer type's range (e.g. `f32` vs `i32`, `f64` vs `i64`).
279
+ * @throws When comparing fundamentally incompatible types: reference vs value type
280
+ * (e.g. `string` vs `i32`, unless one is null/zero), or `v128` vs non-vector type.
281
+ * @throws When comparing containers with incompatible element types (e.g. `Array<string>`
282
+ * vs `Array<i32>`), or precision-loss numeric combinations (e.g. `Array<f32>` vs `Array<i32>`).
265
283
  *
266
284
  * @example
267
285
  * expect([1, 2, 3]).toEqual([1, 2, 3]);
268
286
  * expect(["one", "two", "three"]).toEqual(["one", "two", "three"]);
269
287
  *
270
- * // objects use reference equality (deep equality not yet supported)
271
- * const a: MyObject = new MyObject();
272
- * const b: MyObject = new MyObject();
273
- * expect([a, b]).toEqual([a, b]);
288
+ * // ArrayBuffer byte-level comparison
289
+ * const a = new ArrayBuffer(4);
290
+ * const b = new ArrayBuffer(4);
291
+ * store<u8>(changetype<usize>(a), 0x42);
292
+ * store<u8>(changetype<usize>(b), 66); // 66 decimal == 0x42 hex
293
+ * expect(a).toEqual(b);
294
+ *
295
+ * // SIMD vectors: different lane types with the same underlying bits are equal
296
+ * expect(i64x2(3, 7)).toEqual(i32x4(3, 0, 7, 0));
297
+ *
298
+ * // user-defined objects: deep equality
299
+ * const p1 = new Point(1, 2);
300
+ * const p2 = new Point(1, 2);
301
+ * expect(p1).toEqual(p2);
274
302
  */
275
303
  toEqual<U>(val: U): void {
276
- this.assertComparison(equals(this.actual, val), this.actual, val, "to deeply equal", true);
304
+ equalsRefPairsClear();
305
+ equalsPathClear();
306
+ equalsRtmNamesClear();
307
+ const result = equals(this.actual, val);
308
+ const path = equalsPathString();
309
+ const isRtm = result == __vitest_assemblyscript_EqualityResult.RuntimeTypeMismatch;
310
+
311
+ let suffix = "";
312
+ if (isRtm) {
313
+ const rtmNames = equalsRtmNamesSuffix();
314
+ suffix = path != "" ? " (runtime type mismatch at " + path + rtmNames + ")" : " (runtime type mismatch" + rtmNames + ")";
315
+ } else if (path != "") {
316
+ suffix = " (differs at " + path + ")";
317
+ }
318
+
319
+ this.assertComparison(result == __vitest_assemblyscript_EqualityResult.Equal, this.actual, val, "to deeply equal", true, true, suffix, isRtm);
277
320
  }
278
321
 
279
322
  /**
280
- * Alias for `toEqual`. Currently no differences in AssemblyScript.
323
+ * Alias for `toEqual`, no functional difference.
324
+ *
325
+ * In JavaScript, `toEqual` compares structurally regardless of type,
326
+ * while `toStrictEqual` requires the same runtime type.
327
+ *
328
+ * In AssemblyScript, `toEqual` already requires matching runtime types,
329
+ * which is consistent with how most testing frameworks behave for statically-typed
330
+ * languages without runtime reflection.
281
331
  *
282
332
  * @example
283
- * expect([1, 2]).toStrictEqual([1, 2]);
333
+ * const p1 = new Point(1, 2);
334
+ * const p2 = new Point(1, 2);
335
+ * expect(p1).toEqual(p2);
284
336
  */
285
337
  toStrictEqual<U>(val: U): void {
286
- this.assertComparison(equals(this.actual, val), this.actual, val, "to strictly equal", true);
338
+ equalsRefPairsClear();
339
+ equalsPathClear();
340
+ equalsRtmNamesClear();
341
+ const result = equals(this.actual, val);
342
+ const path = equalsPathString();
343
+ const isRtm = result == __vitest_assemblyscript_EqualityResult.RuntimeTypeMismatch;
344
+
345
+ let suffix = "";
346
+ if (isRtm) {
347
+ const rtmNames = equalsRtmNamesSuffix();
348
+ suffix = path != "" ? " (runtime type mismatch at " + path + rtmNames + ")" : " (runtime type mismatch" + rtmNames + ")";
349
+ } else if (path != "") {
350
+ suffix = " (differs at " + path + ")";
351
+ }
352
+
353
+ this.assertComparison(result == __vitest_assemblyscript_EqualityResult.Equal, this.actual, val, "to strictly equal", true, true, suffix, isRtm);
287
354
  }
288
355
 
289
356
  /**
@@ -293,10 +360,13 @@ abstract class BaseExpectMatcher<T> {
293
360
  * an object reference, not a primitive. An empty string is still an allocated object
294
361
  * with a non-zero address, so it evaluates as truthy.
295
362
  *
363
+ * A SIMD `v128` vector with at least one non-zero bit is truthy; an all-zero vector is falsy.
364
+ *
296
365
  * @example
297
366
  * expect(1).toBeTruthy();
298
367
  * expect("hello").toBeTruthy();
299
368
  * expect("").toBeTruthy(); // truthy in AS (unlike JS)
369
+ * expect(i32x4.splat(1)).toBeTruthy();
300
370
  */
301
371
  toBeTruthy(): void {
302
372
  this.assertComparison(truthyOrFalsey(this.actual, true), this.actual, true, "to be truthy", false);
@@ -309,11 +379,14 @@ abstract class BaseExpectMatcher<T> {
309
379
  * an object reference, not a primitive. An empty string is still an allocated object
310
380
  * with a non-zero address, so it evaluates as truthy.
311
381
  *
382
+ * An all-zero SIMD `v128` vector is falsy; a vector with at least one non-zero bit is truthy.
383
+ *
312
384
  * @example
313
385
  * expect(0).toBeFalsy();
314
386
  * expect(NaN).toBeFalsy();
315
387
  * expect(null).toBeFalsy();
316
388
  * expect("").not.toBeFalsy(); // not falsy in AS (unlike JS)
389
+ * expect(i32x4.splat(0)).toBeFalsy();
317
390
  */
318
391
  toBeFalsy(): void {
319
392
  this.assertComparison(truthyOrFalsey(this.actual, false), this.actual, false, "to be falsey", false);
@@ -340,7 +413,7 @@ abstract class BaseExpectMatcher<T> {
340
413
 
341
414
  /**
342
415
  * Checks that the type of the value is nullable (can hold `null`). This is a type-level
343
- * check, not a value check a bare `null` (which is `usize(0)`) is not itself a nullable type.
416
+ * check, not a value check - a bare `null` (which is `usize(0)`) is not itself a nullable type.
344
417
  * Use `toBeNull()` to check if a value is null.
345
418
  *
346
419
  * @example
@@ -406,16 +479,36 @@ abstract class BaseExpectMatcher<T> {
406
479
  }
407
480
  }
408
481
 
409
- protected assertComparison<U, V>(rawCondition: bool, actual: U, expected: V, methodStr: string, printExpected: bool, provideDiff: bool = true): void {
482
+ protected assertComparison<U, V>(rawCondition: bool, actual: U, expected: V, methodStr: string, printExpected: bool, provideDiff: bool = true, suffix: string = "", isRtm: bool = false): void {
410
483
  const condition = this.isInverted ? !rawCondition : rawCondition;
411
484
 
412
485
  if (condition) {
413
486
  __assertion_pass();
414
487
  } else {
415
488
  const notStr = this.isInverted ? "not " : "";
416
- const actualStr = itemMessageString(actual);
417
- const expectedStr = itemMessageString(expected);
418
- const msg = `expected ${actualStr} ${notStr}${methodStr}${printExpected ? ` ${expectedStr}` : ""}`;
489
+ // For runtime type mismatches, show the top-level type name only — the mismatched
490
+ // types in the suffix are the useful information, not field contents of differently-typed
491
+ // objects. Uses __vitest_assemblyscript_typename (virtual dispatch gives runtime name)
492
+ // with nameof fallback for types without injection (containers, primitives).
493
+ // For value mismatches, full stringification shows what values differ.
494
+ let actualStr: string;
495
+ let expectedStr: string;
496
+ if (isRtm) {
497
+ // @ts-ignore
498
+ actualStr = isDefined(actual.__vitest_assemblyscript_typename)
499
+ // @ts-ignore
500
+ ? (<NonNullable<U>>actual).__vitest_assemblyscript_typename()
501
+ : nameof<U>();
502
+ // @ts-ignore
503
+ expectedStr = isDefined(expected.__vitest_assemblyscript_typename)
504
+ // @ts-ignore
505
+ ? (<NonNullable<V>>expected).__vitest_assemblyscript_typename()
506
+ : nameof<V>();
507
+ } else {
508
+ actualStr = stringifyValue(actual);
509
+ expectedStr = stringifyValue(expected);
510
+ }
511
+ const msg = `expected ${actualStr} ${notStr}${methodStr}${printExpected ? ` ${expectedStr}` : ""}${suffix}`;
419
512
 
420
513
  __assertion_fail<string>(msg, nameof<U>() + " " + nameof<V>(), provideDiff, actualStr, expectedStr);
421
514
 
package/assembly/index.ts CHANGED
@@ -1,13 +1,3 @@
1
- /**
2
- * Test framework with per-test crash isolation support
3
- *
4
- * Execution flow:
5
- * 1. Instantiation: Pool creates WASM instance with import callbacks
6
- * 2. Registration: _start() runs, top-level test() calls invoke __register_test callback
7
- * 3. Discovery: Pool receives test names + function indices via callbacks
8
- * 4. Execution: Pool calls table.get(fnIndex)() directly via exported function table
9
- */
10
-
11
1
  export * from './describe';
12
2
  export * from './expect';
13
3
  export * from './options';
@@ -0,0 +1,168 @@
1
+ export function isNull<T>(value: T): bool {
2
+ if (isReference<T>()) {
3
+ if (isNullable<T>()) {
4
+ return value == null;
5
+ } else {
6
+ return false;
7
+ }
8
+ } else {
9
+ if (isBoolean<T>()) {
10
+ return false;
11
+ } else if (isVector<T>()) {
12
+ return false;
13
+ } else {
14
+ return nameof<T>(value) == 'usize' && value == 0;
15
+ }
16
+ }
17
+ }
18
+
19
+ export function nan<T>(value: T): bool {
20
+ if (isFloat<T>()) {
21
+ // @ts-ignore
22
+ return isNaN<T>(value);
23
+ } else {
24
+ return false;
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Cycle detection for stringification. Tracks which object pointers are currently
30
+ * being stringified to prevent infinite recursion on self-referential objects.
31
+ *
32
+ * Uses add-on-entry/remove-on-exit discipline (unlike equalsRefPairs which is add-only).
33
+ * This is necessary because stringifyValue is called twice per assertion (once for actual,
34
+ * once for expected) — the same pointer appearing in both calls is not a cycle. Add/remove
35
+ * ensures the set is naturally empty between calls with no external clearing needed.
36
+ */
37
+ const stringifyVisited = new Set<usize>();
38
+
39
+ /**
40
+ * Produces a human-readable string representation of a value for assertion messages.
41
+ * Handles primitives, strings, arrays, Sets, Maps, ArrayBuffers, and user-defined objects.
42
+ * Used by matchers to format actual/expected values in error output and diffs.
43
+ */
44
+ export function stringifyValue<T>(item: T): string {
45
+ if (isNull(item)) return "null";
46
+ if (nan(item)) return "NaN";
47
+
48
+ if (isReference<T>()) {
49
+ if (isString<T>()) return `"${item}"`;
50
+
51
+ // Cycle detection for all non-string reference types before recursive stringification
52
+ const ptr = changetype<usize>(item);
53
+ if (stringifyVisited.has(ptr)) return "[Circular]";
54
+ stringifyVisited.add(ptr);
55
+
56
+ let result: string;
57
+ if (item instanceof ArrayBuffer) {
58
+ result = `ArrayBuffer[${item.byteLength}]`;
59
+ } else if (isArrayLike<T>(item)) {
60
+ result = arrayMessageString(item);
61
+ } else if (item instanceof Set) {
62
+ result = setMessageString(item);
63
+ } else if (item instanceof Map) {
64
+ result = mapMessageString(item);
65
+ // @ts-ignore: __vitest_assemblyscript_typename is injected by the compiler transform
66
+ } else if (isDefined(item.__vitest_assemblyscript_typename)) {
67
+ // Cast to NonNullable<T> because AS doesn't narrow nullability from the earlier
68
+ // null check — it requires explicit type narrowing to call methods on nullable types.
69
+ // Safe because null case returns "null" at the top of this function.
70
+ const nonNullItem = <NonNullable<T>>item;
71
+ // @ts-ignore
72
+ const typeName: string = nonNullItem.__vitest_assemblyscript_typename();
73
+ // @ts-ignore
74
+ if (isDefined(nonNullItem.__vitest_assemblyscript_stringify)) {
75
+ // @ts-ignore
76
+ const fields: string = nonNullItem.__vitest_assemblyscript_stringify();
77
+ result = fields != "" ? typeName + " { " + fields + " }" : typeName;
78
+ } else {
79
+ result = typeName;
80
+ }
81
+ } else {
82
+ result = nameof<T>(item);
83
+ }
84
+
85
+ stringifyVisited.delete(ptr);
86
+ return result;
87
+ } else if (isBoolean<T>()){
88
+ return bool(item).toString();
89
+ } else if (isInteger<T>(item) || isFloat<T>(item)) {
90
+ return item.toString();
91
+ } else {
92
+ return nameof<T>(item);
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Global bridge for the compiler transform's injected stringify methods.
98
+ *
99
+ * Transform-injected __vitest_assemblyscript_stringify methods call this to format each
100
+ * field value. Declared global to make it available in all source files without import,
101
+ * solving the afterParse import resolution limitation.
102
+ *
103
+ * Loaded into the compilation transitively: user test imports
104
+ * vitest-pool-assemblyscript/assembly → index.ts → expect.ts → compare.ts → utils.ts.
105
+ */
106
+ // @ts-ignore: AS-specific global decorator
107
+ @global
108
+ function __vitest_assemblyscript_stringify_value<T>(item: T): string {
109
+ return stringifyValue<T>(item);
110
+ }
111
+
112
+ function arrayMessageString<T extends ArrayLike<unknown>>(array: T): string {
113
+ if (isNullable<T>(array) && array == null) {
114
+ return "null";
115
+ }
116
+
117
+ let str = "[";
118
+ for (let i = 0; i < array.length; i++) {
119
+ str += stringifyValue(array[i]);
120
+
121
+ if (i < array.length - 1) {
122
+ str += ","
123
+ }
124
+ }
125
+ str += "]";
126
+
127
+ return str;
128
+ }
129
+
130
+ function setMessageString<T>(set: T): string {
131
+ if (isNullable<T>(set) && set == null) {
132
+ return "null";
133
+ }
134
+
135
+ if (set instanceof Set) {
136
+ const values = set.values();
137
+ let str = "Set {";
138
+ for (let i = 0; i < values.length; i++) {
139
+ if (i > 0) str += ",";
140
+ str += " " + stringifyValue(values[i]);
141
+ }
142
+ if (values.length > 0) str += " ";
143
+ str += "}";
144
+ return str;
145
+ }
146
+
147
+ return nameof<T>(set);
148
+ }
149
+
150
+ function mapMessageString<T>(map: T): string {
151
+ if (isNullable<T>(map) && map == null) {
152
+ return "null";
153
+ }
154
+
155
+ if (map instanceof Map) {
156
+ const keys = map.keys();
157
+ let str = "Map {";
158
+ for (let i = 0; i < keys.length; i++) {
159
+ if (i > 0) str += ",";
160
+ str += " " + stringifyValue(keys[i]) + " => " + stringifyValue(map.get(keys[i]));
161
+ }
162
+ if (keys.length > 0) str += " ";
163
+ str += "}";
164
+ return str;
165
+ }
166
+
167
+ return nameof<T>(map);
168
+ }
@@ -1,5 +1,5 @@
1
- import { INTERNAL_PATH_LIB_PREFIX, POOL_ERROR_NAMES } from "./constants-DuBLuMjt.mjs";
2
- import { createPoolError, debug } from "./debug-Cm1VFmaz.mjs";
1
+ import { INTERNAL_PATH_LIB_PREFIX, POOL_ERROR_NAMES } from "./constants-DbxJ3hzg.mjs";
2
+ import { createPoolError, debug } from "./debug-DtRAL4rM.mjs";
3
3
  import { toForwardSlash } from "./path-utils-t9OzjXYF.mjs";
4
4
  import { getShortFunctionName } from "./wasm-names-BFtzQCH4.mjs";
5
5
  import { createRequire } from "node:module";
@@ -184,6 +184,7 @@ const instrumentForCoverage = (wasmBuffer, sourceMapBuffer, instrumentationOptio
184
184
  excludedFiles: instrumentationOptions.relativeExcludedFiles,
185
185
  excludedLibraryFilePrefix: instrumentationOptions.excludedLibraryFilePrefix,
186
186
  excludedLibraryFileOverridePrefix: instrumentationOptions.excludedLibraryFileOverridePrefix,
187
+ excludedInternalFunctionSubstring: instrumentationOptions.excludedInternalFunctionSubstring,
187
188
  debug: instrumentationOptions.debug,
188
189
  logPrefix: nativeLogPrefix
189
190
  };
@@ -203,4 +204,4 @@ const instrumentForCoverage = (wasmBuffer, sourceMapBuffer, instrumentationOptio
203
204
 
204
205
  //#endregion
205
206
  export { instrumentForCoverage };
206
- //# sourceMappingURL=addon-interface-_pNXcbib.mjs.map
207
+ //# sourceMappingURL=addon-interface-CYFXMbK7.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"addon-interface-CYFXMbK7.mjs","names":[],"sources":["../src/instrumentation/addon-interface.ts"],"sourcesContent":["/**\n * Native addon interface for extracting debug information from WebAssembly binaries\n *\n * This module wraps Binaryen's C++ API to provide expression-level debug locations\n * and basic block information that the JavaScript API doesn't expose.\n *\n * The native addon outputs raw data (0-based columns, relative paths) which this\n * wrapper transforms into the final BinaryDebugInfo format (1-based columns,\n * absolute paths, grouped by file and position).\n */\n\nimport { createRequire } from 'node:module';\nimport { resolve, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type {\n NativeAddon,\n NativeInstrumentationResult,\n NativeDebugInfoOutput,\n NativeFunctionDebugInfo,\n NativeExpressionDebugInfo,\n NativeSourceLocation,\n BinaryDebugInfo,\n FunctionDebugInfo,\n SourceLocation,\n ExpressionDebugInfo,\n InstrumentationResult,\n NativeInstrumentationOptions,\n InstrumentationOptions,\n InstrumentForCoverageFunc,\n} from '../types/types.js';\nimport {\n POOL_ERROR_NAMES,\n INTERNAL_PATH_LIB_PREFIX,\n} from '../types/constants.js';\nimport { debug } from '../util/debug.js';\nimport { toForwardSlash } from '../util/path-utils.js';\nimport { createPoolError } from '../util/pool-errors.js';\nimport { getShortFunctionName } from '../wasm-executor/wasm-names.js';\n\n// Load the native addon via node-gyp-build\n// node-gyp-build checks: prebuilds/ first, then build/Release/\n// It searches from the given directory for a package.json to find the package root.\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst rootFromDist = resolve(__dirname, '..');\n// TODO: Verify if this src fallback is still needed — pool always runs from dist/ even locally.\n// If confirmed dead code, remove this and simplify to a single nodeGypBuild call.\nconst rootFromSrc = resolve(__dirname, '../..');\n\nconst require = createRequire(import.meta.url);\nconst nodeGypBuild: (dir: string) => NativeAddon = require('node-gyp-build');\n\nlet addon: NativeAddon;\ntry {\n addon = nodeGypBuild(rootFromDist);\n} catch {\n try {\n addon = nodeGypBuild(rootFromSrc);\n } catch (err) {\n throw createPoolError(\n `vitest-pool-assemblyscript native instrumentation addon not found. Searched from ${rootFromDist} and ${rootFromSrc}. `\n + `Ensure prebuilds are available or run 'node node_modules/vitest-pool-assemblyscript/scripts/install-native-addon.js'`\n + ` to compile from source. Original error: ${err instanceof Error ? err.message : String(err)}`,\n POOL_ERROR_NAMES.WASMInstrumentationError\n );\n }\n}\n\n/**\n * Convert a raw location (0-indexed columns, path indexes) to\n * processed location (1-indexed columns, absolute path strings)\n *\n * Source map paths vary by import style and project structure:\n * - Relative imports: \"assembly/compare.ts\"\n * - Bare package imports: \"~lib/vitest-pool-assemblyscript/assembly/compare.ts\"\n * - Source outside project root: \"../assembly/compare.ts\" (e.g. test-external importing parent sources)\n *\n * All are normalized to absolute filesystem paths for consistent coverage key matching.\n */\nfunction convertLocation(\n rawLocation: NativeSourceLocation,\n debugSourceFiles: string[],\n projectRoot: string\n): SourceLocation {\n let filePath = debugSourceFiles[rawLocation.fileIndex];\n\n if (!filePath) {\n throw createPoolError(\n `No debug source file with index: ${rawLocation.fileIndex}}`,\n POOL_ERROR_NAMES.WASMInstrumentationError\n );\n }\n\n // Normalize to absolute path for consistent coverage key matching\n if (filePath.startsWith(INTERNAL_PATH_LIB_PREFIX)) {\n // ~lib/vitest-pool-assemblyscript/assembly/X.ts -> projectRoot/assembly/X.ts\n const relativePart = filePath.slice(INTERNAL_PATH_LIB_PREFIX.length);\n filePath = toForwardSlash(resolve(projectRoot, 'assembly', relativePart));\n } else {\n // Resolve relative path (handles both 'assembly/X.ts' and '../assembly/X.ts')\n filePath = toForwardSlash(resolve(projectRoot, filePath));\n }\n\n return {\n filePath,\n line: rawLocation.line,\n column: rawLocation.column + 1, // convert from 0-indexed to 1-indexed\n };\n}\n\n/**\n * Convert a raw expression to processed format\n */\nfunction convertExpression(\n rawExpr: NativeExpressionDebugInfo,\n debugSourceFiles: string[],\n projectRoot: string\n): ExpressionDebugInfo {\n const converted: ExpressionDebugInfo = {\n type: rawExpr.type,\n isBranch: rawExpr.isBranch,\n };\n\n if (rawExpr.branchPaths !== undefined) {\n converted.branchPaths = rawExpr.branchPaths;\n }\n\n if (rawExpr.location) {\n const convertedLocation = convertLocation(rawExpr.location, debugSourceFiles, projectRoot);\n if (convertedLocation) {\n converted.location = convertedLocation;\n }\n }\n\n return converted;\n}\n\n/**\n * Generate a position key to identify the SourceLocation uniquely\n * within a file. Does NOT include the file identifier.\n */\nfunction getPositionKey(location: SourceLocation) {\n return `${location.line}:${location.column}`;\n}\n\n/**\n * Convert a raw function to processed format and compute position key\n * Returns undefined if function has no valid representative location\n */\nfunction convertFunction(\n rawFunc: NativeFunctionDebugInfo,\n debugSourceFiles: string[],\n projectRoot: string\n): { func: FunctionDebugInfo; filePath: string; positionKey: string } | undefined {\n const representativeLocation = convertLocation(rawFunc.representativeLocation, debugSourceFiles, projectRoot);\n\n // Convert expressions\n const expressions: ExpressionDebugInfo[] = [];\n if (rawFunc.expressions) {\n for (const expr of rawFunc.expressions) {\n expressions.push(convertExpression(expr, debugSourceFiles, projectRoot));\n }\n }\n\n const converted: FunctionDebugInfo = {\n wasmIndex: rawFunc.wasmIndex,\n name: rawFunc.name,\n representativeLocation,\n coverageMemoryIndex: rawFunc.coverageMemoryIndex,\n expressions,\n basicBlocks: rawFunc.basicBlocks,\n };\n\n const filePath = representativeLocation.filePath;\n const positionKey = getPositionKey(representativeLocation);\n\n return { func: converted, filePath, positionKey };\n}\n\n/**\n * Check if two WASM function names are monomorphizations of the same generic function.\n * Generic monomorphizations share the same base name and suffix, differing only in\n * the type parameters inside angle brackets.\n *\n * e.g. \"assembly/compare/closeTo<bool\\2cbool>\" and \"assembly/compare/closeTo<bool\\2cu8>\"\n * e.g. \"assembly/expect/BaseExpectMatcher<bool>#constructor\" and \"assembly/expect/BaseExpectMatcher<i8>#constructor\"\n */\nfunction isGenericMonomorphizationMatch(nameA: string, nameB: string): boolean {\n const openA = nameA.indexOf('<');\n const openB = nameB.indexOf('<');\n\n // Both must contain generic type parameters\n if (openA === -1 || openB === -1) return false;\n\n const lastCloseA = nameA.lastIndexOf('>');\n const lastCloseB = nameB.lastIndexOf('>');\n\n if (lastCloseA === -1 || lastCloseB === -1) return false;\n\n // Prefix before '<' must match (includes module path, class, function name)\n const prefixA = nameA.substring(0, openA);\n const prefixB = nameB.substring(0, openB);\n if (prefixA !== prefixB) return false;\n\n // Suffix after last '>' must match (e.g. \"#constructor\", or empty)\n const suffixA = nameA.substring(lastCloseA + 1);\n const suffixB = nameB.substring(lastCloseB + 1);\n if (suffixA !== suffixB) return false;\n\n return true;\n}\n\n/**\n * Transform raw native addon output to processed BinaryDebugInfo\n */\nfunction transformDebugInfo(\n raw: NativeDebugInfoOutput,\n logPrefix: string,\n projectRoot: string,\n): BinaryDebugInfo {\n const functionsByFileAndPosition: Record<string, Record<string, FunctionDebugInfo[]>> = {};\n\n debug(`${logPrefix} - Converting ${raw.functions.length} functions`);\n\n let genericCollisionCount = 0;\n let skippedCount = 0;\n let instrumentedFunctionCount = 0;\n\n for (const rawFunc of raw.functions) {\n const result = convertFunction(rawFunc, raw.debugSourceFiles, projectRoot);\n if (!result) {\n debug(`${logPrefix} - WARNING: Skipped function (bad conversion): \"${rawFunc.name}\"`);\n skippedCount++;\n continue;\n }\n\n const { func, filePath, positionKey } = result;\n\n // Check for position collisions\n const existingAtPosition = functionsByFileAndPosition[filePath]?.[positionKey];\n if (existingAtPosition) {\n const existingName = existingAtPosition[0]!.name;\n\n // Only allow collision if both are monomorphizations of the same generic\n if (isGenericMonomorphizationMatch(existingName, func.name)) {\n existingAtPosition.push(func);\n genericCollisionCount++;\n instrumentedFunctionCount++;\n debug(\n `${logPrefix} - Generic monomorphization at ${filePath}:${positionKey}:`\n + ` \"${getShortFunctionName(func.name)}\" grouped with \"${getShortFunctionName(existingName)}\"`\n );\n continue;\n }\n\n throw createPoolError(\n `ERROR - Function Debug Position Collision at ${filePath}:${positionKey}: \"${getShortFunctionName(existingName)}\"`\n + ` will be replaced by \"${getShortFunctionName(func.name)}\". This is a bug. Please report it at:`\n + ` https://github.com/themattspiral/vitest-pool-assemblyscript/issues/new`,\n POOL_ERROR_NAMES.WASMInstrumentationError\n );\n }\n\n instrumentedFunctionCount++;\n\n // Group by file and position\n if (!functionsByFileAndPosition[filePath]) {\n functionsByFileAndPosition[filePath] = {};\n }\n\n functionsByFileAndPosition[filePath][positionKey] = [func];\n }\n\n debug(\n `${logPrefix} - BinaryDebugInfo transform complete: ${instrumentedFunctionCount} instrumented functions`\n + ` (${genericCollisionCount} generic collisions, ${skippedCount} skipped)`\n );\n\n return {\n debugSourceFiles: raw.debugSourceFiles,\n functionsByFileAndPosition,\n instrumentedFunctionCount,\n };\n}\n\n/**\n * Instrument a WASM binary for coverage collection and regenerate source map\n *\n * This function:\n * 1. Adds __coverage_memory import (multi-memory for coverage counters)\n * 2. Injects coverage counter increments at each function entry\n * 3. Regenerates source map with correct offsets after instrumentation\n * 4. Extracts debug info with coverageMemoryIndex assigned\n *\n * @param wasmBuffer - Buffer containing the clean WASM binary\n * @param sourceMapBuffer - Buffer containing the source map JSON\n * @returns Instrumented binary, regenerated source map, and debug info\n *\n * @throws {TypeError} If wasmBuffer or sourceMapBuffer are not Buffers\n * @throws {Error} If WASM binary or source map is invalid\n */\nexport const instrumentForCoverage: InstrumentForCoverageFunc = (\n wasmBuffer: Buffer,\n sourceMapBuffer: Buffer,\n instrumentationOptions: InstrumentationOptions,\n logModule: string,\n logLabel: string,\n): InstrumentationResult => {\n if (!Buffer.isBuffer(wasmBuffer)) {\n throw createPoolError(\n 'instrumentForCoverage - wasmBuffer must be a Buffer',\n POOL_ERROR_NAMES.WASMInstrumentationError\n );\n }\n if (!Buffer.isBuffer(sourceMapBuffer)) {\n throw createPoolError(\n 'instrumentForCoverage - sourceMapBuffer must be a Buffer',\n POOL_ERROR_NAMES.WASMInstrumentationError\n );\n }\n\n const interfaceLogPrefix = `[${logModule} Inst] ${logLabel}`;\n const nativeLogPrefix = `[${logModule} InstNative] ${logLabel}`;\n\n debug(`${interfaceLogPrefix} - Calling native instrumentForCoverage`);\n const startTime = performance.now();\n\n const options: NativeInstrumentationOptions = {\n coverageMemoryPagesMin: instrumentationOptions.coverageMemoryPagesMin,\n coverageMemoryPagesMax: instrumentationOptions.coverageMemoryPagesMax,\n excludedFiles: instrumentationOptions.relativeExcludedFiles,\n excludedLibraryFilePrefix: instrumentationOptions.excludedLibraryFilePrefix,\n excludedLibraryFileOverridePrefix: instrumentationOptions.excludedLibraryFileOverridePrefix,\n excludedInternalFunctionSubstring: instrumentationOptions.excludedInternalFunctionSubstring,\n debug: instrumentationOptions.debug,\n logPrefix: nativeLogPrefix\n };\n const nativeResult: NativeInstrumentationResult = addon.instrumentForCoverage(wasmBuffer, sourceMapBuffer, options);\n const addonTime = performance.now();\n debug(`${interfaceLogPrefix} - TIMING Native addon: ${(addonTime - startTime).toFixed(2)} ms`);\n\n if (nativeResult.errors?.length) {\n throw createPoolError(\n `Errors encountered duriing native instrumentation: ${nativeResult.errors.join('\\n')}`,\n POOL_ERROR_NAMES.WASMInstrumentationError,\n );\n }\n\n const debugInfo = transformDebugInfo(nativeResult.debugInfo, interfaceLogPrefix, instrumentationOptions.projectRoot);\n \n const transformTime = performance.now();\n debug(`${interfaceLogPrefix} - TIMING DebugInfo Transform: ${(transformTime - addonTime).toFixed(2)} ms`);\n debug(`${interfaceLogPrefix} - Binary size: ${nativeResult.instrumentedWasm.length} bytes | Source map size: ${nativeResult.sourceMap.length * 2} bytes`);\n\n return {\n instrumentedWasm: nativeResult.instrumentedWasm,\n sourceMap: nativeResult.sourceMap,\n debugInfo,\n };\n}\n"],"mappings":"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"}