-
Notifications
You must be signed in to change notification settings - Fork 0
/
webr-serviceworker.js.map
7 lines (7 loc) · 12.2 KB
/
webr-serviceworker.js.map
1
2
3
4
5
6
7
{
"version": 3,
"sources": ["../src/webR/compat.ts", "../src/webR/utils.ts", "../src/webR/chan/message.ts", "../src/webR/chan/serviceworker.ts"],
"sourcesContent": ["interface Process {\n browser: string | undefined;\n release: { [key: string]: string };\n}\ndeclare let process: Process;\n\nexport const IN_NODE =\n typeof process !== 'undefined' &&\n process.release &&\n process.release.name === 'node' &&\n typeof process.browser === 'undefined';\n\n// Adapted from https://github.com/pyodide/pyodide/blob/main/src/js/compat.ts\nexport let loadScript: (url: string) => Promise<void>;\nif (globalThis.document) {\n loadScript = (url) =>\n new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = url;\n script.onload = () => resolve();\n script.onerror = reject;\n document.head.appendChild(script);\n });\n} else if (globalThis.importScripts) {\n loadScript = async (url) => {\n try {\n globalThis.importScripts(url);\n } catch (e) {\n if (e instanceof TypeError) {\n await import(url);\n } else {\n throw e;\n }\n }\n };\n} else if (IN_NODE) {\n loadScript = async (url: string) => {\n const nodePathMod = (await import('path')).default;\n await import(nodePathMod.resolve(url));\n };\n} else {\n throw new Error('Cannot determine runtime environment');\n}\n", "import { IN_NODE } from './compat';\n\nexport type ResolveFn = (_value?: unknown) => void;\nexport type RejectFn = (_reason?: any) => void;\n\nexport function promiseHandles() {\n const out = {\n resolve: (_value?: unknown) => {},\n reject: (_reason?: any) => {},\n promise: null as unknown as Promise<unknown>,\n };\n\n const promise = new Promise((resolve, reject) => {\n out.resolve = resolve;\n out.reject = reject;\n });\n out.promise = promise;\n\n return out;\n}\n\nexport function sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function replaceInObject<T>(\n obj: T | T[],\n test: (obj: any) => boolean,\n replacer: (obj: any, ...replacerArgs: any[]) => unknown,\n ...replacerArgs: unknown[]\n): T | T[] {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n if (test(obj)) {\n return replacer(obj, ...replacerArgs) as T;\n }\n if (Array.isArray(obj) || ArrayBuffer.isView(obj)) {\n return (obj as unknown[]).map((v) =>\n replaceInObject(v, test, replacer, ...replacerArgs)\n ) as T[];\n }\n return Object.fromEntries(\n Object.entries(obj).map(([k, v], i) => [k, replaceInObject(v, test, replacer, ...replacerArgs)])\n ) as T;\n}\n\n/* Workaround for loading a cross-origin script.\n *\n * When fetching a worker script, the fetch is required by the spec to\n * use \"same-origin\" mode. This is to avoid loading a worker with a\n * cross-origin global scope, which can allow for a cross-origin\n * restriction bypass.\n *\n * When the fetch URL begins with 'http', we assume the request is\n * cross-origin. We download the content of the URL using a XHR first,\n * create a blob URL containing the requested content, then load the\n * blob URL as a script.\n *\n * The origin of a blob URL is the same as that of the environment that\n * created the URL, and so the global scope of the resulting worker is\n * no longer cross-origin. In that case, the cross-origin restriction\n * bypass is not possible, and the script is permitted to be loaded.\n */\nexport function newCrossOriginWorker(url: string, cb: (worker: Worker) => void): void {\n const req = new XMLHttpRequest();\n req.open('get', url, true);\n req.onload = () => {\n const worker = new Worker(URL.createObjectURL(new Blob([req.responseText])));\n cb(worker);\n };\n req.send();\n}\n\nexport function isCrossOrigin(urlString: string) {\n if (IN_NODE) return false;\n const url1 = new URL(location.href);\n const url2 = new URL(urlString, location.origin);\n if (url1.host === url2.host && url1.port === url2.port && url1.protocol === url2.protocol) {\n return false;\n }\n return true;\n}\n\nexport function throwUnreachable(context?: string) {\n let msg = 'Reached the unreachable';\n msg = msg + (context ? ': ' + context : '.');\n\n throw new Error(msg);\n}\n", "/**\n * WebR communication channel messaging and request types.\n * @module Message\n */\nimport { generateUUID, transfer, UUID } from './task-common';\n\n/** A webR communication channel message. */\nexport interface Message {\n type: string;\n data?: any;\n}\n\n/** A webR communication channel request. */\nexport interface Request {\n type: 'request';\n data: {\n uuid: UUID;\n msg: Message;\n };\n}\n\n/** A webR communication channel response. */\nexport interface Response {\n type: 'response';\n data: {\n uuid: UUID;\n resp: unknown;\n };\n}\n\n/** @internal */\nexport function newRequest(msg: Message, transferables?: [Transferable]): Request {\n return newRequestResponseMessage(\n {\n type: 'request',\n data: {\n uuid: generateUUID(),\n msg: msg,\n },\n },\n transferables\n );\n}\n\n/** @internal */\nexport function newResponse(uuid: UUID, resp: unknown, transferables?: [Transferable]): Response {\n return newRequestResponseMessage(\n {\n type: 'response',\n data: {\n uuid,\n resp,\n },\n },\n transferables\n );\n}\n\n/** @internal */\nfunction newRequestResponseMessage<T>(msg: T, transferables?: [Transferable]): T {\n // Signal to Synclink that the data contains objects we wish to\n // transfer, as in `postMessage()`\n if (transferables) {\n transfer(msg, transferables);\n }\n return msg;\n}\n\n/** A webR communication channel sync-request.\n * @internal\n */\nexport interface SyncRequest {\n type: 'sync-request';\n data: {\n msg: Message;\n reqData: SyncRequestData;\n };\n}\n\n/** Transfer data required when using sync-request with SharedArrayBuffer.\n * @internal */\nexport interface SyncRequestData {\n taskId?: number;\n sizeBuffer: Int32Array;\n signalBuffer: Int32Array;\n dataBuffer: Uint8Array;\n}\n\n/** @internal */\nexport function newSyncRequest(msg: Message, data: SyncRequestData): SyncRequest {\n return {\n type: 'sync-request',\n data: { msg, reqData: data },\n };\n}\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder('utf-8');\n\n/**\n * Encode data for transfering from worker thread to main thread.\n * @param {any} data The message data to be serialised and encoded.\n * @return {Uint8Array} The encoded data.\n * @internal\n * */\nexport function encodeData(data: any): Uint8Array {\n // TODO: Pass a `replacer` function\n return encoder.encode(JSON.stringify(data));\n}\n\n/**\n * Decode data that has been transferred from worker thread to main thread.\n * @param {any} data The message data to be decoded.\n * @return {unknown} The data after decoding.\n * @internal\n * */\nexport function decodeData(data: Uint8Array): unknown {\n return JSON.parse(decoder.decode(data)) as unknown;\n}\n", "import { promiseHandles } from '../utils';\nimport { decodeData, encodeData } from './message';\n\ndeclare let self: ServiceWorkerGlobalScope;\n\nconst requests: {\n [key: string]: {\n resolve: (_value?: unknown) => void;\n reject: (_reason?: any) => void;\n promise: Promise<unknown>;\n };\n} = {};\n\nfunction handleInstall() {\n console.log('webR service worker installed');\n self.skipWaiting();\n}\n\nfunction handleActivate(event: ExtendableEvent) {\n console.log('webR service worker activating');\n event.waitUntil(self.clients.claim());\n}\n\nconst sendRequest = async (clientId: string, uuid: string): Promise<Response> => {\n const client = await self.clients.get(clientId);\n if (!client) {\n throw new Error('Service worker client not found');\n }\n\n if (!(uuid in requests)) {\n requests[uuid] = promiseHandles();\n client.postMessage({ type: 'request', data: uuid });\n }\n\n const response = await requests[uuid].promise;\n const headers = { 'Cross-Origin-Embedder-Policy': 'require-corp' };\n return new Response(encodeData(response), { headers });\n};\n\nconst handleFetch = (event: FetchEvent) => {\n // console.log('service worker got a fetch', event);\n const wasmMatch = /__wasm__\\/webr-fetch-request\\//.exec(event.request.url);\n if (!wasmMatch) {\n return;\n }\n const requestBody = event.request.arrayBuffer();\n const requestReponse = requestBody.then(async (body) => {\n const data = decodeData(new Uint8Array(body)) as { clientId: string; uuid: string };\n return await sendRequest(data.clientId, data.uuid);\n });\n event.waitUntil(requestReponse);\n event.respondWith(requestReponse);\n};\n\nfunction handleMessage(event: ExtendableMessageEvent) {\n // console.log('service worker got a message', event.data);\n switch (event.data.type) {\n case 'register-client-main': {\n self.clients.claim();\n const source = event.source as WindowClient;\n self.clients.get(source.id).then((client) => {\n if (!client) {\n throw new Error(\"Can't respond to client in service worker message handler\");\n }\n client.postMessage({\n type: 'registration-successful',\n clientId: source.id,\n });\n });\n break;\n }\n case 'wasm-webr-fetch-response': {\n if (event.data.uuid in requests) {\n requests[event.data.uuid].resolve(event.data.response);\n delete requests[event.data.uuid];\n }\n break;\n }\n default:\n throw new Error(`Unknown service worker message type: ${event.data.type as string}`);\n }\n}\n\nself.addEventListener('install', handleInstall);\nself.addEventListener('activate', handleActivate);\nself.addEventListener('fetch', handleFetch);\nself.addEventListener('message', handleMessage);\n"],
"mappings": "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",
"names": []
}