@ricsam/isolate 0.1.4 → 0.1.6
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.
- package/README.md +45 -2
- package/dist/cjs/internal/async-context/index.cjs +401 -0
- package/dist/cjs/internal/async-context/index.cjs.map +10 -0
- package/dist/cjs/internal/client/connection.cjs +175 -123
- package/dist/cjs/internal/client/connection.cjs.map +3 -3
- package/dist/cjs/internal/console/index.cjs +2 -2
- package/dist/cjs/internal/console/index.cjs.map +2 -2
- package/dist/cjs/internal/core/index.cjs +22 -6
- package/dist/cjs/internal/core/index.cjs.map +3 -3
- package/dist/cjs/internal/crypto/index.cjs +2 -2
- package/dist/cjs/internal/crypto/index.cjs.map +2 -2
- package/dist/cjs/internal/daemon/connection.cjs +77 -12
- package/dist/cjs/internal/daemon/connection.cjs.map +3 -3
- package/dist/cjs/internal/encoding/index.cjs.map +1 -1
- package/dist/cjs/internal/fetch/index.cjs +119 -18
- package/dist/cjs/internal/fetch/index.cjs.map +3 -3
- package/dist/cjs/internal/fetch/stream-state.cjs.map +1 -1
- package/dist/cjs/internal/fs/index.cjs +2 -2
- package/dist/cjs/internal/fs/index.cjs.map +2 -2
- package/dist/cjs/internal/module-loader/bundle.cjs +277 -1
- package/dist/cjs/internal/module-loader/bundle.cjs.map +3 -3
- package/dist/cjs/internal/path/index.cjs.map +1 -1
- package/dist/cjs/internal/playwright/index.cjs +2 -2
- package/dist/cjs/internal/playwright/index.cjs.map +2 -2
- package/dist/cjs/internal/runtime/index.cjs +78 -6
- package/dist/cjs/internal/runtime/index.cjs.map +3 -3
- package/dist/cjs/internal/test-environment/index.cjs +2 -2
- package/dist/cjs/internal/test-environment/index.cjs.map +2 -2
- package/dist/cjs/internal/timers/index.cjs +42 -7
- package/dist/cjs/internal/timers/index.cjs.map +3 -3
- package/dist/cjs/internal/typecheck/isolate-types.cjs +36 -1
- package/dist/cjs/internal/typecheck/isolate-types.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/internal/async-context/index.mjs +361 -0
- package/dist/mjs/internal/async-context/index.mjs.map +10 -0
- package/dist/mjs/internal/client/connection.mjs +176 -123
- package/dist/mjs/internal/client/connection.mjs.map +3 -3
- package/dist/mjs/internal/console/index.mjs +2 -2
- package/dist/mjs/internal/console/index.mjs.map +2 -2
- package/dist/mjs/internal/core/index.mjs +22 -6
- package/dist/mjs/internal/core/index.mjs.map +3 -3
- package/dist/mjs/internal/crypto/index.mjs +2 -2
- package/dist/mjs/internal/crypto/index.mjs.map +2 -2
- package/dist/mjs/internal/daemon/connection.mjs +77 -12
- package/dist/mjs/internal/daemon/connection.mjs.map +3 -3
- package/dist/mjs/internal/encoding/index.mjs.map +1 -1
- package/dist/mjs/internal/fetch/index.mjs +119 -18
- package/dist/mjs/internal/fetch/index.mjs.map +3 -3
- package/dist/mjs/internal/fetch/stream-state.mjs.map +1 -1
- package/dist/mjs/internal/fs/index.mjs +2 -2
- package/dist/mjs/internal/fs/index.mjs.map +2 -2
- package/dist/mjs/internal/module-loader/bundle.mjs +277 -1
- package/dist/mjs/internal/module-loader/bundle.mjs.map +3 -3
- package/dist/mjs/internal/path/index.mjs.map +1 -1
- package/dist/mjs/internal/playwright/index.mjs +2 -2
- package/dist/mjs/internal/playwright/index.mjs.map +2 -2
- package/dist/mjs/internal/runtime/index.mjs +78 -6
- package/dist/mjs/internal/runtime/index.mjs.map +3 -3
- package/dist/mjs/internal/test-environment/index.mjs +2 -2
- package/dist/mjs/internal/test-environment/index.mjs.map +2 -2
- package/dist/mjs/internal/timers/index.mjs +42 -7
- package/dist/mjs/internal/timers/index.mjs.map +3 -3
- package/dist/mjs/internal/typecheck/isolate-types.mjs +36 -1
- package/dist/mjs/internal/typecheck/isolate-types.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/internal/async-context/index.d.ts +5 -0
- package/dist/types/internal/console/index.d.ts +1 -1
- package/dist/types/internal/core/index.d.ts +2 -2
- package/dist/types/internal/crypto/index.d.ts +1 -1
- package/dist/types/internal/daemon/types.d.ts +1 -0
- package/dist/types/internal/encoding/index.d.ts +1 -1
- package/dist/types/internal/fetch/index.d.ts +1 -1
- package/dist/types/internal/fetch/stream-state.d.ts +1 -1
- package/dist/types/internal/fs/index.d.ts +1 -1
- package/dist/types/internal/path/index.d.ts +1 -1
- package/dist/types/internal/playwright/index.d.ts +1 -1
- package/dist/types/internal/test-environment/index.d.ts +1 -1
- package/dist/types/internal/timers/index.d.ts +1 -1
- package/dist/types/internal/typecheck/isolate-types.d.ts +2 -2
- package/package.json +8 -3
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/internal/encoding/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type ivm from \"isolated-vm\";\n\nexport interface EncodingHandle {\n dispose(): void;\n}\n\nconst encodingCode = `\n(function() {\n // Define DOMException if not available\n if (typeof DOMException === 'undefined') {\n globalThis.DOMException = class DOMException extends Error {\n constructor(message, name) {\n super(message);\n this.name = name || 'DOMException';\n }\n };\n }\n\n const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n // Build reverse lookup table\n const base64Lookup = new Map();\n for (let i = 0; i < base64Chars.length; i++) {\n base64Lookup.set(base64Chars[i], i);\n }\n\n globalThis.btoa = function btoa(str) {\n if (str === undefined) {\n throw new TypeError(\"1 argument required, but only 0 present.\");\n }\n\n str = String(str);\n\n // Check for characters outside Latin-1 range\n for (let i = 0; i < str.length; i++) {\n if (str.charCodeAt(i) > 255) {\n throw new DOMException(\n \"The string to be encoded contains characters outside of the Latin1 range.\",\n \"InvalidCharacterError\"\n );\n }\n }\n\n if (str.length === 0) {\n return '';\n }\n\n let result = '';\n let i = 0;\n\n while (i < str.length) {\n const a = str.charCodeAt(i++);\n const bExists = i < str.length;\n const b = bExists ? str.charCodeAt(i++) : 0;\n const cExists = i < str.length;\n const c = cExists ? str.charCodeAt(i++) : 0;\n\n const triplet = (a << 16) | (b << 8) | c;\n\n result += base64Chars[(triplet >> 18) & 0x3F];\n result += base64Chars[(triplet >> 12) & 0x3F];\n result += bExists ? base64Chars[(triplet >> 6) & 0x3F] : '=';\n result += cExists ? base64Chars[triplet & 0x3F] : '=';\n }\n\n return result;\n };\n\n globalThis.atob = function atob(str) {\n if (str === undefined) {\n throw new TypeError(\"1 argument required, but only 0 present.\");\n }\n\n str = String(str);\n\n // Remove whitespace\n str = str.replace(/[\\\\t\\\\n\\\\f\\\\r ]/g, '');\n\n // Validate characters and length\n if (str.length === 0) {\n return '';\n }\n\n // Check for invalid characters (before padding normalization)\n for (let i = 0; i < str.length; i++) {\n const c = str[i];\n if (c !== '=' && !base64Lookup.has(c)) {\n throw new DOMException(\n \"The string to be decoded is not correctly encoded.\",\n \"InvalidCharacterError\"\n );\n }\n }\n\n // Validate padding position (must be at end)\n const paddingIndex = str.indexOf('=');\n if (paddingIndex !== -1) {\n for (let i = paddingIndex; i < str.length; i++) {\n if (str[i] !== '=') {\n throw new DOMException(\n \"The string to be decoded is not correctly encoded.\",\n \"InvalidCharacterError\"\n );\n }\n }\n const paddingLength = str.length - paddingIndex;\n if (paddingLength > 2) {\n throw new DOMException(\n \"The string to be decoded is not correctly encoded.\",\n \"InvalidCharacterError\"\n );\n }\n }\n\n // Length without padding must be valid (can't have remainder of 1)\n const strWithoutPadding = str.replace(/=/g, '');\n if (strWithoutPadding.length % 4 === 1) {\n throw new DOMException(\n \"The string to be decoded is not correctly encoded.\",\n \"InvalidCharacterError\"\n );\n }\n\n // Pad to multiple of 4 if needed (for inputs without explicit padding)\n while (str.length % 4 !== 0) {\n str += '=';\n }\n\n let result = '';\n let i = 0;\n\n while (i < str.length) {\n const a = base64Lookup.get(str[i++]) ?? 0;\n const b = base64Lookup.get(str[i++]) ?? 0;\n const c = base64Lookup.get(str[i++]) ?? 0;\n const d = base64Lookup.get(str[i++]) ?? 0;\n\n const triplet = (a << 18) | (b << 12) | (c << 6) | d;\n\n result += String.fromCharCode((triplet >> 16) & 0xFF);\n if (str[i - 2] !== '=') {\n result += String.fromCharCode((triplet >> 8) & 0xFF);\n }\n if (str[i - 1] !== '=') {\n result += String.fromCharCode(triplet & 0xFF);\n }\n }\n\n return result;\n };\n\n // ============================================\n // Buffer implementation\n // ============================================\n\n const BUFFER_SYMBOL = Symbol.for('__isBuffer');\n\n class Buffer extends Uint8Array {\n constructor(arg, encodingOrOffset, length) {\n if (typeof arg === 'number') {\n super(arg);\n } else if (typeof arg === 'string') {\n const bytes = stringToBytes(arg, encodingOrOffset || 'utf8');\n super(bytes);\n } else if (arg instanceof ArrayBuffer) {\n if (typeof encodingOrOffset === 'number') {\n super(arg, encodingOrOffset, length);\n } else {\n super(arg);\n }\n } else if (ArrayBuffer.isView(arg)) {\n super(arg.buffer, arg.byteOffset, arg.byteLength);\n } else if (Array.isArray(arg)) {\n super(arg);\n } else {\n super(arg);\n }\n Object.defineProperty(this, BUFFER_SYMBOL, { value: true, writable: false });\n }\n\n toString(encoding = 'utf8') {\n encoding = normalizeEncoding(encoding);\n if (encoding === 'utf8') {\n return new TextDecoder('utf-8').decode(this);\n } else if (encoding === 'base64') {\n return bytesToBase64(this);\n } else if (encoding === 'hex') {\n return bytesToHex(this);\n }\n return new TextDecoder('utf-8').decode(this);\n }\n\n slice(start, end) {\n const sliced = super.slice(start, end);\n return Buffer.from(sliced);\n }\n\n subarray(start, end) {\n const sub = super.subarray(start, end);\n const buf = new Buffer(sub.length);\n buf.set(sub);\n return buf;\n }\n\n static from(value, encodingOrOffset, length) {\n if (typeof value === 'string') {\n return new Buffer(value, encodingOrOffset);\n }\n if (value instanceof ArrayBuffer) {\n if (typeof encodingOrOffset === 'number') {\n return new Buffer(value, encodingOrOffset, length);\n }\n return new Buffer(value);\n }\n if (ArrayBuffer.isView(value)) {\n return new Buffer(value);\n }\n if (Array.isArray(value)) {\n return new Buffer(value);\n }\n if (value && typeof value[Symbol.iterator] === 'function') {\n return new Buffer(Array.from(value));\n }\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object');\n }\n\n static alloc(size, fill, encoding) {\n if (typeof size !== 'number' || size < 0) {\n throw new RangeError('Invalid size');\n }\n const buf = new Buffer(size);\n if (fill !== undefined) {\n if (typeof fill === 'number') {\n buf.fill(fill);\n } else if (typeof fill === 'string') {\n const fillBytes = stringToBytes(fill, encoding || 'utf8');\n for (let i = 0; i < size; i++) {\n buf[i] = fillBytes[i % fillBytes.length];\n }\n } else if (Buffer.isBuffer(fill) || fill instanceof Uint8Array) {\n for (let i = 0; i < size; i++) {\n buf[i] = fill[i % fill.length];\n }\n }\n }\n return buf;\n }\n\n static allocUnsafe(size) {\n if (typeof size !== 'number' || size < 0) {\n throw new RangeError('Invalid size');\n }\n return new Buffer(size);\n }\n\n static concat(list, totalLength) {\n if (!Array.isArray(list)) {\n throw new TypeError('list argument must be an array');\n }\n if (list.length === 0) {\n return Buffer.alloc(0);\n }\n if (totalLength === undefined) {\n totalLength = 0;\n for (const buf of list) {\n totalLength += buf.length;\n }\n }\n const result = Buffer.alloc(totalLength);\n let offset = 0;\n for (const buf of list) {\n if (offset + buf.length > totalLength) {\n result.set(buf.subarray(0, totalLength - offset), offset);\n break;\n }\n result.set(buf, offset);\n offset += buf.length;\n }\n return result;\n }\n\n static isBuffer(obj) {\n return obj != null && obj[BUFFER_SYMBOL] === true;\n }\n\n static byteLength(string, encoding = 'utf8') {\n if (typeof string !== 'string') {\n if (ArrayBuffer.isView(string) || string instanceof ArrayBuffer) {\n return string.byteLength;\n }\n throw new TypeError('First argument must be a string, Buffer, or ArrayBuffer');\n }\n encoding = normalizeEncoding(encoding);\n if (encoding === 'utf8') {\n return new TextEncoder().encode(string).length;\n } else if (encoding === 'base64') {\n const padding = (string.match(/=+$/) || [''])[0].length;\n return Math.floor((string.length * 3) / 4) - padding;\n } else if (encoding === 'hex') {\n return Math.floor(string.length / 2);\n }\n return new TextEncoder().encode(string).length;\n }\n\n static isEncoding(encoding) {\n return ['utf8', 'utf-8', 'base64', 'hex'].includes(normalizeEncoding(encoding));\n }\n }\n\n function normalizeEncoding(encoding) {\n if (!encoding) return 'utf8';\n const lower = String(encoding).toLowerCase().replace('-', '');\n if (lower === 'utf8' || lower === 'utf-8') return 'utf8';\n if (lower === 'base64') return 'base64';\n if (lower === 'hex') return 'hex';\n return lower;\n }\n\n function stringToBytes(str, encoding) {\n encoding = normalizeEncoding(encoding);\n if (encoding === 'utf8') {\n return new TextEncoder().encode(str);\n } else if (encoding === 'base64') {\n return base64ToBytes(str);\n } else if (encoding === 'hex') {\n return hexToBytes(str);\n }\n return new TextEncoder().encode(str);\n }\n\n function base64ToBytes(str) {\n const binary = atob(str);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n\n function bytesToBase64(bytes) {\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n }\n\n function hexToBytes(str) {\n if (str.length % 2 !== 0) {\n throw new TypeError('Invalid hex string');\n }\n const bytes = new Uint8Array(str.length / 2);\n for (let i = 0; i < str.length; i += 2) {\n const byte = parseInt(str.substr(i, 2), 16);\n if (isNaN(byte)) {\n throw new TypeError('Invalid hex string');\n }\n bytes[i / 2] = byte;\n }\n return bytes;\n }\n\n function bytesToHex(bytes) {\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += bytes[i].toString(16).padStart(2, '0');\n }\n return hex;\n }\n\n globalThis.Buffer = Buffer;\n})();\n`;\n\n/**\n * Setup encoding APIs in an isolated-vm context\n *\n * Injects:\n * - atob/btoa for Base64 encoding/decoding\n * - Buffer class for binary data handling (utf8, base64, hex)\n *\n * @example\n * const handle = await setupEncoding(context);\n * await context.eval(`\n * const encoded = btoa(\"hello\");\n * const decoded = atob(encoded);\n * const buf = Buffer.from(\"hello\");\n * const hex = buf.toString(\"hex\");\n * `);\n */\nexport async function setupEncoding(\n context: ivm.Context\n): Promise<EncodingHandle> {\n context.evalSync(encodingCode);\n return {\n dispose() {\n // No resources to cleanup for pure JS injection\n },\n };\n}\n"
|
|
5
|
+
"import type ivm from \"@ricsam/isolated-vm\";\n\nexport interface EncodingHandle {\n dispose(): void;\n}\n\nconst encodingCode = `\n(function() {\n // Define DOMException if not available\n if (typeof DOMException === 'undefined') {\n globalThis.DOMException = class DOMException extends Error {\n constructor(message, name) {\n super(message);\n this.name = name || 'DOMException';\n }\n };\n }\n\n const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\n\n // Build reverse lookup table\n const base64Lookup = new Map();\n for (let i = 0; i < base64Chars.length; i++) {\n base64Lookup.set(base64Chars[i], i);\n }\n\n globalThis.btoa = function btoa(str) {\n if (str === undefined) {\n throw new TypeError(\"1 argument required, but only 0 present.\");\n }\n\n str = String(str);\n\n // Check for characters outside Latin-1 range\n for (let i = 0; i < str.length; i++) {\n if (str.charCodeAt(i) > 255) {\n throw new DOMException(\n \"The string to be encoded contains characters outside of the Latin1 range.\",\n \"InvalidCharacterError\"\n );\n }\n }\n\n if (str.length === 0) {\n return '';\n }\n\n let result = '';\n let i = 0;\n\n while (i < str.length) {\n const a = str.charCodeAt(i++);\n const bExists = i < str.length;\n const b = bExists ? str.charCodeAt(i++) : 0;\n const cExists = i < str.length;\n const c = cExists ? str.charCodeAt(i++) : 0;\n\n const triplet = (a << 16) | (b << 8) | c;\n\n result += base64Chars[(triplet >> 18) & 0x3F];\n result += base64Chars[(triplet >> 12) & 0x3F];\n result += bExists ? base64Chars[(triplet >> 6) & 0x3F] : '=';\n result += cExists ? base64Chars[triplet & 0x3F] : '=';\n }\n\n return result;\n };\n\n globalThis.atob = function atob(str) {\n if (str === undefined) {\n throw new TypeError(\"1 argument required, but only 0 present.\");\n }\n\n str = String(str);\n\n // Remove whitespace\n str = str.replace(/[\\\\t\\\\n\\\\f\\\\r ]/g, '');\n\n // Validate characters and length\n if (str.length === 0) {\n return '';\n }\n\n // Check for invalid characters (before padding normalization)\n for (let i = 0; i < str.length; i++) {\n const c = str[i];\n if (c !== '=' && !base64Lookup.has(c)) {\n throw new DOMException(\n \"The string to be decoded is not correctly encoded.\",\n \"InvalidCharacterError\"\n );\n }\n }\n\n // Validate padding position (must be at end)\n const paddingIndex = str.indexOf('=');\n if (paddingIndex !== -1) {\n for (let i = paddingIndex; i < str.length; i++) {\n if (str[i] !== '=') {\n throw new DOMException(\n \"The string to be decoded is not correctly encoded.\",\n \"InvalidCharacterError\"\n );\n }\n }\n const paddingLength = str.length - paddingIndex;\n if (paddingLength > 2) {\n throw new DOMException(\n \"The string to be decoded is not correctly encoded.\",\n \"InvalidCharacterError\"\n );\n }\n }\n\n // Length without padding must be valid (can't have remainder of 1)\n const strWithoutPadding = str.replace(/=/g, '');\n if (strWithoutPadding.length % 4 === 1) {\n throw new DOMException(\n \"The string to be decoded is not correctly encoded.\",\n \"InvalidCharacterError\"\n );\n }\n\n // Pad to multiple of 4 if needed (for inputs without explicit padding)\n while (str.length % 4 !== 0) {\n str += '=';\n }\n\n let result = '';\n let i = 0;\n\n while (i < str.length) {\n const a = base64Lookup.get(str[i++]) ?? 0;\n const b = base64Lookup.get(str[i++]) ?? 0;\n const c = base64Lookup.get(str[i++]) ?? 0;\n const d = base64Lookup.get(str[i++]) ?? 0;\n\n const triplet = (a << 18) | (b << 12) | (c << 6) | d;\n\n result += String.fromCharCode((triplet >> 16) & 0xFF);\n if (str[i - 2] !== '=') {\n result += String.fromCharCode((triplet >> 8) & 0xFF);\n }\n if (str[i - 1] !== '=') {\n result += String.fromCharCode(triplet & 0xFF);\n }\n }\n\n return result;\n };\n\n // ============================================\n // Buffer implementation\n // ============================================\n\n const BUFFER_SYMBOL = Symbol.for('__isBuffer');\n\n class Buffer extends Uint8Array {\n constructor(arg, encodingOrOffset, length) {\n if (typeof arg === 'number') {\n super(arg);\n } else if (typeof arg === 'string') {\n const bytes = stringToBytes(arg, encodingOrOffset || 'utf8');\n super(bytes);\n } else if (arg instanceof ArrayBuffer) {\n if (typeof encodingOrOffset === 'number') {\n super(arg, encodingOrOffset, length);\n } else {\n super(arg);\n }\n } else if (ArrayBuffer.isView(arg)) {\n super(arg.buffer, arg.byteOffset, arg.byteLength);\n } else if (Array.isArray(arg)) {\n super(arg);\n } else {\n super(arg);\n }\n Object.defineProperty(this, BUFFER_SYMBOL, { value: true, writable: false });\n }\n\n toString(encoding = 'utf8') {\n encoding = normalizeEncoding(encoding);\n if (encoding === 'utf8') {\n return new TextDecoder('utf-8').decode(this);\n } else if (encoding === 'base64') {\n return bytesToBase64(this);\n } else if (encoding === 'hex') {\n return bytesToHex(this);\n }\n return new TextDecoder('utf-8').decode(this);\n }\n\n slice(start, end) {\n const sliced = super.slice(start, end);\n return Buffer.from(sliced);\n }\n\n subarray(start, end) {\n const sub = super.subarray(start, end);\n const buf = new Buffer(sub.length);\n buf.set(sub);\n return buf;\n }\n\n static from(value, encodingOrOffset, length) {\n if (typeof value === 'string') {\n return new Buffer(value, encodingOrOffset);\n }\n if (value instanceof ArrayBuffer) {\n if (typeof encodingOrOffset === 'number') {\n return new Buffer(value, encodingOrOffset, length);\n }\n return new Buffer(value);\n }\n if (ArrayBuffer.isView(value)) {\n return new Buffer(value);\n }\n if (Array.isArray(value)) {\n return new Buffer(value);\n }\n if (value && typeof value[Symbol.iterator] === 'function') {\n return new Buffer(Array.from(value));\n }\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object');\n }\n\n static alloc(size, fill, encoding) {\n if (typeof size !== 'number' || size < 0) {\n throw new RangeError('Invalid size');\n }\n const buf = new Buffer(size);\n if (fill !== undefined) {\n if (typeof fill === 'number') {\n buf.fill(fill);\n } else if (typeof fill === 'string') {\n const fillBytes = stringToBytes(fill, encoding || 'utf8');\n for (let i = 0; i < size; i++) {\n buf[i] = fillBytes[i % fillBytes.length];\n }\n } else if (Buffer.isBuffer(fill) || fill instanceof Uint8Array) {\n for (let i = 0; i < size; i++) {\n buf[i] = fill[i % fill.length];\n }\n }\n }\n return buf;\n }\n\n static allocUnsafe(size) {\n if (typeof size !== 'number' || size < 0) {\n throw new RangeError('Invalid size');\n }\n return new Buffer(size);\n }\n\n static concat(list, totalLength) {\n if (!Array.isArray(list)) {\n throw new TypeError('list argument must be an array');\n }\n if (list.length === 0) {\n return Buffer.alloc(0);\n }\n if (totalLength === undefined) {\n totalLength = 0;\n for (const buf of list) {\n totalLength += buf.length;\n }\n }\n const result = Buffer.alloc(totalLength);\n let offset = 0;\n for (const buf of list) {\n if (offset + buf.length > totalLength) {\n result.set(buf.subarray(0, totalLength - offset), offset);\n break;\n }\n result.set(buf, offset);\n offset += buf.length;\n }\n return result;\n }\n\n static isBuffer(obj) {\n return obj != null && obj[BUFFER_SYMBOL] === true;\n }\n\n static byteLength(string, encoding = 'utf8') {\n if (typeof string !== 'string') {\n if (ArrayBuffer.isView(string) || string instanceof ArrayBuffer) {\n return string.byteLength;\n }\n throw new TypeError('First argument must be a string, Buffer, or ArrayBuffer');\n }\n encoding = normalizeEncoding(encoding);\n if (encoding === 'utf8') {\n return new TextEncoder().encode(string).length;\n } else if (encoding === 'base64') {\n const padding = (string.match(/=+$/) || [''])[0].length;\n return Math.floor((string.length * 3) / 4) - padding;\n } else if (encoding === 'hex') {\n return Math.floor(string.length / 2);\n }\n return new TextEncoder().encode(string).length;\n }\n\n static isEncoding(encoding) {\n return ['utf8', 'utf-8', 'base64', 'hex'].includes(normalizeEncoding(encoding));\n }\n }\n\n function normalizeEncoding(encoding) {\n if (!encoding) return 'utf8';\n const lower = String(encoding).toLowerCase().replace('-', '');\n if (lower === 'utf8' || lower === 'utf-8') return 'utf8';\n if (lower === 'base64') return 'base64';\n if (lower === 'hex') return 'hex';\n return lower;\n }\n\n function stringToBytes(str, encoding) {\n encoding = normalizeEncoding(encoding);\n if (encoding === 'utf8') {\n return new TextEncoder().encode(str);\n } else if (encoding === 'base64') {\n return base64ToBytes(str);\n } else if (encoding === 'hex') {\n return hexToBytes(str);\n }\n return new TextEncoder().encode(str);\n }\n\n function base64ToBytes(str) {\n const binary = atob(str);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n\n function bytesToBase64(bytes) {\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n }\n\n function hexToBytes(str) {\n if (str.length % 2 !== 0) {\n throw new TypeError('Invalid hex string');\n }\n const bytes = new Uint8Array(str.length / 2);\n for (let i = 0; i < str.length; i += 2) {\n const byte = parseInt(str.substr(i, 2), 16);\n if (isNaN(byte)) {\n throw new TypeError('Invalid hex string');\n }\n bytes[i / 2] = byte;\n }\n return bytes;\n }\n\n function bytesToHex(bytes) {\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += bytes[i].toString(16).padStart(2, '0');\n }\n return hex;\n }\n\n globalThis.Buffer = Buffer;\n})();\n`;\n\n/**\n * Setup encoding APIs in an isolated-vm context\n *\n * Injects:\n * - atob/btoa for Base64 encoding/decoding\n * - Buffer class for binary data handling (utf8, base64, hex)\n *\n * @example\n * const handle = await setupEncoding(context);\n * await context.eval(`\n * const encoded = btoa(\"hello\");\n * const decoded = atob(encoded);\n * const buf = Buffer.from(\"hello\");\n * const hex = buf.toString(\"hex\");\n * `);\n */\nexport async function setupEncoding(\n context: ivm.Context\n): Promise<EncodingHandle> {\n context.evalSync(encodingCode);\n return {\n dispose() {\n // No resources to cleanup for pure JS injection\n },\n };\n}\n"
|
|
6
6
|
],
|
|
7
7
|
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,IAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgYrB,eAAsB,aAAa,CACjC,SACyB;AAAA,EACzB,QAAQ,SAAS,YAAY;AAAA,EAC7B,OAAO;AAAA,IACL,OAAO,GAAG;AAAA,EAGZ;AAAA;",
|
|
8
8
|
"debugId": "45DC5B28BDBCE20A64756E2164756E21",
|
|
@@ -67,7 +67,7 @@ __export(exports_fetch, {
|
|
|
67
67
|
clearAllInstanceState: () => import_core.clearAllInstanceState
|
|
68
68
|
});
|
|
69
69
|
module.exports = __toCommonJS(exports_fetch);
|
|
70
|
-
var import_isolated_vm = __toESM(require("isolated-vm"));
|
|
70
|
+
var import_isolated_vm = __toESM(require("@ricsam/isolated-vm"));
|
|
71
71
|
var import_core = require("../core/index.cjs");
|
|
72
72
|
var import_stream_state = require("./stream-state.cjs");
|
|
73
73
|
var instanceStateMap = new WeakMap;
|
|
@@ -1911,21 +1911,32 @@ function setupClientWebSocket(context, clientWsCommandCallbacks) {
|
|
|
1911
1911
|
}
|
|
1912
1912
|
};
|
|
1913
1913
|
|
|
1914
|
+
const __wrapAsyncContextCallback = (callback, options = {}) => (
|
|
1915
|
+
typeof callback === 'function' && globalThis.__isolateAsyncContextInternals?.wrapCallback
|
|
1916
|
+
? globalThis.__isolateAsyncContextInternals.wrapCallback(callback, options)
|
|
1917
|
+
: callback
|
|
1918
|
+
);
|
|
1919
|
+
const __releaseAsyncContextCallback = (callback) => (
|
|
1920
|
+
typeof callback === 'function' && globalThis.__isolateAsyncContextInternals?.releaseCallback
|
|
1921
|
+
? globalThis.__isolateAsyncContextInternals.releaseCallback(callback)
|
|
1922
|
+
: false
|
|
1923
|
+
);
|
|
1924
|
+
|
|
1914
1925
|
// Helper to dispatch events
|
|
1915
1926
|
function dispatchEvent(ws, event) {
|
|
1916
1927
|
const listeners = ws._listeners.get(event.type) || [];
|
|
1917
1928
|
for (const listener of listeners) {
|
|
1918
1929
|
try {
|
|
1919
|
-
listener.call(ws, event);
|
|
1930
|
+
listener.wrapped.call(ws, event);
|
|
1920
1931
|
} catch (e) {
|
|
1921
1932
|
console.error('WebSocket event listener error:', e);
|
|
1922
1933
|
}
|
|
1923
1934
|
}
|
|
1924
1935
|
// Also call on* handler if set
|
|
1925
|
-
const handler = ws
|
|
1926
|
-
if (
|
|
1936
|
+
const handler = ws._handlers.get(event.type);
|
|
1937
|
+
if (handler?.wrapped) {
|
|
1927
1938
|
try {
|
|
1928
|
-
handler.call(ws, event);
|
|
1939
|
+
handler.wrapped.call(ws, event);
|
|
1929
1940
|
} catch (e) {
|
|
1930
1941
|
console.error('WebSocket handler error:', e);
|
|
1931
1942
|
}
|
|
@@ -1946,12 +1957,21 @@ function setupClientWebSocket(context, clientWsCommandCallbacks) {
|
|
|
1946
1957
|
#protocol = '';
|
|
1947
1958
|
#binaryType = 'blob';
|
|
1948
1959
|
_listeners = new Map();
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1960
|
+
_handlers = new Map([
|
|
1961
|
+
['open', null],
|
|
1962
|
+
['message', null],
|
|
1963
|
+
['error', null],
|
|
1964
|
+
['close', null],
|
|
1965
|
+
]);
|
|
1966
|
+
|
|
1967
|
+
get onopen() { return this._handlers.get('open')?.original ?? null; }
|
|
1968
|
+
set onopen(handler) { this._setHandler('open', handler); }
|
|
1969
|
+
get onmessage() { return this._handlers.get('message')?.original ?? null; }
|
|
1970
|
+
set onmessage(handler) { this._setHandler('message', handler); }
|
|
1971
|
+
get onerror() { return this._handlers.get('error')?.original ?? null; }
|
|
1972
|
+
set onerror(handler) { this._setHandler('error', handler); }
|
|
1973
|
+
get onclose() { return this._handlers.get('close')?.original ?? null; }
|
|
1974
|
+
set onclose(handler) { this._setHandler('close', handler); }
|
|
1955
1975
|
|
|
1956
1976
|
constructor(url, protocols) {
|
|
1957
1977
|
// Validate URL
|
|
@@ -2036,6 +2056,24 @@ function setupClientWebSocket(context, clientWsCommandCallbacks) {
|
|
|
2036
2056
|
get CLOSING() { return WebSocket.CLOSING; }
|
|
2037
2057
|
get CLOSED() { return WebSocket.CLOSED; }
|
|
2038
2058
|
|
|
2059
|
+
_setHandler(type, handler) {
|
|
2060
|
+
const previous = this._handlers.get(type);
|
|
2061
|
+
if (previous?.wrapped) {
|
|
2062
|
+
__releaseAsyncContextCallback(previous.wrapped);
|
|
2063
|
+
}
|
|
2064
|
+
if (typeof handler !== 'function') {
|
|
2065
|
+
this._handlers.set(type, null);
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
this._handlers.set(type, {
|
|
2069
|
+
original: handler,
|
|
2070
|
+
wrapped: __wrapAsyncContextCallback(handler, {
|
|
2071
|
+
resource: this,
|
|
2072
|
+
type: 'isolate.websocket',
|
|
2073
|
+
}),
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2039
2077
|
send(data) {
|
|
2040
2078
|
if (this.#readyState === WebSocket.CONNECTING) {
|
|
2041
2079
|
throw new DOMException("Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.", 'InvalidStateError');
|
|
@@ -2109,16 +2147,23 @@ function setupClientWebSocket(context, clientWsCommandCallbacks) {
|
|
|
2109
2147
|
listeners = [];
|
|
2110
2148
|
this._listeners.set(type, listeners);
|
|
2111
2149
|
}
|
|
2112
|
-
if (!listeners.
|
|
2113
|
-
listeners.push(
|
|
2150
|
+
if (!listeners.some((entry) => entry.original === listener)) {
|
|
2151
|
+
listeners.push({
|
|
2152
|
+
original: listener,
|
|
2153
|
+
wrapped: __wrapAsyncContextCallback(listener, {
|
|
2154
|
+
resource: this,
|
|
2155
|
+
type: 'isolate.websocket',
|
|
2156
|
+
}),
|
|
2157
|
+
});
|
|
2114
2158
|
}
|
|
2115
2159
|
}
|
|
2116
2160
|
|
|
2117
2161
|
removeEventListener(type, listener, options) {
|
|
2118
2162
|
const listeners = this._listeners.get(type);
|
|
2119
2163
|
if (!listeners) return;
|
|
2120
|
-
const index = listeners.
|
|
2164
|
+
const index = listeners.findIndex((entry) => entry.original === listener || entry.wrapped === listener);
|
|
2121
2165
|
if (index !== -1) {
|
|
2166
|
+
__releaseAsyncContextCallback(listeners[index].wrapped);
|
|
2122
2167
|
listeners.splice(index, 1);
|
|
2123
2168
|
}
|
|
2124
2169
|
}
|
|
@@ -2177,6 +2222,18 @@ function setupClientWebSocket(context, clientWsCommandCallbacks) {
|
|
|
2177
2222
|
this.#readyState = WebSocket.CLOSED;
|
|
2178
2223
|
const event = new _CloseEvent('close', { code, reason, wasClean });
|
|
2179
2224
|
dispatchEvent(this, event);
|
|
2225
|
+
for (const handler of this._handlers.values()) {
|
|
2226
|
+
if (handler?.wrapped) {
|
|
2227
|
+
__releaseAsyncContextCallback(handler.wrapped);
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
for (const listeners of this._listeners.values()) {
|
|
2231
|
+
for (const listener of listeners) {
|
|
2232
|
+
__releaseAsyncContextCallback(listener.wrapped);
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
this._handlers.clear();
|
|
2236
|
+
this._listeners.clear();
|
|
2180
2237
|
__clientWebSockets.delete(this.#socketId);
|
|
2181
2238
|
}
|
|
2182
2239
|
}
|
|
@@ -2212,9 +2269,41 @@ function setupServe(context) {
|
|
|
2212
2269
|
context.evalSync(`
|
|
2213
2270
|
(function() {
|
|
2214
2271
|
globalThis.__serveOptions__ = null;
|
|
2272
|
+
const __wrapAsyncContextCallback = (callback, options = {}) => (
|
|
2273
|
+
typeof callback === 'function' && globalThis.__isolateAsyncContextInternals?.wrapCallback
|
|
2274
|
+
? globalThis.__isolateAsyncContextInternals.wrapCallback(callback, options)
|
|
2275
|
+
: callback
|
|
2276
|
+
);
|
|
2277
|
+
|
|
2278
|
+
function wrapServeOptions(options) {
|
|
2279
|
+
if (!options || typeof options !== 'object') {
|
|
2280
|
+
return options;
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2283
|
+
const wrapped = { ...options };
|
|
2284
|
+
if (typeof options.fetch === 'function') {
|
|
2285
|
+
wrapped.fetch = __wrapAsyncContextCallback(options.fetch, {
|
|
2286
|
+
type: 'isolate.serve',
|
|
2287
|
+
});
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2290
|
+
if (options.websocket && typeof options.websocket === 'object') {
|
|
2291
|
+
wrapped.websocket = { ...options.websocket };
|
|
2292
|
+
for (const name of ['open', 'message', 'close', 'error']) {
|
|
2293
|
+
if (typeof options.websocket[name] === 'function') {
|
|
2294
|
+
wrapped.websocket[name] = __wrapAsyncContextCallback(
|
|
2295
|
+
options.websocket[name],
|
|
2296
|
+
{ type: 'isolate.serve.websocket' },
|
|
2297
|
+
);
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
return wrapped;
|
|
2303
|
+
}
|
|
2215
2304
|
|
|
2216
2305
|
function serve(options) {
|
|
2217
|
-
globalThis.__serveOptions__ = options;
|
|
2306
|
+
globalThis.__serveOptions__ = wrapServeOptions(options);
|
|
2218
2307
|
}
|
|
2219
2308
|
|
|
2220
2309
|
globalThis.serve = serve;
|
|
@@ -2252,6 +2341,16 @@ async function setupFetch(context, options) {
|
|
|
2252
2341
|
context.evalSync(`
|
|
2253
2342
|
(function() {
|
|
2254
2343
|
const __eventListeners = new Map();
|
|
2344
|
+
const __wrapAsyncContextCallback = (callback) => (
|
|
2345
|
+
typeof callback === 'function' && globalThis.__isolateAsyncContextInternals?.wrapCallback
|
|
2346
|
+
? globalThis.__isolateAsyncContextInternals.wrapCallback(callback, { type: 'isolate.event' })
|
|
2347
|
+
: callback
|
|
2348
|
+
);
|
|
2349
|
+
const __releaseAsyncContextCallback = (callback) => (
|
|
2350
|
+
typeof callback === 'function' && globalThis.__isolateAsyncContextInternals?.releaseCallback
|
|
2351
|
+
? globalThis.__isolateAsyncContextInternals.releaseCallback(callback)
|
|
2352
|
+
: false
|
|
2353
|
+
);
|
|
2255
2354
|
|
|
2256
2355
|
globalThis.__on = function(event, callback) {
|
|
2257
2356
|
let listeners = __eventListeners.get(event);
|
|
@@ -2259,9 +2358,11 @@ async function setupFetch(context, options) {
|
|
|
2259
2358
|
listeners = new Set();
|
|
2260
2359
|
__eventListeners.set(event, listeners);
|
|
2261
2360
|
}
|
|
2262
|
-
|
|
2361
|
+
const wrapped = __wrapAsyncContextCallback(callback);
|
|
2362
|
+
listeners.add(wrapped);
|
|
2263
2363
|
return function() {
|
|
2264
|
-
listeners.delete(
|
|
2364
|
+
listeners.delete(wrapped);
|
|
2365
|
+
__releaseAsyncContextCallback(wrapped);
|
|
2265
2366
|
if (listeners.size === 0) {
|
|
2266
2367
|
__eventListeners.delete(event);
|
|
2267
2368
|
}
|
|
@@ -2637,4 +2738,4 @@ async function setupFetch(context, options) {
|
|
|
2637
2738
|
};
|
|
2638
2739
|
}
|
|
2639
2740
|
|
|
2640
|
-
//# debugId=
|
|
2741
|
+
//# debugId=9AF8B200C8CF0CEC64756E2164756E21
|