@ricsam/isolate-test-environment 0.1.8 → 0.1.10

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.
@@ -1,5 +1,4 @@
1
- // @bun @bun-cjs
2
- (function(exports, require, module, __filename, __dirname) {var __create = Object.create;
1
+ var __create = Object.create;
3
2
  var __getProtoOf = Object.getPrototypeOf;
4
3
  var __defProp = Object.defineProperty;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -936,6 +935,5 @@ function hasTests(context) {
936
935
  function getTestCount(context) {
937
936
  return context.evalSync("__getTestCount()");
938
937
  }
939
- })
940
938
 
941
- //# debugId=424CE17957C8217764756E2164756E21
939
+ //# debugId=62DC5588AE7E091364756E2164756E21
@@ -4,7 +4,7 @@
4
4
  "sourcesContent": [
5
5
  "import type ivm from \"isolated-vm\";\nimport IsolatedVM from \"isolated-vm\";\n\n// ============================================================\n// Test Environment Options\n// ============================================================\n\nexport interface TestEnvironmentOptions {\n /** Receive test lifecycle events */\n onEvent?: (event: TestEvent) => void;\n /** Timeout for individual tests (ms) */\n testTimeout?: number;\n}\n\n// ============================================================\n// Event Types (discriminated union)\n// ============================================================\n\nexport type TestEvent =\n | { type: \"runStart\"; testCount: number; suiteCount: number }\n | { type: \"suiteStart\"; suite: SuiteInfo }\n | { type: \"suiteEnd\"; suite: SuiteResult }\n | { type: \"testStart\"; test: TestInfo }\n | { type: \"testEnd\"; test: TestResult }\n | { type: \"runEnd\"; results: RunResults };\n\n// ============================================================\n// Suite Types\n// ============================================================\n\nexport interface SuiteInfo {\n name: string;\n /** Ancestry path: [\"outer\", \"inner\"] */\n path: string[];\n /** Full display name: \"outer > inner\" */\n fullName: string;\n /** Nesting depth (0 for root-level suites) */\n depth: number;\n}\n\nexport interface SuiteResult extends SuiteInfo {\n passed: number;\n failed: number;\n skipped: number;\n todo: number;\n duration: number;\n}\n\n// ============================================================\n// Test Types\n// ============================================================\n\nexport interface TestInfo {\n name: string;\n /** Suite ancestry */\n suitePath: string[];\n /** Full display name: \"suite > test name\" */\n fullName: string;\n}\n\nexport interface TestResult extends TestInfo {\n status: \"pass\" | \"fail\" | \"skip\" | \"todo\";\n duration: number;\n error?: TestError;\n}\n\nexport interface TestError {\n message: string;\n stack?: string;\n /** For assertion failures */\n expected?: unknown;\n actual?: unknown;\n /** e.g., \"toBe\", \"toEqual\", \"toContain\" */\n matcherName?: string;\n}\n\n// ============================================================\n// Run Results\n// ============================================================\n\nexport interface RunResults {\n passed: number;\n failed: number;\n skipped: number;\n todo: number;\n total: number;\n duration: number;\n success: boolean;\n suites: SuiteResult[];\n tests: TestResult[];\n}\n\n// ============================================================\n// Handle Interface\n// ============================================================\n\nexport interface TestEnvironmentHandle {\n dispose(): void;\n}\n\nconst testEnvironmentCode = `\n(function() {\n // ============================================================\n // Internal State\n // ============================================================\n\n function createSuite(name, skip = false, only = false) {\n return {\n name,\n tests: [],\n children: [],\n beforeAll: [],\n afterAll: [],\n beforeEach: [],\n afterEach: [],\n skip,\n only,\n };\n }\n\n const rootSuite = createSuite('root');\n let currentSuite = rootSuite;\n const suiteStack = [rootSuite];\n\n // Event callback (set from host)\n let eventCallback = null;\n\n function emitEvent(event) {\n if (eventCallback) {\n try {\n eventCallback(JSON.stringify(event));\n } catch (e) {\n // Ignore callback errors\n }\n }\n }\n\n // ============================================================\n // TestError class for rich error info\n // ============================================================\n\n class TestError extends Error {\n constructor(message, matcherName, expected, actual) {\n super(message);\n this.name = 'TestError';\n this.matcherName = matcherName;\n this.expected = expected;\n this.actual = actual;\n }\n }\n\n // ============================================================\n // Deep Equality Helper\n // ============================================================\n\n function deepEqual(a, b) {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (typeof a !== 'object' || a === null || b === null) return false;\n\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false;\n if (!deepEqual(a[key], b[key])) return false;\n }\n return true;\n }\n\n function strictDeepEqual(a, b) {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (typeof a !== 'object' || a === null || b === null) return false;\n\n // Check prototypes\n if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) return false;\n\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n // For arrays, check sparse arrays (holes)\n if (Array.isArray(a)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const aHasIndex = i in a;\n const bHasIndex = i in b;\n if (aHasIndex !== bHasIndex) return false;\n if (aHasIndex && !strictDeepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n // Check for undefined properties vs missing properties\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false;\n if (!strictDeepEqual(a[key], b[key])) return false;\n }\n\n // Check for symbol properties\n const symbolsA = Object.getOwnPropertySymbols(a);\n const symbolsB = Object.getOwnPropertySymbols(b);\n if (symbolsA.length !== symbolsB.length) return false;\n\n for (const sym of symbolsA) {\n if (!symbolsB.includes(sym)) return false;\n if (!strictDeepEqual(a[sym], b[sym])) return false;\n }\n\n return true;\n }\n\n function getNestedProperty(obj, path) {\n const parts = path.split('.');\n let current = obj;\n for (const part of parts) {\n if (current == null || !(part in current)) {\n return { exists: false };\n }\n current = current[part];\n }\n return { exists: true, value: current };\n }\n\n function formatValue(val) {\n if (val === null) return 'null';\n if (val === undefined) return 'undefined';\n if (typeof val === 'string') return JSON.stringify(val);\n if (typeof val === 'object') {\n try {\n return JSON.stringify(val);\n } catch {\n return String(val);\n }\n }\n return String(val);\n }\n\n // ============================================================\n // expect() Implementation\n // ============================================================\n\n function expect(actual) {\n function createMatchers(negated = false) {\n const assert = (condition, message, matcherName, expected) => {\n const pass = negated ? !condition : condition;\n if (!pass) {\n throw new TestError(message, matcherName, expected, actual);\n }\n };\n\n const matchers = {\n toBe(expected) {\n assert(\n actual === expected,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to be \\${formatValue(expected)}\\`,\n 'toBe',\n expected\n );\n },\n\n toEqual(expected) {\n assert(\n deepEqual(actual, expected),\n negated\n ? \\`Expected \\${formatValue(actual)} not to equal \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to equal \\${formatValue(expected)}\\`,\n 'toEqual',\n expected\n );\n },\n\n toStrictEqual(expected) {\n assert(\n strictDeepEqual(actual, expected),\n negated\n ? \\`Expected \\${formatValue(actual)} not to strictly equal \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to strictly equal \\${formatValue(expected)}\\`,\n 'toStrictEqual',\n expected\n );\n },\n\n toBeTruthy() {\n assert(\n !!actual,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be truthy\\`\n : \\`Expected \\${formatValue(actual)} to be truthy\\`,\n 'toBeTruthy',\n true\n );\n },\n\n toBeFalsy() {\n assert(\n !actual,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be falsy\\`\n : \\`Expected \\${formatValue(actual)} to be falsy\\`,\n 'toBeFalsy',\n false\n );\n },\n\n toBeNull() {\n assert(\n actual === null,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be null\\`\n : \\`Expected \\${formatValue(actual)} to be null\\`,\n 'toBeNull',\n null\n );\n },\n\n toBeUndefined() {\n assert(\n actual === undefined,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be undefined\\`\n : \\`Expected \\${formatValue(actual)} to be undefined\\`,\n 'toBeUndefined',\n undefined\n );\n },\n\n toBeDefined() {\n assert(\n actual !== undefined,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be defined\\`\n : \\`Expected \\${formatValue(actual)} to be defined\\`,\n 'toBeDefined',\n 'defined'\n );\n },\n\n toContain(item) {\n let contains = false;\n if (Array.isArray(actual)) {\n contains = actual.includes(item);\n } else if (typeof actual === 'string') {\n contains = actual.includes(item);\n }\n assert(\n contains,\n negated\n ? \\`Expected \\${formatValue(actual)} not to contain \\${formatValue(item)}\\`\n : \\`Expected \\${formatValue(actual)} to contain \\${formatValue(item)}\\`,\n 'toContain',\n item\n );\n },\n\n toThrow(expected) {\n if (typeof actual !== 'function') {\n throw new Error('toThrow requires a function');\n }\n\n let threw = false;\n let error = null;\n try {\n actual();\n } catch (e) {\n threw = true;\n error = e;\n }\n\n if (expected !== undefined) {\n const matches = threw && (\n (typeof expected === 'string' && error.message.includes(expected)) ||\n (expected instanceof RegExp && expected.test(error.message)) ||\n (typeof expected === 'function' && error instanceof expected)\n );\n assert(\n matches,\n negated\n ? \\`Expected function not to throw \\${formatValue(expected)}\\`\n : \\`Expected function to throw \\${formatValue(expected)}, but \\${threw ? \\`threw: \\${error.message}\\` : 'did not throw'}\\`,\n 'toThrow',\n expected\n );\n } else {\n assert(\n threw,\n negated\n ? \\`Expected function not to throw\\`\n : \\`Expected function to throw\\`,\n 'toThrow',\n 'any error'\n );\n }\n },\n\n toBeInstanceOf(cls) {\n assert(\n actual instanceof cls,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be instance of \\${cls.name || cls}\\`\n : \\`Expected \\${formatValue(actual)} to be instance of \\${cls.name || cls}\\`,\n 'toBeInstanceOf',\n cls.name || cls\n );\n },\n\n toHaveLength(length) {\n const actualLength = actual?.length;\n assert(\n actualLength === length,\n negated\n ? \\`Expected length not to be \\${length}, but got \\${actualLength}\\`\n : \\`Expected length to be \\${length}, but got \\${actualLength}\\`,\n 'toHaveLength',\n length\n );\n },\n\n toMatch(pattern) {\n let matches = false;\n if (typeof pattern === 'string') {\n matches = actual.includes(pattern);\n } else if (pattern instanceof RegExp) {\n matches = pattern.test(actual);\n }\n assert(\n matches,\n negated\n ? \\`Expected \\${formatValue(actual)} not to match \\${pattern}\\`\n : \\`Expected \\${formatValue(actual)} to match \\${pattern}\\`,\n 'toMatch',\n pattern\n );\n },\n\n toHaveProperty(path, value) {\n const prop = getNestedProperty(actual, path);\n const hasProperty = prop.exists;\n const valueMatches = arguments.length < 2 || deepEqual(prop.value, value);\n\n assert(\n hasProperty && valueMatches,\n negated\n ? \\`Expected \\${formatValue(actual)} not to have property \\${path}\\${arguments.length >= 2 ? \\` with value \\${formatValue(value)}\\` : ''}\\`\n : \\`Expected \\${formatValue(actual)} to have property \\${path}\\${arguments.length >= 2 ? \\` with value \\${formatValue(value)}\\` : ''}\\`,\n 'toHaveProperty',\n arguments.length >= 2 ? { path, value } : { path }\n );\n },\n\n toBeGreaterThan(expected) {\n assert(\n actual > expected,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be greater than \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to be greater than \\${formatValue(expected)}\\`,\n 'toBeGreaterThan',\n expected\n );\n },\n\n toBeGreaterThanOrEqual(expected) {\n assert(\n actual >= expected,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be greater than or equal to \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to be greater than or equal to \\${formatValue(expected)}\\`,\n 'toBeGreaterThanOrEqual',\n expected\n );\n },\n\n toBeLessThan(expected) {\n assert(\n actual < expected,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be less than \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to be less than \\${formatValue(expected)}\\`,\n 'toBeLessThan',\n expected\n );\n },\n\n toBeLessThanOrEqual(expected) {\n assert(\n actual <= expected,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be less than or equal to \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to be less than or equal to \\${formatValue(expected)}\\`,\n 'toBeLessThanOrEqual',\n expected\n );\n },\n };\n\n return matchers;\n }\n\n const matchers = createMatchers(false);\n matchers.not = createMatchers(true);\n\n return matchers;\n }\n\n // ============================================================\n // Test Registration Functions\n // ============================================================\n\n function describe(name, fn) {\n const suite = createSuite(name);\n currentSuite.children.push(suite);\n\n const parentSuite = currentSuite;\n currentSuite = suite;\n suiteStack.push(suite);\n\n fn();\n\n suiteStack.pop();\n currentSuite = parentSuite;\n }\n\n describe.skip = function(name, fn) {\n const suite = createSuite(name, true, false);\n currentSuite.children.push(suite);\n\n const parentSuite = currentSuite;\n currentSuite = suite;\n suiteStack.push(suite);\n\n fn();\n\n suiteStack.pop();\n currentSuite = parentSuite;\n };\n\n describe.only = function(name, fn) {\n const suite = createSuite(name, false, true);\n currentSuite.children.push(suite);\n\n const parentSuite = currentSuite;\n currentSuite = suite;\n suiteStack.push(suite);\n\n fn();\n\n suiteStack.pop();\n currentSuite = parentSuite;\n };\n\n function test(name, fn) {\n currentSuite.tests.push({\n name,\n fn,\n skip: false,\n only: false,\n });\n }\n\n test.skip = function(name, fn) {\n currentSuite.tests.push({\n name,\n fn,\n skip: true,\n only: false,\n });\n };\n\n test.only = function(name, fn) {\n currentSuite.tests.push({\n name,\n fn,\n skip: false,\n only: true,\n });\n };\n\n test.todo = function(name) {\n currentSuite.tests.push({\n name,\n fn: null,\n skip: false,\n only: false,\n todo: true,\n });\n };\n\n const it = test;\n it.skip = test.skip;\n it.only = test.only;\n it.todo = test.todo;\n\n // ============================================================\n // Lifecycle Hooks\n // ============================================================\n\n function beforeEach(fn) {\n currentSuite.beforeEach.push(fn);\n }\n\n function afterEach(fn) {\n currentSuite.afterEach.push(fn);\n }\n\n function beforeAll(fn) {\n currentSuite.beforeAll.push(fn);\n }\n\n function afterAll(fn) {\n currentSuite.afterAll.push(fn);\n }\n\n // ============================================================\n // Test Runner Helpers\n // ============================================================\n\n function checkForOnly(suite) {\n if (suite.only) return true;\n for (const t of suite.tests) {\n if (t.only) return true;\n }\n for (const child of suite.children) {\n if (checkForOnly(child)) return true;\n }\n return false;\n }\n\n function suiteHasOnly(suite) {\n if (suite.only) return true;\n for (const t of suite.tests) {\n if (t.only) return true;\n }\n for (const child of suite.children) {\n if (suiteHasOnly(child)) return true;\n }\n return false;\n }\n\n function countTests(suite, hasOnly) {\n let count = 0;\n if (hasOnly && !suiteHasOnly(suite)) return 0;\n if (suite.skip) return suite.tests.length;\n\n for (const t of suite.tests) {\n if (hasOnly && !t.only && !suite.only) continue;\n count++;\n }\n for (const child of suite.children) {\n count += countTests(child, hasOnly);\n }\n return count;\n }\n\n function countSuites(suite, hasOnly) {\n let count = 0;\n if (hasOnly && !suiteHasOnly(suite)) return 0;\n\n for (const child of suite.children) {\n count++;\n count += countSuites(child, hasOnly);\n }\n return count;\n }\n\n // ============================================================\n // Test Runner\n // ============================================================\n\n async function __runAllTests() {\n const testResults = [];\n const suiteResults = [];\n const hasOnly = checkForOnly(rootSuite);\n const runStart = Date.now();\n\n // Emit runStart\n const testCount = countTests(rootSuite, hasOnly);\n const suiteCount = countSuites(rootSuite, hasOnly);\n emitEvent({ type: 'runStart', testCount, suiteCount });\n\n async function runSuite(suite, parentHooks, pathArray, depth) {\n // Skip if this suite doesn't have any .only when .only exists elsewhere\n if (hasOnly && !suiteHasOnly(suite)) return;\n\n const suitePath = [...pathArray];\n const fullName = suitePath.join(' > ');\n const suiteInfo = {\n name: suite.name,\n path: suitePath.slice(0, -1),\n fullName,\n depth,\n };\n\n // Emit suiteStart (only for non-root suites)\n if (suite !== rootSuite) {\n emitEvent({ type: 'suiteStart', suite: suiteInfo });\n }\n\n const suiteStart = Date.now();\n let suitePassed = 0;\n let suiteFailed = 0;\n let suiteSkipped = 0;\n let suiteTodo = 0;\n\n // Skip if suite is marked as skip\n if (suite.skip) {\n // Mark all tests in this suite as skipped\n for (const t of suite.tests) {\n const testFullName = fullName ? fullName + ' > ' + t.name : t.name;\n const testInfo = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n };\n emitEvent({ type: 'testStart', test: testInfo });\n\n const testResult = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n status: 'skip',\n duration: 0,\n };\n testResults.push(testResult);\n suiteSkipped++;\n\n emitEvent({ type: 'testEnd', test: testResult });\n }\n } else {\n // Run beforeAll hooks\n for (const hook of suite.beforeAll) {\n await hook();\n }\n\n // Run tests\n for (const t of suite.tests) {\n const testFullName = fullName ? fullName + ' > ' + t.name : t.name;\n const testInfo = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n };\n\n // Skip if .only is used and this test isn't .only AND the suite doesn't have .only\n if (hasOnly && !t.only && !suite.only) continue;\n\n emitEvent({ type: 'testStart', test: testInfo });\n\n // Skip if test is marked as skip\n if (t.skip) {\n const testResult = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n status: 'skip',\n duration: 0,\n };\n testResults.push(testResult);\n suiteSkipped++;\n emitEvent({ type: 'testEnd', test: testResult });\n continue;\n }\n\n // Handle todo tests (no function provided)\n if (t.todo) {\n const testResult = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n status: 'todo',\n duration: 0,\n };\n testResults.push(testResult);\n suiteTodo++;\n emitEvent({ type: 'testEnd', test: testResult });\n continue;\n }\n\n const testStart = Date.now();\n try {\n // Run all beforeEach hooks (parent first, then current)\n for (const hook of [...parentHooks.beforeEach, ...suite.beforeEach]) {\n await hook();\n }\n\n // Run test\n await t.fn();\n\n // Run all afterEach hooks (current first, then parent)\n for (const hook of [...suite.afterEach, ...parentHooks.afterEach]) {\n await hook();\n }\n\n const testResult = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n status: 'pass',\n duration: Date.now() - testStart,\n };\n testResults.push(testResult);\n suitePassed++;\n emitEvent({ type: 'testEnd', test: testResult });\n } catch (err) {\n const testError = {\n message: err.message || String(err),\n stack: err.stack,\n };\n // If it's a TestError, include matcher info\n if (err.matcherName !== undefined) {\n testError.matcherName = err.matcherName;\n testError.expected = err.expected;\n testError.actual = err.actual;\n }\n const testResult = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n status: 'fail',\n duration: Date.now() - testStart,\n error: testError,\n };\n testResults.push(testResult);\n suiteFailed++;\n emitEvent({ type: 'testEnd', test: testResult });\n }\n }\n\n // Run child suites\n for (const child of suite.children) {\n const childPath = [...suitePath, child.name];\n await runSuite(child, {\n beforeEach: [...parentHooks.beforeEach, ...suite.beforeEach],\n afterEach: [...suite.afterEach, ...parentHooks.afterEach],\n }, childPath, depth + 1);\n }\n\n // Run afterAll hooks\n for (const hook of suite.afterAll) {\n await hook();\n }\n }\n\n // Emit suiteEnd (only for non-root suites)\n if (suite !== rootSuite) {\n const suiteResult = {\n ...suiteInfo,\n passed: suitePassed,\n failed: suiteFailed,\n skipped: suiteSkipped,\n todo: suiteTodo,\n duration: Date.now() - suiteStart,\n };\n suiteResults.push(suiteResult);\n emitEvent({ type: 'suiteEnd', suite: suiteResult });\n }\n }\n\n await runSuite(rootSuite, { beforeEach: [], afterEach: [] }, [], -1);\n\n const passed = testResults.filter(r => r.status === 'pass').length;\n const failed = testResults.filter(r => r.status === 'fail').length;\n const skipped = testResults.filter(r => r.status === 'skip').length;\n const todo = testResults.filter(r => r.status === 'todo').length;\n\n const runResults = {\n passed,\n failed,\n skipped,\n todo,\n total: testResults.length,\n duration: Date.now() - runStart,\n success: failed === 0,\n suites: suiteResults,\n tests: testResults,\n };\n\n emitEvent({ type: 'runEnd', results: runResults });\n\n return JSON.stringify(runResults);\n }\n\n // ============================================================\n // Helper Functions\n // ============================================================\n\n function __hasTests() {\n function checkSuite(suite) {\n if (suite.tests.length > 0) return true;\n for (const child of suite.children) {\n if (checkSuite(child)) return true;\n }\n return false;\n }\n return checkSuite(rootSuite);\n }\n\n function __getTestCount() {\n function countInSuite(suite) {\n let count = suite.tests.length;\n for (const child of suite.children) {\n count += countInSuite(child);\n }\n return count;\n }\n return countInSuite(rootSuite);\n }\n\n // Reset function to clear state between runs\n function __resetTestEnvironment() {\n rootSuite.tests = [];\n rootSuite.children = [];\n rootSuite.beforeAll = [];\n rootSuite.afterAll = [];\n rootSuite.beforeEach = [];\n rootSuite.afterEach = [];\n currentSuite = rootSuite;\n suiteStack.length = 0;\n suiteStack.push(rootSuite);\n }\n\n function __setEventCallback(callback) {\n eventCallback = callback;\n }\n\n // ============================================================\n // Expose Globals\n // ============================================================\n\n globalThis.describe = describe;\n globalThis.test = test;\n globalThis.it = it;\n globalThis.expect = expect;\n globalThis.beforeEach = beforeEach;\n globalThis.afterEach = afterEach;\n globalThis.beforeAll = beforeAll;\n globalThis.afterAll = afterAll;\n globalThis.__runAllTests = __runAllTests;\n globalThis.__resetTestEnvironment = __resetTestEnvironment;\n globalThis.__hasTests = __hasTests;\n globalThis.__getTestCount = __getTestCount;\n globalThis.__setEventCallback = __setEventCallback;\n})();\n`;\n\n/**\n * Setup test environment primitives in an isolated-vm context\n *\n * Provides Jest/Vitest-compatible test primitives:\n * - describe, test, it\n * - beforeEach, afterEach, beforeAll, afterAll\n * - expect matchers\n *\n * @example\n * const handle = await setupTestEnvironment(context, {\n * onEvent: (event) => console.log(event),\n * });\n *\n * await context.eval(`\n * describe(\"my tests\", () => {\n * test(\"example\", () => {\n * expect(1 + 1).toBe(2);\n * });\n * });\n * `);\n */\nexport async function setupTestEnvironment(\n context: ivm.Context,\n options?: TestEnvironmentOptions\n): Promise<TestEnvironmentHandle> {\n context.evalSync(testEnvironmentCode);\n\n // Set up event callback if provided\n if (options?.onEvent) {\n const eventCallbackRef = new IsolatedVM.Reference((eventJson: string) => {\n try {\n const event = JSON.parse(eventJson);\n options.onEvent!(event);\n } catch {\n // Ignore parse errors\n }\n });\n\n const global = context.global;\n global.setSync(\"__eventCallbackRef\", eventCallbackRef);\n context.evalSync(`\n __setEventCallback((eventJson) => {\n __eventCallbackRef.applySync(undefined, [eventJson]);\n });\n `);\n }\n\n return {\n dispose() {\n // Reset the test environment state\n try {\n context.evalSync(\"__resetTestEnvironment()\");\n } catch {\n // Context may already be released\n }\n },\n };\n}\n\n/**\n * Run tests in the context and return results\n */\nexport async function runTests(context: ivm.Context): Promise<RunResults> {\n const resultJson = await context.eval(\"__runAllTests()\", { promise: true });\n return JSON.parse(resultJson as string);\n}\n\n/**\n * Check if any tests are registered\n */\nexport function hasTests(context: ivm.Context): boolean {\n return context.evalSync(\"__hasTests()\") as boolean;\n}\n\n/**\n * Get the count of registered tests\n */\nexport function getTestCount(context: ivm.Context): number {\n return context.evalSync(\"__getTestCount()\") as number;\n}\n"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACuB,IAAvB;AAmGA,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAy2B5B,eAAsB,oBAAoB,CACxC,SACA,SACgC;AAAA,EAChC,QAAQ,SAAS,mBAAmB;AAAA,EAGpC,IAAI,SAAS,SAAS;AAAA,IACpB,MAAM,mBAAmB,IAAI,2BAAW,UAAU,CAAC,cAAsB;AAAA,MACvE,IAAI;AAAA,QACF,MAAM,QAAQ,KAAK,MAAM,SAAS;AAAA,QAClC,QAAQ,QAAS,KAAK;AAAA,QACtB,MAAM;AAAA,KAGT;AAAA,IAED,MAAM,SAAS,QAAQ;AAAA,IACvB,OAAO,QAAQ,sBAAsB,gBAAgB;AAAA,IACrD,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,KAIhB;AAAA,EACH;AAAA,EAEA,OAAO;AAAA,IACL,OAAO,GAAG;AAAA,MAER,IAAI;AAAA,QACF,QAAQ,SAAS,0BAA0B;AAAA,QAC3C,MAAM;AAAA;AAAA,EAIZ;AAAA;AAMF,eAAsB,QAAQ,CAAC,SAA2C;AAAA,EACxE,MAAM,aAAa,MAAM,QAAQ,KAAK,mBAAmB,EAAE,SAAS,KAAK,CAAC;AAAA,EAC1E,OAAO,KAAK,MAAM,UAAoB;AAAA;AAMjC,SAAS,QAAQ,CAAC,SAA+B;AAAA,EACtD,OAAO,QAAQ,SAAS,cAAc;AAAA;AAMjC,SAAS,YAAY,CAAC,SAA8B;AAAA,EACzD,OAAO,QAAQ,SAAS,kBAAkB;AAAA;",
8
- "debugId": "424CE17957C8217764756E2164756E21",
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACuB,IAAvB;AAmGA,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAy2B5B,eAAsB,oBAAoB,CACxC,SACA,SACgC;AAAA,EAChC,QAAQ,SAAS,mBAAmB;AAAA,EAGpC,IAAI,SAAS,SAAS;AAAA,IACpB,MAAM,mBAAmB,IAAI,2BAAW,UAAU,CAAC,cAAsB;AAAA,MACvE,IAAI;AAAA,QACF,MAAM,QAAQ,KAAK,MAAM,SAAS;AAAA,QAClC,QAAQ,QAAS,KAAK;AAAA,QACtB,MAAM;AAAA,KAGT;AAAA,IAED,MAAM,SAAS,QAAQ;AAAA,IACvB,OAAO,QAAQ,sBAAsB,gBAAgB;AAAA,IACrD,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,KAIhB;AAAA,EACH;AAAA,EAEA,OAAO;AAAA,IACL,OAAO,GAAG;AAAA,MAER,IAAI;AAAA,QACF,QAAQ,SAAS,0BAA0B;AAAA,QAC3C,MAAM;AAAA;AAAA,EAIZ;AAAA;AAMF,eAAsB,QAAQ,CAAC,SAA2C;AAAA,EACxE,MAAM,aAAa,MAAM,QAAQ,KAAK,mBAAmB,EAAE,SAAS,KAAK,CAAC;AAAA,EAC1E,OAAO,KAAK,MAAM,UAAoB;AAAA;AAMjC,SAAS,QAAQ,CAAC,SAA+B;AAAA,EACtD,OAAO,QAAQ,SAAS,cAAc;AAAA;AAMjC,SAAS,YAAY,CAAC,SAA8B;AAAA,EACzD,OAAO,QAAQ,SAAS,kBAAkB;AAAA;",
8
+ "debugId": "62DC5588AE7E091364756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/isolate-test-environment",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "type": "commonjs"
5
5
  }
@@ -1,4 +1,3 @@
1
- // @bun
2
1
  // packages/test-environment/src/index.ts
3
2
  import IsolatedVM from "isolated-vm";
4
3
  var testEnvironmentCode = `
@@ -894,4 +893,4 @@ export {
894
893
  getTestCount
895
894
  };
896
895
 
897
- //# debugId=E1ED7CC917A46E0364756E2164756E21
896
+ //# debugId=E073089EDACCEE1764756E2164756E21
@@ -4,7 +4,7 @@
4
4
  "sourcesContent": [
5
5
  "import type ivm from \"isolated-vm\";\nimport IsolatedVM from \"isolated-vm\";\n\n// ============================================================\n// Test Environment Options\n// ============================================================\n\nexport interface TestEnvironmentOptions {\n /** Receive test lifecycle events */\n onEvent?: (event: TestEvent) => void;\n /** Timeout for individual tests (ms) */\n testTimeout?: number;\n}\n\n// ============================================================\n// Event Types (discriminated union)\n// ============================================================\n\nexport type TestEvent =\n | { type: \"runStart\"; testCount: number; suiteCount: number }\n | { type: \"suiteStart\"; suite: SuiteInfo }\n | { type: \"suiteEnd\"; suite: SuiteResult }\n | { type: \"testStart\"; test: TestInfo }\n | { type: \"testEnd\"; test: TestResult }\n | { type: \"runEnd\"; results: RunResults };\n\n// ============================================================\n// Suite Types\n// ============================================================\n\nexport interface SuiteInfo {\n name: string;\n /** Ancestry path: [\"outer\", \"inner\"] */\n path: string[];\n /** Full display name: \"outer > inner\" */\n fullName: string;\n /** Nesting depth (0 for root-level suites) */\n depth: number;\n}\n\nexport interface SuiteResult extends SuiteInfo {\n passed: number;\n failed: number;\n skipped: number;\n todo: number;\n duration: number;\n}\n\n// ============================================================\n// Test Types\n// ============================================================\n\nexport interface TestInfo {\n name: string;\n /** Suite ancestry */\n suitePath: string[];\n /** Full display name: \"suite > test name\" */\n fullName: string;\n}\n\nexport interface TestResult extends TestInfo {\n status: \"pass\" | \"fail\" | \"skip\" | \"todo\";\n duration: number;\n error?: TestError;\n}\n\nexport interface TestError {\n message: string;\n stack?: string;\n /** For assertion failures */\n expected?: unknown;\n actual?: unknown;\n /** e.g., \"toBe\", \"toEqual\", \"toContain\" */\n matcherName?: string;\n}\n\n// ============================================================\n// Run Results\n// ============================================================\n\nexport interface RunResults {\n passed: number;\n failed: number;\n skipped: number;\n todo: number;\n total: number;\n duration: number;\n success: boolean;\n suites: SuiteResult[];\n tests: TestResult[];\n}\n\n// ============================================================\n// Handle Interface\n// ============================================================\n\nexport interface TestEnvironmentHandle {\n dispose(): void;\n}\n\nconst testEnvironmentCode = `\n(function() {\n // ============================================================\n // Internal State\n // ============================================================\n\n function createSuite(name, skip = false, only = false) {\n return {\n name,\n tests: [],\n children: [],\n beforeAll: [],\n afterAll: [],\n beforeEach: [],\n afterEach: [],\n skip,\n only,\n };\n }\n\n const rootSuite = createSuite('root');\n let currentSuite = rootSuite;\n const suiteStack = [rootSuite];\n\n // Event callback (set from host)\n let eventCallback = null;\n\n function emitEvent(event) {\n if (eventCallback) {\n try {\n eventCallback(JSON.stringify(event));\n } catch (e) {\n // Ignore callback errors\n }\n }\n }\n\n // ============================================================\n // TestError class for rich error info\n // ============================================================\n\n class TestError extends Error {\n constructor(message, matcherName, expected, actual) {\n super(message);\n this.name = 'TestError';\n this.matcherName = matcherName;\n this.expected = expected;\n this.actual = actual;\n }\n }\n\n // ============================================================\n // Deep Equality Helper\n // ============================================================\n\n function deepEqual(a, b) {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (typeof a !== 'object' || a === null || b === null) return false;\n\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false;\n if (!deepEqual(a[key], b[key])) return false;\n }\n return true;\n }\n\n function strictDeepEqual(a, b) {\n if (a === b) return true;\n if (typeof a !== typeof b) return false;\n if (typeof a !== 'object' || a === null || b === null) return false;\n\n // Check prototypes\n if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) return false;\n\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n // For arrays, check sparse arrays (holes)\n if (Array.isArray(a)) {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const aHasIndex = i in a;\n const bHasIndex = i in b;\n if (aHasIndex !== bHasIndex) return false;\n if (aHasIndex && !strictDeepEqual(a[i], b[i])) return false;\n }\n return true;\n }\n\n // Check for undefined properties vs missing properties\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false;\n if (!strictDeepEqual(a[key], b[key])) return false;\n }\n\n // Check for symbol properties\n const symbolsA = Object.getOwnPropertySymbols(a);\n const symbolsB = Object.getOwnPropertySymbols(b);\n if (symbolsA.length !== symbolsB.length) return false;\n\n for (const sym of symbolsA) {\n if (!symbolsB.includes(sym)) return false;\n if (!strictDeepEqual(a[sym], b[sym])) return false;\n }\n\n return true;\n }\n\n function getNestedProperty(obj, path) {\n const parts = path.split('.');\n let current = obj;\n for (const part of parts) {\n if (current == null || !(part in current)) {\n return { exists: false };\n }\n current = current[part];\n }\n return { exists: true, value: current };\n }\n\n function formatValue(val) {\n if (val === null) return 'null';\n if (val === undefined) return 'undefined';\n if (typeof val === 'string') return JSON.stringify(val);\n if (typeof val === 'object') {\n try {\n return JSON.stringify(val);\n } catch {\n return String(val);\n }\n }\n return String(val);\n }\n\n // ============================================================\n // expect() Implementation\n // ============================================================\n\n function expect(actual) {\n function createMatchers(negated = false) {\n const assert = (condition, message, matcherName, expected) => {\n const pass = negated ? !condition : condition;\n if (!pass) {\n throw new TestError(message, matcherName, expected, actual);\n }\n };\n\n const matchers = {\n toBe(expected) {\n assert(\n actual === expected,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to be \\${formatValue(expected)}\\`,\n 'toBe',\n expected\n );\n },\n\n toEqual(expected) {\n assert(\n deepEqual(actual, expected),\n negated\n ? \\`Expected \\${formatValue(actual)} not to equal \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to equal \\${formatValue(expected)}\\`,\n 'toEqual',\n expected\n );\n },\n\n toStrictEqual(expected) {\n assert(\n strictDeepEqual(actual, expected),\n negated\n ? \\`Expected \\${formatValue(actual)} not to strictly equal \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to strictly equal \\${formatValue(expected)}\\`,\n 'toStrictEqual',\n expected\n );\n },\n\n toBeTruthy() {\n assert(\n !!actual,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be truthy\\`\n : \\`Expected \\${formatValue(actual)} to be truthy\\`,\n 'toBeTruthy',\n true\n );\n },\n\n toBeFalsy() {\n assert(\n !actual,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be falsy\\`\n : \\`Expected \\${formatValue(actual)} to be falsy\\`,\n 'toBeFalsy',\n false\n );\n },\n\n toBeNull() {\n assert(\n actual === null,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be null\\`\n : \\`Expected \\${formatValue(actual)} to be null\\`,\n 'toBeNull',\n null\n );\n },\n\n toBeUndefined() {\n assert(\n actual === undefined,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be undefined\\`\n : \\`Expected \\${formatValue(actual)} to be undefined\\`,\n 'toBeUndefined',\n undefined\n );\n },\n\n toBeDefined() {\n assert(\n actual !== undefined,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be defined\\`\n : \\`Expected \\${formatValue(actual)} to be defined\\`,\n 'toBeDefined',\n 'defined'\n );\n },\n\n toContain(item) {\n let contains = false;\n if (Array.isArray(actual)) {\n contains = actual.includes(item);\n } else if (typeof actual === 'string') {\n contains = actual.includes(item);\n }\n assert(\n contains,\n negated\n ? \\`Expected \\${formatValue(actual)} not to contain \\${formatValue(item)}\\`\n : \\`Expected \\${formatValue(actual)} to contain \\${formatValue(item)}\\`,\n 'toContain',\n item\n );\n },\n\n toThrow(expected) {\n if (typeof actual !== 'function') {\n throw new Error('toThrow requires a function');\n }\n\n let threw = false;\n let error = null;\n try {\n actual();\n } catch (e) {\n threw = true;\n error = e;\n }\n\n if (expected !== undefined) {\n const matches = threw && (\n (typeof expected === 'string' && error.message.includes(expected)) ||\n (expected instanceof RegExp && expected.test(error.message)) ||\n (typeof expected === 'function' && error instanceof expected)\n );\n assert(\n matches,\n negated\n ? \\`Expected function not to throw \\${formatValue(expected)}\\`\n : \\`Expected function to throw \\${formatValue(expected)}, but \\${threw ? \\`threw: \\${error.message}\\` : 'did not throw'}\\`,\n 'toThrow',\n expected\n );\n } else {\n assert(\n threw,\n negated\n ? \\`Expected function not to throw\\`\n : \\`Expected function to throw\\`,\n 'toThrow',\n 'any error'\n );\n }\n },\n\n toBeInstanceOf(cls) {\n assert(\n actual instanceof cls,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be instance of \\${cls.name || cls}\\`\n : \\`Expected \\${formatValue(actual)} to be instance of \\${cls.name || cls}\\`,\n 'toBeInstanceOf',\n cls.name || cls\n );\n },\n\n toHaveLength(length) {\n const actualLength = actual?.length;\n assert(\n actualLength === length,\n negated\n ? \\`Expected length not to be \\${length}, but got \\${actualLength}\\`\n : \\`Expected length to be \\${length}, but got \\${actualLength}\\`,\n 'toHaveLength',\n length\n );\n },\n\n toMatch(pattern) {\n let matches = false;\n if (typeof pattern === 'string') {\n matches = actual.includes(pattern);\n } else if (pattern instanceof RegExp) {\n matches = pattern.test(actual);\n }\n assert(\n matches,\n negated\n ? \\`Expected \\${formatValue(actual)} not to match \\${pattern}\\`\n : \\`Expected \\${formatValue(actual)} to match \\${pattern}\\`,\n 'toMatch',\n pattern\n );\n },\n\n toHaveProperty(path, value) {\n const prop = getNestedProperty(actual, path);\n const hasProperty = prop.exists;\n const valueMatches = arguments.length < 2 || deepEqual(prop.value, value);\n\n assert(\n hasProperty && valueMatches,\n negated\n ? \\`Expected \\${formatValue(actual)} not to have property \\${path}\\${arguments.length >= 2 ? \\` with value \\${formatValue(value)}\\` : ''}\\`\n : \\`Expected \\${formatValue(actual)} to have property \\${path}\\${arguments.length >= 2 ? \\` with value \\${formatValue(value)}\\` : ''}\\`,\n 'toHaveProperty',\n arguments.length >= 2 ? { path, value } : { path }\n );\n },\n\n toBeGreaterThan(expected) {\n assert(\n actual > expected,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be greater than \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to be greater than \\${formatValue(expected)}\\`,\n 'toBeGreaterThan',\n expected\n );\n },\n\n toBeGreaterThanOrEqual(expected) {\n assert(\n actual >= expected,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be greater than or equal to \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to be greater than or equal to \\${formatValue(expected)}\\`,\n 'toBeGreaterThanOrEqual',\n expected\n );\n },\n\n toBeLessThan(expected) {\n assert(\n actual < expected,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be less than \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to be less than \\${formatValue(expected)}\\`,\n 'toBeLessThan',\n expected\n );\n },\n\n toBeLessThanOrEqual(expected) {\n assert(\n actual <= expected,\n negated\n ? \\`Expected \\${formatValue(actual)} not to be less than or equal to \\${formatValue(expected)}\\`\n : \\`Expected \\${formatValue(actual)} to be less than or equal to \\${formatValue(expected)}\\`,\n 'toBeLessThanOrEqual',\n expected\n );\n },\n };\n\n return matchers;\n }\n\n const matchers = createMatchers(false);\n matchers.not = createMatchers(true);\n\n return matchers;\n }\n\n // ============================================================\n // Test Registration Functions\n // ============================================================\n\n function describe(name, fn) {\n const suite = createSuite(name);\n currentSuite.children.push(suite);\n\n const parentSuite = currentSuite;\n currentSuite = suite;\n suiteStack.push(suite);\n\n fn();\n\n suiteStack.pop();\n currentSuite = parentSuite;\n }\n\n describe.skip = function(name, fn) {\n const suite = createSuite(name, true, false);\n currentSuite.children.push(suite);\n\n const parentSuite = currentSuite;\n currentSuite = suite;\n suiteStack.push(suite);\n\n fn();\n\n suiteStack.pop();\n currentSuite = parentSuite;\n };\n\n describe.only = function(name, fn) {\n const suite = createSuite(name, false, true);\n currentSuite.children.push(suite);\n\n const parentSuite = currentSuite;\n currentSuite = suite;\n suiteStack.push(suite);\n\n fn();\n\n suiteStack.pop();\n currentSuite = parentSuite;\n };\n\n function test(name, fn) {\n currentSuite.tests.push({\n name,\n fn,\n skip: false,\n only: false,\n });\n }\n\n test.skip = function(name, fn) {\n currentSuite.tests.push({\n name,\n fn,\n skip: true,\n only: false,\n });\n };\n\n test.only = function(name, fn) {\n currentSuite.tests.push({\n name,\n fn,\n skip: false,\n only: true,\n });\n };\n\n test.todo = function(name) {\n currentSuite.tests.push({\n name,\n fn: null,\n skip: false,\n only: false,\n todo: true,\n });\n };\n\n const it = test;\n it.skip = test.skip;\n it.only = test.only;\n it.todo = test.todo;\n\n // ============================================================\n // Lifecycle Hooks\n // ============================================================\n\n function beforeEach(fn) {\n currentSuite.beforeEach.push(fn);\n }\n\n function afterEach(fn) {\n currentSuite.afterEach.push(fn);\n }\n\n function beforeAll(fn) {\n currentSuite.beforeAll.push(fn);\n }\n\n function afterAll(fn) {\n currentSuite.afterAll.push(fn);\n }\n\n // ============================================================\n // Test Runner Helpers\n // ============================================================\n\n function checkForOnly(suite) {\n if (suite.only) return true;\n for (const t of suite.tests) {\n if (t.only) return true;\n }\n for (const child of suite.children) {\n if (checkForOnly(child)) return true;\n }\n return false;\n }\n\n function suiteHasOnly(suite) {\n if (suite.only) return true;\n for (const t of suite.tests) {\n if (t.only) return true;\n }\n for (const child of suite.children) {\n if (suiteHasOnly(child)) return true;\n }\n return false;\n }\n\n function countTests(suite, hasOnly) {\n let count = 0;\n if (hasOnly && !suiteHasOnly(suite)) return 0;\n if (suite.skip) return suite.tests.length;\n\n for (const t of suite.tests) {\n if (hasOnly && !t.only && !suite.only) continue;\n count++;\n }\n for (const child of suite.children) {\n count += countTests(child, hasOnly);\n }\n return count;\n }\n\n function countSuites(suite, hasOnly) {\n let count = 0;\n if (hasOnly && !suiteHasOnly(suite)) return 0;\n\n for (const child of suite.children) {\n count++;\n count += countSuites(child, hasOnly);\n }\n return count;\n }\n\n // ============================================================\n // Test Runner\n // ============================================================\n\n async function __runAllTests() {\n const testResults = [];\n const suiteResults = [];\n const hasOnly = checkForOnly(rootSuite);\n const runStart = Date.now();\n\n // Emit runStart\n const testCount = countTests(rootSuite, hasOnly);\n const suiteCount = countSuites(rootSuite, hasOnly);\n emitEvent({ type: 'runStart', testCount, suiteCount });\n\n async function runSuite(suite, parentHooks, pathArray, depth) {\n // Skip if this suite doesn't have any .only when .only exists elsewhere\n if (hasOnly && !suiteHasOnly(suite)) return;\n\n const suitePath = [...pathArray];\n const fullName = suitePath.join(' > ');\n const suiteInfo = {\n name: suite.name,\n path: suitePath.slice(0, -1),\n fullName,\n depth,\n };\n\n // Emit suiteStart (only for non-root suites)\n if (suite !== rootSuite) {\n emitEvent({ type: 'suiteStart', suite: suiteInfo });\n }\n\n const suiteStart = Date.now();\n let suitePassed = 0;\n let suiteFailed = 0;\n let suiteSkipped = 0;\n let suiteTodo = 0;\n\n // Skip if suite is marked as skip\n if (suite.skip) {\n // Mark all tests in this suite as skipped\n for (const t of suite.tests) {\n const testFullName = fullName ? fullName + ' > ' + t.name : t.name;\n const testInfo = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n };\n emitEvent({ type: 'testStart', test: testInfo });\n\n const testResult = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n status: 'skip',\n duration: 0,\n };\n testResults.push(testResult);\n suiteSkipped++;\n\n emitEvent({ type: 'testEnd', test: testResult });\n }\n } else {\n // Run beforeAll hooks\n for (const hook of suite.beforeAll) {\n await hook();\n }\n\n // Run tests\n for (const t of suite.tests) {\n const testFullName = fullName ? fullName + ' > ' + t.name : t.name;\n const testInfo = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n };\n\n // Skip if .only is used and this test isn't .only AND the suite doesn't have .only\n if (hasOnly && !t.only && !suite.only) continue;\n\n emitEvent({ type: 'testStart', test: testInfo });\n\n // Skip if test is marked as skip\n if (t.skip) {\n const testResult = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n status: 'skip',\n duration: 0,\n };\n testResults.push(testResult);\n suiteSkipped++;\n emitEvent({ type: 'testEnd', test: testResult });\n continue;\n }\n\n // Handle todo tests (no function provided)\n if (t.todo) {\n const testResult = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n status: 'todo',\n duration: 0,\n };\n testResults.push(testResult);\n suiteTodo++;\n emitEvent({ type: 'testEnd', test: testResult });\n continue;\n }\n\n const testStart = Date.now();\n try {\n // Run all beforeEach hooks (parent first, then current)\n for (const hook of [...parentHooks.beforeEach, ...suite.beforeEach]) {\n await hook();\n }\n\n // Run test\n await t.fn();\n\n // Run all afterEach hooks (current first, then parent)\n for (const hook of [...suite.afterEach, ...parentHooks.afterEach]) {\n await hook();\n }\n\n const testResult = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n status: 'pass',\n duration: Date.now() - testStart,\n };\n testResults.push(testResult);\n suitePassed++;\n emitEvent({ type: 'testEnd', test: testResult });\n } catch (err) {\n const testError = {\n message: err.message || String(err),\n stack: err.stack,\n };\n // If it's a TestError, include matcher info\n if (err.matcherName !== undefined) {\n testError.matcherName = err.matcherName;\n testError.expected = err.expected;\n testError.actual = err.actual;\n }\n const testResult = {\n name: t.name,\n suitePath: suitePath,\n fullName: testFullName,\n status: 'fail',\n duration: Date.now() - testStart,\n error: testError,\n };\n testResults.push(testResult);\n suiteFailed++;\n emitEvent({ type: 'testEnd', test: testResult });\n }\n }\n\n // Run child suites\n for (const child of suite.children) {\n const childPath = [...suitePath, child.name];\n await runSuite(child, {\n beforeEach: [...parentHooks.beforeEach, ...suite.beforeEach],\n afterEach: [...suite.afterEach, ...parentHooks.afterEach],\n }, childPath, depth + 1);\n }\n\n // Run afterAll hooks\n for (const hook of suite.afterAll) {\n await hook();\n }\n }\n\n // Emit suiteEnd (only for non-root suites)\n if (suite !== rootSuite) {\n const suiteResult = {\n ...suiteInfo,\n passed: suitePassed,\n failed: suiteFailed,\n skipped: suiteSkipped,\n todo: suiteTodo,\n duration: Date.now() - suiteStart,\n };\n suiteResults.push(suiteResult);\n emitEvent({ type: 'suiteEnd', suite: suiteResult });\n }\n }\n\n await runSuite(rootSuite, { beforeEach: [], afterEach: [] }, [], -1);\n\n const passed = testResults.filter(r => r.status === 'pass').length;\n const failed = testResults.filter(r => r.status === 'fail').length;\n const skipped = testResults.filter(r => r.status === 'skip').length;\n const todo = testResults.filter(r => r.status === 'todo').length;\n\n const runResults = {\n passed,\n failed,\n skipped,\n todo,\n total: testResults.length,\n duration: Date.now() - runStart,\n success: failed === 0,\n suites: suiteResults,\n tests: testResults,\n };\n\n emitEvent({ type: 'runEnd', results: runResults });\n\n return JSON.stringify(runResults);\n }\n\n // ============================================================\n // Helper Functions\n // ============================================================\n\n function __hasTests() {\n function checkSuite(suite) {\n if (suite.tests.length > 0) return true;\n for (const child of suite.children) {\n if (checkSuite(child)) return true;\n }\n return false;\n }\n return checkSuite(rootSuite);\n }\n\n function __getTestCount() {\n function countInSuite(suite) {\n let count = suite.tests.length;\n for (const child of suite.children) {\n count += countInSuite(child);\n }\n return count;\n }\n return countInSuite(rootSuite);\n }\n\n // Reset function to clear state between runs\n function __resetTestEnvironment() {\n rootSuite.tests = [];\n rootSuite.children = [];\n rootSuite.beforeAll = [];\n rootSuite.afterAll = [];\n rootSuite.beforeEach = [];\n rootSuite.afterEach = [];\n currentSuite = rootSuite;\n suiteStack.length = 0;\n suiteStack.push(rootSuite);\n }\n\n function __setEventCallback(callback) {\n eventCallback = callback;\n }\n\n // ============================================================\n // Expose Globals\n // ============================================================\n\n globalThis.describe = describe;\n globalThis.test = test;\n globalThis.it = it;\n globalThis.expect = expect;\n globalThis.beforeEach = beforeEach;\n globalThis.afterEach = afterEach;\n globalThis.beforeAll = beforeAll;\n globalThis.afterAll = afterAll;\n globalThis.__runAllTests = __runAllTests;\n globalThis.__resetTestEnvironment = __resetTestEnvironment;\n globalThis.__hasTests = __hasTests;\n globalThis.__getTestCount = __getTestCount;\n globalThis.__setEventCallback = __setEventCallback;\n})();\n`;\n\n/**\n * Setup test environment primitives in an isolated-vm context\n *\n * Provides Jest/Vitest-compatible test primitives:\n * - describe, test, it\n * - beforeEach, afterEach, beforeAll, afterAll\n * - expect matchers\n *\n * @example\n * const handle = await setupTestEnvironment(context, {\n * onEvent: (event) => console.log(event),\n * });\n *\n * await context.eval(`\n * describe(\"my tests\", () => {\n * test(\"example\", () => {\n * expect(1 + 1).toBe(2);\n * });\n * });\n * `);\n */\nexport async function setupTestEnvironment(\n context: ivm.Context,\n options?: TestEnvironmentOptions\n): Promise<TestEnvironmentHandle> {\n context.evalSync(testEnvironmentCode);\n\n // Set up event callback if provided\n if (options?.onEvent) {\n const eventCallbackRef = new IsolatedVM.Reference((eventJson: string) => {\n try {\n const event = JSON.parse(eventJson);\n options.onEvent!(event);\n } catch {\n // Ignore parse errors\n }\n });\n\n const global = context.global;\n global.setSync(\"__eventCallbackRef\", eventCallbackRef);\n context.evalSync(`\n __setEventCallback((eventJson) => {\n __eventCallbackRef.applySync(undefined, [eventJson]);\n });\n `);\n }\n\n return {\n dispose() {\n // Reset the test environment state\n try {\n context.evalSync(\"__resetTestEnvironment()\");\n } catch {\n // Context may already be released\n }\n },\n };\n}\n\n/**\n * Run tests in the context and return results\n */\nexport async function runTests(context: ivm.Context): Promise<RunResults> {\n const resultJson = await context.eval(\"__runAllTests()\", { promise: true });\n return JSON.parse(resultJson as string);\n}\n\n/**\n * Check if any tests are registered\n */\nexport function hasTests(context: ivm.Context): boolean {\n return context.evalSync(\"__hasTests()\") as boolean;\n}\n\n/**\n * Get the count of registered tests\n */\nexport function getTestCount(context: ivm.Context): number {\n return context.evalSync(\"__getTestCount()\") as number;\n}\n"
6
6
  ],
7
- "mappings": ";;AACA;AAmGA,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAy2B5B,eAAsB,oBAAoB,CACxC,SACA,SACgC;AAAA,EAChC,QAAQ,SAAS,mBAAmB;AAAA,EAGpC,IAAI,SAAS,SAAS;AAAA,IACpB,MAAM,mBAAmB,IAAI,WAAW,UAAU,CAAC,cAAsB;AAAA,MACvE,IAAI;AAAA,QACF,MAAM,QAAQ,KAAK,MAAM,SAAS;AAAA,QAClC,QAAQ,QAAS,KAAK;AAAA,QACtB,MAAM;AAAA,KAGT;AAAA,IAED,MAAM,SAAS,QAAQ;AAAA,IACvB,OAAO,QAAQ,sBAAsB,gBAAgB;AAAA,IACrD,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,KAIhB;AAAA,EACH;AAAA,EAEA,OAAO;AAAA,IACL,OAAO,GAAG;AAAA,MAER,IAAI;AAAA,QACF,QAAQ,SAAS,0BAA0B;AAAA,QAC3C,MAAM;AAAA;AAAA,EAIZ;AAAA;AAMF,eAAsB,QAAQ,CAAC,SAA2C;AAAA,EACxE,MAAM,aAAa,MAAM,QAAQ,KAAK,mBAAmB,EAAE,SAAS,KAAK,CAAC;AAAA,EAC1E,OAAO,KAAK,MAAM,UAAoB;AAAA;AAMjC,SAAS,QAAQ,CAAC,SAA+B;AAAA,EACtD,OAAO,QAAQ,SAAS,cAAc;AAAA;AAMjC,SAAS,YAAY,CAAC,SAA8B;AAAA,EACzD,OAAO,QAAQ,SAAS,kBAAkB;AAAA;",
8
- "debugId": "E1ED7CC917A46E0364756E2164756E21",
7
+ "mappings": ";AACA;AAmGA,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAy2B5B,eAAsB,oBAAoB,CACxC,SACA,SACgC;AAAA,EAChC,QAAQ,SAAS,mBAAmB;AAAA,EAGpC,IAAI,SAAS,SAAS;AAAA,IACpB,MAAM,mBAAmB,IAAI,WAAW,UAAU,CAAC,cAAsB;AAAA,MACvE,IAAI;AAAA,QACF,MAAM,QAAQ,KAAK,MAAM,SAAS;AAAA,QAClC,QAAQ,QAAS,KAAK;AAAA,QACtB,MAAM;AAAA,KAGT;AAAA,IAED,MAAM,SAAS,QAAQ;AAAA,IACvB,OAAO,QAAQ,sBAAsB,gBAAgB;AAAA,IACrD,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,KAIhB;AAAA,EACH;AAAA,EAEA,OAAO;AAAA,IACL,OAAO,GAAG;AAAA,MAER,IAAI;AAAA,QACF,QAAQ,SAAS,0BAA0B;AAAA,QAC3C,MAAM;AAAA;AAAA,EAIZ;AAAA;AAMF,eAAsB,QAAQ,CAAC,SAA2C;AAAA,EACxE,MAAM,aAAa,MAAM,QAAQ,KAAK,mBAAmB,EAAE,SAAS,KAAK,CAAC;AAAA,EAC1E,OAAO,KAAK,MAAM,UAAoB;AAAA;AAMjC,SAAS,QAAQ,CAAC,SAA+B;AAAA,EACtD,OAAO,QAAQ,SAAS,cAAc;AAAA;AAMjC,SAAS,YAAY,CAAC,SAA8B;AAAA,EACzD,OAAO,QAAQ,SAAS,kBAAkB;AAAA;",
8
+ "debugId": "E073089EDACCEE1764756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/isolate-test-environment",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "type": "module"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ricsam/isolate-test-environment",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Test environment for isolated-vm with Jest/Vitest-compatible primitives",
5
5
  "main": "./dist/cjs/index.cjs",
6
6
  "types": "./dist/types/index.d.ts",