lucent-pack 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts","../src/debug.ts","../src/rwasm-constants.ts","../src/rWasmServiceDriver.ts","../src/transport.ts","../src/wiring.ts","../src/runApp.ts"],"names":["rWorker"],"mappings":"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","file":"runApp.js","sourcesContent":["export interface LucentConfig {\n /** Base URL where Lucent-built httpuv transport assets (httpuv-web.js, shiny-socket.js, ...) are served. */\n transportBaseUrl: string;\n /**\n * URL of the httpuv service worker script. Defaults to `/httpuv-sw.js` at the\n * site root so registration works on hosts that cannot send\n * `Service-Worker-Allowed` (e.g. GitHub Pages). That file is a deploy-time\n * or serve-time alias of `lucent/dist/httpuv-sw.js`.\n */\n serviceWorkerUrl: string;\n /**\n * Base URL for the Rmain bootstrap binaries (`bin/Rmain.js`, `bin/Rmain.wasm`).\n * Trailing slash is normalized at use sites.\n */\n rRuntimeBaseUrl: string;\n /** URL of `empack_env_meta.json` (packages + appended webApp archive). */\n empackMetaUrl: string;\n /** Base URL for empack package archives listed in the meta file. */\n empackPackagesBaseUrl: string;\n /**\n * Base URL under which the virtual Shiny app is mounted; the mount prefix is\n * `<shinyBaseUrl>shiny/`. Defaults to the origin root (\"/\"), giving `/shiny/`.\n * This MUST be decoupled from where the JS bundles live (e.g. /lucent/dist/),\n * otherwise Shiny's asset URLs collide with the real bundle directory.\n */\n shinyBaseUrl: string;\n}\n\n/** Default location of Lucent-built httpuv transport assets. */\nexport const DEFAULT_TRANSPORT_BASE_URL = \"/lucent/dist/\";\n\n/** Default SW script URL (site root alias of lucent/dist/httpuv-sw.js). */\nexport const DEFAULT_SERVICE_WORKER_URL = \"/httpuv-sw.js\";\n\n/** Default base for Rmain.js / Rmain.wasm (`bin/` under this URL). */\nexport const DEFAULT_R_RUNTIME_BASE_URL = \"/runtime/\";\n\n/** Default empack meta URL. */\nexport const DEFAULT_EMPACK_META_URL = \"/packages/empack_env_meta.json\";\n\n/** Default base for the Shiny mount point (origin root → prefix `/shiny/`). */\nexport const DEFAULT_SHINY_BASE_URL = \"/\";\n\ninterface LucentGlobal {\n __LUCENT__?: Partial<LucentConfig>;\n}\n\n/** URL query param the host uses to hand its resolved config to the worker. */\nexport const LUCENT_CONFIG_PARAM = \"lucentConfig\";\n\n/**\n * Read config overrides serialized onto this context's own URL\n * (`?lucentConfig=<json>`). The host is the single source of truth: it resolves\n * config once and passes it to the worker via this param, so the worker does\n * not re-resolve from its own (empty) globalThis.\n */\nfunction configOverridesFromUrl(): Partial<LucentConfig> {\n try {\n const search = (globalThis as unknown as { location?: { search?: string } }).location?.search;\n if (!search) {\n return {};\n }\n const raw = new URLSearchParams(search).get(LUCENT_CONFIG_PARAM);\n if (!raw) {\n return {};\n }\n const parsed = JSON.parse(raw) as unknown;\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Partial<LucentConfig>;\n }\n } catch {\n // ignore malformed config; fall back to globals/defaults\n }\n return {};\n}\n\nfunction resolveAgainstLocation(url: string): URL {\n const base =\n typeof self !== \"undefined\" && self.location?.href\n ? self.location.href\n : \"http://localhost/\";\n return new URL(url, base);\n}\n\n/**\n * Resolve the runtime config, layering explicit overrides over a `?lucentConfig`\n * URL param (host → worker handoff) over a globalThis (`__LUCENT__`) config over\n * the built-in defaults.\n */\nexport function resolveLucentConfig(overrides: Partial<LucentConfig> = {}): LucentConfig {\n const fromGlobal = (globalThis as unknown as LucentGlobal).__LUCENT__ ?? {};\n const fromUrl = configOverridesFromUrl();\n const pick = <K extends keyof LucentConfig>(key: K): LucentConfig[K] | undefined =>\n overrides[key] ?? fromUrl[key] ?? fromGlobal[key];\n\n const empackMetaUrl = pick(\"empackMetaUrl\") ?? DEFAULT_EMPACK_META_URL;\n const empackPackagesBaseUrl =\n pick(\"empackPackagesBaseUrl\") ?? new URL(\".\", resolveAgainstLocation(empackMetaUrl)).href;\n\n return {\n transportBaseUrl: pick(\"transportBaseUrl\") ?? DEFAULT_TRANSPORT_BASE_URL,\n serviceWorkerUrl: pick(\"serviceWorkerUrl\") ?? DEFAULT_SERVICE_WORKER_URL,\n rRuntimeBaseUrl: pick(\"rRuntimeBaseUrl\") ?? DEFAULT_R_RUNTIME_BASE_URL,\n empackMetaUrl,\n empackPackagesBaseUrl,\n shinyBaseUrl: pick(\"shinyBaseUrl\") ?? DEFAULT_SHINY_BASE_URL,\n };\n}\n","/**\n * Opt-in tracing for Lucent / wasm Shiny (same switches as r-httpuv).\n *\n * Enable with either:\n * - URL query: ?httpuvDebug=1\n * - localStorage: shinyForgeDebug = \"1\"\n * - console: shinyForge.enableHttpuvDebug()\n */\nexport function isLucentDebug(): boolean {\n if (globalThis.__HTTPUV_DEBUG__) {\n return true;\n }\n try {\n if (typeof localStorage !== \"undefined\" && localStorage.getItem(\"shinyForgeDebug\") === \"1\") {\n return true;\n }\n const loc =\n typeof location !== \"undefined\"\n ? location\n : typeof self !== \"undefined\" && \"location\" in self\n ? (self as WorkerGlobalScope).location\n : undefined;\n if (loc?.href) {\n const params = new URL(loc.href).searchParams;\n if (params.has(\"httpuvDebug\") || params.get(\"debug\") === \"httpuv\") {\n return true;\n }\n }\n } catch {\n // ignore\n }\n return false;\n}\n\n/** Structured trace — only when debug is enabled. */\nexport function lucentDebugLog(stage: string, ...args: unknown[]): void {\n if (!isLucentDebug()) {\n return;\n }\n console.info(`[lucent-debug:${stage}]`, ...args);\n}\n\n/** One-shot informational log — only when debug is enabled. */\nexport function lucentInfo(...args: unknown[]): void {\n if (!isLucentDebug()) {\n return;\n }\n console.info(...args);\n}\n\n/** R worker log relay: always forwarded to the console. */\nexport function forwardRWorkerLog(level: \"log\" | \"error\", text: string): void {\n if (level === \"error\") {\n console.error(`[rWasmWorker] ${text}`);\n return;\n }\n console.log(`[rWasmWorker] ${text}`);\n}\n","/** R_HOME inside the mounted prefix (VFS root is /). */\nexport const WASM_R_HOME = \"/lib/R\";\n\n/** App directory inside the R VFS (populated via empack pack dir + append). */\nexport const WEB_APP_DIR = \"/webApp\";\n\n/** Message types between the main page and the R.wasm dedicated worker. */\nexport const RWASM = {\n READY: \"rwasm_ready\",\n EVAL: \"rwasm_eval\",\n EVAL_RESULT: \"rwasm_eval_result\",\n STOP_APP: \"rwasm_stop_app\",\n REMOUNT_R_HOME: \"rwasm_remount_r_home\",\n STOPPED: \"rwasm_stopped\",\n COMLINK_PORT: \"rwasm_comlink_port\",\n COMLINK_READY: \"rwasm_comlink_ready\",\n GET_RESOURCE_PATHS: \"rwasm_get_resource_paths\",\n RESOURCE_PATHS: \"rwasm_resource_paths\",\n LOG: \"rwasm_log\",\n /** Worker → main: empack package download progress. */\n DOWNLOAD_PROGRESS: \"rwasm_download_progress\",\n /** Worker → main: coarse boot phase updates after / around downloads. */\n BOOT_STATUS: \"rwasm_boot_status\",\n ERROR: \"rwasm_error\",\n /** Main → worker: run one shiny::serviceOnce tick. */\n SERVICE_TICK: \"rwasm_service_tick\",\n /** Worker → main: result of a SERVICE_TICK (`hadWork` / `nextDelayMs`). */\n SERVICE_STATUS: \"rwasm_service_status\",\n /** Worker → main: schedule an immediate MessageChannel wake. */\n NEED_SERVICE: \"rwasm_need_service\",\n /** Worker → main: delayed wake (`delayMs`) via setTimeout then MessageChannel.\n * Used when scheduleTask runs outside a SERVICE_TICK; idle delays after a tick\n * go through SERVICE_STATUS.nextDelayMs instead. */\n SCHEDULE_DELAY: \"rwasm_schedule_delay\",\n} as const;\n","import { RWASM } from \"./rwasm-constants\";\n\nexport type ServiceDriver = {\n /** Ensure an rAF tick is scheduled (idempotent; visible tabs only). */\n wake: () => void;\n /** Schedule a delayed wake via setTimeout → MessageChannel (breaks chained-timer loops). */\n scheduleDelay: (delayMs: number) => void;\n /** Attach to a worker; replaces any previous attachment. */\n attach: (worker: Worker) => void;\n /** Detach listeners and cancel pending frames/timers. */\n stop: () => void;\n};\n\nexport type ServiceDriverOptions = {\n /** Called when a SERVICE_TICK reported reactive/HTTP work. */\n onHadWork?: () => void;\n};\n\ntype ServiceStatusMessage = {\n type: typeof RWASM.SERVICE_STATUS;\n hadWork?: boolean;\n /** Ms until next R timer, or -1 / omitted when idle. */\n nextDelayMs?: number;\n};\n\ntype NeedServiceMessage = {\n type: typeof RWASM.NEED_SERVICE;\n};\n\ntype ScheduleDelayMessage = {\n type: typeof RWASM.SCHEDULE_DELAY;\n delayMs?: number;\n};\n\n/**\n * Main-thread Shiny service driver.\n *\n * Immediate follow-ups use a MessageChannel macrotask so Chrome does not\n * throttle nested setTimeout(0) chains while DevTools is open or focus is\n * inside the Shiny iframe. requestAnimationFrame only coalesces visible work\n * (it pauses when the tab is hidden).\n */\nexport function createServiceDriver(options: ServiceDriverOptions = {}): ServiceDriver {\n let worker: Worker | null = null;\n let rafPending = false;\n let rafId = 0;\n let tickInFlight = false;\n let wakeQueued = false;\n let soonPending = false;\n let stopped = true;\n const delayTimers = new Set<ReturnType<typeof setTimeout>>();\n /** Absolute deadline (performance.now) of the soonest pending delay, or Infinity. */\n let delayDeadline = Infinity;\n\n // MessageChannel macrotasks avoid nested-setTimeout clamping / DevTools deferral\n // (same approach as rWasmTasks.ts on the worker).\n const soonChannel = new MessageChannel();\n soonChannel.port1.onmessage = () => {\n if (!soonPending) {\n // Cancelled by clearSoon / stop / scheduleDelay coalescing.\n return;\n }\n soonPending = false;\n if (stopped || !worker) {\n return;\n }\n postTick();\n };\n\n function clearSoon(): void {\n soonPending = false;\n }\n\n /** Cancel pending setTimeout delays only (leave MessageChannel wakes alone). */\n function clearDelayOnly(): void {\n for (const id of delayTimers) {\n clearTimeout(id);\n }\n delayTimers.clear();\n delayDeadline = Infinity;\n }\n\n function clearDelayTimers(): void {\n clearDelayOnly();\n clearSoon();\n }\n\n function cancelRaf(): void {\n if (rafPending && rafId) {\n cancelAnimationFrame(rafId);\n }\n rafPending = false;\n rafId = 0;\n }\n\n function postTick(): void {\n if (!worker || stopped) {\n return;\n }\n if (tickInFlight) {\n wakeQueued = true;\n return;\n }\n tickInFlight = true;\n wakeQueued = false;\n worker.postMessage({ type: RWASM.SERVICE_TICK });\n }\n\n function onFrame(): void {\n rafPending = false;\n rafId = 0;\n if (stopped || !worker) {\n return;\n }\n postTick();\n }\n\n function wake(): void {\n if (stopped || !worker) {\n return;\n }\n // rAF is paused while the tab is hidden; MessageChannel covers that case.\n if (document.visibilityState !== \"visible\") {\n return;\n }\n if (tickInFlight) {\n wakeQueued = true;\n return;\n }\n if (rafPending) {\n wakeQueued = true;\n return;\n }\n rafPending = true;\n rafId = requestAnimationFrame(onFrame);\n }\n\n /**\n * Immediate wake that does not wait for the next animation frame.\n * Uses MessageChannel instead of setTimeout(0) so Chrome does not clamp\n * chained timers when DevTools is open or the Shiny iframe has focus.\n */\n function wakeSoon(): void {\n if (stopped || !worker) {\n return;\n }\n if (tickInFlight) {\n wakeQueued = true;\n return;\n }\n if (soonPending) {\n wakeQueued = true;\n return;\n }\n soonPending = true;\n soonChannel.port2.postMessage(0);\n }\n\n /** Schedule an immediate service tick; MessageChannel first, rAF as visible backup. */\n function scheduleFollowUp(): void {\n wakeSoon();\n wake();\n }\n\n function scheduleDelay(delayMs: number): void {\n if (stopped || !worker) {\n return;\n }\n const ms = Math.max(0, Number(delayMs) || 0);\n if (ms <= 0) {\n scheduleFollowUp();\n return;\n }\n const deadline = performance.now() + ms;\n // Keep only the soonest wake; ignore later requests.\n if (deadline >= delayDeadline) {\n return;\n }\n clearDelayOnly();\n delayDeadline = deadline;\n const id = setTimeout(() => {\n delayTimers.delete(id);\n delayDeadline = Infinity;\n scheduleFollowUp();\n }, ms);\n delayTimers.add(id);\n }\n\n function onWorkerMessage(event: MessageEvent): void {\n const data = event.data as\n | ServiceStatusMessage\n | NeedServiceMessage\n | ScheduleDelayMessage\n | undefined;\n if (!data || typeof data.type !== \"string\") {\n return;\n }\n\n if (data.type === RWASM.SERVICE_STATUS) {\n tickInFlight = false;\n const status = data as ServiceStatusMessage;\n const hadWork = Boolean(status.hadWork);\n const nextDelayMs = Number(status.nextDelayMs);\n if (stopped) {\n return;\n }\n if (hadWork || wakeQueued) {\n if (hadWork) {\n options.onHadWork?.();\n }\n wakeQueued = false;\n scheduleFollowUp();\n return;\n }\n // Host owns the post-tick delay timer (R no longer scheduleHostDelay from serviceOnce).\n if (Number.isFinite(nextDelayMs) && nextDelayMs >= 0) {\n scheduleDelay(nextDelayMs);\n } else {\n // Idle or cancelled timers: drop any stale delay (keep MessageChannel wakes).\n clearDelayOnly();\n }\n return;\n }\n\n if (data.type === RWASM.NEED_SERVICE) {\n scheduleFollowUp();\n return;\n }\n\n if (data.type === RWASM.SCHEDULE_DELAY) {\n scheduleDelay(Number((data as ScheduleDelayMessage).delayMs) || 0);\n }\n }\n\n function onVisibilityChange(): void {\n if (stopped) {\n return;\n }\n if (document.visibilityState === \"visible\") {\n scheduleFollowUp();\n }\n }\n\n /**\n * Attaching does not tick. A tick is a synchronous R call, and until the app\n * is started there is nothing to service, so the first tick is left to R\n * (NEED_SERVICE) or to the explicit wake() after startApp. Ticking on attach\n * put a long R call in front of the boot-time Comlink handshake.\n */\n function attach(next: Worker): void {\n if (worker === next && !stopped) {\n return;\n }\n stop();\n worker = next;\n stopped = false;\n worker.addEventListener(\"message\", onWorkerMessage);\n document.addEventListener(\"visibilitychange\", onVisibilityChange);\n }\n\n function stop(): void {\n stopped = true;\n tickInFlight = false;\n wakeQueued = false;\n cancelRaf();\n clearDelayTimers();\n document.removeEventListener(\"visibilitychange\", onVisibilityChange);\n if (worker) {\n worker.removeEventListener(\"message\", onWorkerMessage);\n worker = null;\n }\n }\n\n return { wake, scheduleDelay, attach, stop };\n}\n","import type { HostInboundMessage } from \"./wiring\";\n\nexport interface MsgTypes {\n REGISTER_HOST: string;\n HTTP_REQUEST: string;\n HTTP_RESPONSE: string;\n WS_PUSH: string;\n STOP: string;\n CLEAR_APP_CACHE: string;\n REGISTER_RESOURCE_PATHS: string;\n UPDATE_RESOURCE_PATH: string;\n REQUEST_COMLINK: string;\n REGISTER_SESSION: string;\n SESSION_ACK: string;\n REQUEST_SESSION_PORT: string;\n [key: string]: string;\n}\n\nexport interface ChannelTypes {\n HTTP_REQUEST: string;\n TCP_RESPONSE: string;\n WS_OPEN: string;\n WS_MESSAGE: string;\n WS_CLOSE: string;\n WS_RESPONSE: string;\n STDIN: string;\n [key: string]: string;\n}\n\nexport interface ComlinkTypes {\n PORT_HANDOFF: string;\n /** Absent on transport bundles built before the handoff ack was added. */\n PORT_HANDOFF_ACK?: string;\n [key: string]: string | undefined;\n}\n\n/** Loose shape of a channel message pushed into R (buildReq / WS frames). */\nexport interface ChannelMessageLike {\n type: string;\n uuid?: string;\n handle?: string;\n binary?: boolean;\n message?: unknown;\n method?: string;\n url?: string;\n headers?: Record<string, string>;\n body?: ArrayBuffer | number[] | null;\n req?: unknown;\n clientId?: string | null;\n data?: unknown;\n}\n\n/** Loose shape of an outbound message the bridge posts to the service worker. */\nexport interface OutboundMessage {\n type: string;\n uuid?: string;\n status?: number;\n headers?: Record<string, string>;\n body?: unknown;\n handle?: string;\n binary?: boolean;\n wsType?: string;\n message?: unknown;\n}\n\nexport interface HttpuvBridgeOptions {\n postOutbound?: (msg: OutboundMessage, transfer?: Transferable[]) => void;\n installSwListener?: boolean;\n pushToR?: (msg: ChannelMessageLike) => void;\n requestHostService?: () => void;\n scheduleHostDelay?: (delayMs: number) => void;\n}\n\n/**\n * The public surface of httpuv-web.js that Lucent consumes at runtime.\n * Kept as a hand-written contract so runApp/rWasmWorker stay decoupled from\n * the transport bundle's build graph (loaded via dynamic import).\n */\nexport interface HttpuvTransport {\n MSG: MsgTypes;\n CHANNEL: ChannelTypes;\n COMLINK: ComlinkTypes;\n REQUEST_TIMEOUT_MS: number;\n WARMUP_REQUEST_HEADER: string;\n installHttpuvBridge(options?: HttpuvBridgeOptions): unknown;\n flushDeferredOutbound(): void;\n pushInboundHostMessage(msg: HostInboundMessage): void;\n channelMessageToRExpr(msg: ChannelMessageLike): string;\n isLikelyStaticAsset(url: string): boolean;\n isSessionHttpRequest(url: string, prefix?: string): boolean;\n normalizeSessionHandle(handle: unknown): string;\n getShinyPrefix(): string;\n setShinyPrefix(prefix: string): void;\n resolveShinyPrefix(fromUrl: string | URL): string;\n shinyAppUrl(subpath?: string, fromUrl?: string | URL): string;\n isHttpuvDebug(): boolean;\n httpuvDebugLog(stage: string, ...args: unknown[]): void;\n enableHttpuvDebug(): void;\n}\n\nlet cached: Promise<HttpuvTransport> | null = null;\n\nfunction transportUrl(baseUrl: string): string {\n const base = new URL(baseUrl, self.location.href);\n return new URL(\"httpuv-web.js\", base).href;\n}\n\n/**\n * Dynamically load the httpuv transport module (`httpuv-web.js`) served from\n * `baseUrl` (typically Lucent dist). The result is cached; the specifier is a\n * runtime value so the bundler leaves it as a live `import()` instead of\n * inlining the transport.\n */\nexport function loadTransport(baseUrl: string): Promise<HttpuvTransport> {\n if (!cached) {\n const url = transportUrl(baseUrl);\n cached = import(/* @vite-ignore */ /* webpackIgnore: true */ url) as Promise<HttpuvTransport>;\n }\n return cached;\n}\n","import { lucentInfo } from \"./debug\";\nimport { RWASM } from \"./rwasm-constants\";\n\n/** Inbound HTTP request payload the service worker sends over Comlink. */\nexport interface HostHttpRequest {\n uuid?: string;\n method?: string;\n url?: string;\n headers?: Record<string, string>;\n body?: ArrayBuffer | null;\n clientId?: string | null;\n}\n\n/** Normalized inbound message handed to the R worker's push handler. */\nexport interface HostInboundMessage {\n type: string;\n uuid?: string;\n method?: string;\n url?: string;\n headers?: Record<string, string>;\n body?: ArrayBuffer | null;\n clientId?: string | null;\n}\n\nexport interface RHostHandlers {\n onHttpRequest: (msg: HostInboundMessage) => void | Promise<void>;\n onStop: () => void;\n getResourcePaths: () => Promise<Record<string, string>>;\n /** Comlink HTTP delivery port + one-way WS push port. */\n registerSwDelivery: (port: MessagePort, wsPushPort: MessagePort) => void;\n readVfsFile: (vfsDir: string, suffix: string) => Promise<ArrayBuffer | null>;\n readVfsFileAt: (vfsPath: string) => Promise<ArrayBuffer | null>;\n}\n\n/** API the R worker exposes to the service worker (Comlink target). */\nexport interface RHostApi {\n registerSwDelivery(port: MessagePort, wsPushPort: MessagePort): void | Promise<void>;\n deliverHttpRequest(req: HostHttpRequest): void | Promise<void>;\n getShinyResourcePaths(): Promise<Record<string, string>>;\n readVfsFile(vfsDir: string, suffix: string): Promise<ArrayBuffer | null>;\n readVfsFileAt(vfsPath: string): Promise<ArrayBuffer | null>;\n stop(): void | Promise<void>;\n}\n\n/** Reverse delivery API the service worker exposes to the R worker (Comlink; HTTP only). */\nexport interface SwDeliveryApi {\n deliverHttpResponse(resp: unknown): void | Promise<void>;\n}\n\n/** Times the handoff is re-posted before giving up (needs `ackType`). */\nconst HANDOFF_ATTEMPTS = 3;\n\n/** Wait for the service worker to confirm the port before re-posting it. */\nconst HANDOFF_ACK_TIMEOUT_MS = 5_000;\n\n/** Wait for the R worker to report both halves of the handshake complete. */\nconst COMLINK_READY_TIMEOUT_MS = 30_000;\n\nexport interface ComlinkHandshakeOptions {\n /**\n * Transport `COMLINK.PORT_HANDOFF_ACK` type. Omit for transport bundles built\n * before the ack existed: without it a missing `COMLINK_READY` cannot be told\n * apart from a slow one, so the handoff is posted only once.\n */\n ackType?: string;\n attempts?: number;\n ackTimeoutMs?: number;\n readyTimeoutMs?: number;\n}\n\ninterface Watcher<T> {\n promise: Promise<T>;\n cancel: () => void;\n}\n\ntype HandshakeOutcome = \"ready\" | \"acked\" | \"pending\";\n\n/**\n * Broker a single Comlink MessagePort between the service worker and R worker.\n * The SW creates a reverse delivery channel after wrapping the worker API.\n *\n * The R worker only reports `COMLINK_READY` once the SW has called back into it\n * (`registerSwDelivery`), so this handshake spans all three parties. A service\n * worker evicted while R boots can silently drop the handoff — `postMessage`\n * with a transferred port races the worker's restart — hence the retries.\n *\n * @param portHandoffType transport COMLINK.PORT_HANDOFF message type\n */\nexport async function connectHttpuvComlink(\n rWorker: Worker,\n portHandoffType: string,\n options: ComlinkHandshakeOptions = {},\n): Promise<void> {\n const {\n ackType,\n attempts = HANDOFF_ATTEMPTS,\n ackTimeoutMs = HANDOFF_ACK_TIMEOUT_MS,\n readyTimeoutMs = COMLINK_READY_TIMEOUT_MS,\n } = options;\n\n const ready = watchWorkerComlinkReady(rWorker);\n // Retries share the overall budget rather than extending it.\n const deadline = Date.now() + readyTimeoutMs;\n const maxAttempts = ackType ? Math.max(1, attempts) : 1;\n let connected = false;\n let acked = false;\n\n try {\n for (let attempt = 1; attempt <= maxAttempts && !connected && !acked; attempt += 1) {\n const ack = ackType ? watchServiceWorkerMessage(ackType) : null;\n try {\n postComlinkPorts(rWorker, portHandoffType);\n const outcome = await raceHandshake(ready.promise, ack?.promise, ackTimeoutMs);\n connected = outcome === \"ready\";\n acked = outcome === \"acked\";\n if (outcome === \"pending\") {\n lucentInfo(\n `[lucent] service worker did not confirm the Comlink port handoff (attempt ${attempt}/${maxAttempts})`,\n );\n }\n } finally {\n ack?.cancel();\n }\n }\n\n if (!connected) {\n await waitFor(ready.promise, Math.max(0, deadline - Date.now()), () =>\n comlinkTimeoutError(Boolean(ackType), acked),\n );\n }\n lucentInfo(\"[lucent] service worker <-> R worker connected (unified port)\");\n } finally {\n ready.cancel();\n }\n}\n\n/** Hand one end of a fresh channel to the SW and the other to the R worker. */\nfunction postComlinkPorts(rWorker: Worker, portHandoffType: string): void {\n const controller = navigator.serviceWorker.controller;\n if (!controller) {\n throw new Error(\"Service worker controller is not available for Comlink setup\");\n }\n\n const channel = new MessageChannel();\n controller.postMessage({ type: portHandoffType }, [channel.port1]);\n rWorker.postMessage({ type: RWASM.COMLINK_PORT }, [channel.port2]);\n}\n\nfunction comlinkTimeoutError(canAck: boolean, acked: boolean): Error {\n if (!canAck) {\n return new Error(\"Comlink setup timed out\");\n }\n if (acked) {\n return new Error(\n \"Comlink setup timed out: the service worker took the port but the R worker never completed setup\",\n );\n }\n return new Error(\n \"Comlink setup timed out: the service worker never acknowledged the port handoff\",\n );\n}\n\nasync function raceHandshake(\n ready: Promise<void>,\n ack: Promise<void> | undefined,\n timeoutMs: number,\n): Promise<HandshakeOutcome> {\n const timer = timeoutWatcher(timeoutMs);\n try {\n return await Promise.race<HandshakeOutcome>([\n ready.then((): HandshakeOutcome => \"ready\"),\n ...(ack ? [ack.then((): HandshakeOutcome => \"acked\")] : []),\n timer.promise.then((): HandshakeOutcome => \"pending\"),\n ]);\n } finally {\n timer.cancel();\n }\n}\n\nasync function waitFor(\n promise: Promise<void>,\n timeoutMs: number,\n onTimeout: () => Error,\n): Promise<void> {\n const timer = timeoutWatcher(timeoutMs);\n try {\n const timedOut = await Promise.race([\n promise.then(() => false),\n timer.promise.then(() => true),\n ]);\n if (timedOut) {\n throw onTimeout();\n }\n } finally {\n timer.cancel();\n }\n}\n\nfunction timeoutWatcher(ms: number): Watcher<void> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const promise = new Promise<void>((resolve) => {\n timer = setTimeout(resolve, ms);\n });\n return { promise, cancel: () => clearTimeout(timer) };\n}\n\n/** Settles when the R worker finishes (or fails) Comlink setup. */\nfunction watchWorkerComlinkReady(rWorker: Worker): Watcher<void> {\n let cleanup = () => {};\n const promise = new Promise<void>((resolve, reject) => {\n const onMessage = (event: MessageEvent) => {\n if (event.data?.type === RWASM.COMLINK_READY) {\n cleanup();\n resolve();\n }\n if (event.data?.type === RWASM.ERROR) {\n cleanup();\n reject(new Error(event.data.message ?? \"R worker Comlink setup failed\"));\n }\n };\n cleanup = () => rWorker.removeEventListener(\"message\", onMessage);\n rWorker.addEventListener(\"message\", onMessage);\n });\n return { promise, cancel: () => cleanup() };\n}\n\n/** Resolves on the first service worker message of `type`. */\nfunction watchServiceWorkerMessage(type: string): Watcher<void> {\n let cleanup = () => {};\n const promise = new Promise<void>((resolve) => {\n const onMessage = (event: MessageEvent) => {\n if (event.data?.type === type) {\n cleanup();\n resolve();\n }\n };\n cleanup = () => navigator.serviceWorker.removeEventListener(\"message\", onMessage);\n navigator.serviceWorker.addEventListener(\"message\", onMessage);\n });\n return { promise, cancel: () => cleanup() };\n}\n\n/**\n * Build the API exposed by the R worker for inbound httpuv traffic.\n *\n * @param httpRequestType transport MSG.HTTP_REQUEST message type\n */\nexport function createRHostApi(httpRequestType: string, handlers: RHostHandlers): RHostApi {\n const { onHttpRequest, onStop, getResourcePaths, registerSwDelivery, readVfsFile, readVfsFileAt } =\n handlers;\n return {\n registerSwDelivery(port: MessagePort, wsPushPort: MessagePort) {\n registerSwDelivery(port, wsPushPort);\n },\n deliverHttpRequest(req: HostHttpRequest) {\n return onHttpRequest({\n type: httpRequestType,\n uuid: req.uuid,\n method: req.method,\n url: req.url,\n headers: req.headers ?? {},\n body: req.body ?? null,\n clientId: req.clientId ?? null,\n });\n },\n getShinyResourcePaths() {\n return getResourcePaths();\n },\n readVfsFile(vfsDir: string, suffix: string) {\n return readVfsFile(vfsDir, suffix);\n },\n readVfsFileAt(vfsPath: string) {\n return readVfsFileAt(vfsPath);\n },\n stop() {\n onStop();\n },\n };\n}\n","import { LUCENT_CONFIG_PARAM, resolveLucentConfig, type LucentConfig } from \"./config\";\nimport { forwardRWorkerLog, isLucentDebug, lucentInfo } from \"./debug\";\nimport { RWASM } from \"./rwasm-constants\";\nimport { createServiceDriver, type ServiceDriver } from \"./rWasmServiceDriver\";\nimport { loadTransport, type HttpuvTransport } from \"./transport\";\nimport { connectHttpuvComlink } from \"./wiring\";\n\nconst RUN_WEB_APP_R = `\nlocal({\n loadNamespace(\"shiny\")\n shiny::startApp(appDir = \"webApp\", port = 3838L, host = \"127.0.0.1\", launch.browser = FALSE, quiet = TRUE)\n})\n`;\n\nconst config: LucentConfig = resolveLucentConfig();\n\nlet transport: HttpuvTransport | null = null;\nlet rWorker: Worker | null = null;\nlet rWorkerPromise: Promise<Worker> | null = null;\nlet comlinkConnected = false;\nlet comlinkPromise: Promise<void> | null = null;\nlet comlinkHandshakeInFlight = false;\nlet swRegistrationPromise: Promise<ServiceWorkerRegistration | null> | null = null;\nlet httpuvReadyPromise: Promise<void> | null = null;\nlet evalSeq = 0;\nlet serviceDriver: ServiceDriver | null = null;\n\nconst HTTPUV_SW_RELOAD_KEY = \"httpuv-sw-reload\";\n\ninterface RWorkerMessage {\n id?: string;\n type?: string;\n level?: string;\n text?: string;\n ok?: boolean;\n error?: string;\n message?: string;\n paths?: Record<string, string>;\n hadWork?: boolean;\n nextDelayMs?: number;\n delayMs?: number;\n percent?: number | null;\n downloadedBytes?: number;\n totalBytes?: number;\n phase?: string;\n}\n\nfunction requireTransport(): HttpuvTransport {\n if (!transport) {\n throw new Error(\"[lucent] transport not loaded yet\");\n }\n return transport;\n}\n\n/**\n * Absolute base URL under which the Shiny app is mounted. Deliberately NOT\n * derived from import.meta.url (the bundle lives in /lucent/dist/, which would\n * collide with real static files); defaults to the origin root → `/shiny/`.\n */\nfunction shinyBaseUrl(): string {\n return new URL(config.shinyBaseUrl, self.location.href).href;\n}\n\nfunction shinyPrefix(): string {\n return requireTransport().resolveShinyPrefix(shinyBaseUrl());\n}\n\nfunction appUrl(subpath = \"\"): string {\n return requireTransport().shinyAppUrl(subpath, shinyBaseUrl());\n}\n\nfunction serviceWorkerScriptUrl(): URL {\n const url = new URL(config.serviceWorkerUrl, self.location.href);\n // Tell the SW its mount prefix up-front so it intercepts correctly before the\n // REGISTER_HOST message arrives (avoids a first-load race on asset requests).\n url.searchParams.set(\"shinyPrefix\", shinyPrefix());\n return url;\n}\n\n/** Max default scope for the SW script (its directory). Avoid forcing `/` so\n * project GitHub Pages mounts (`/repo/httpuv-sw.js` → scope `/repo/`) work\n * without `Service-Worker-Allowed`. */\nfunction serviceWorkerScope(): string {\n return new URL(\"./\", serviceWorkerScriptUrl()).pathname;\n}\n\nfunction announceHostToServiceWorker(): boolean {\n const t = requireTransport();\n const prefix = shinyPrefix();\n const msg = {\n type: t.MSG.REGISTER_HOST,\n shinyPrefix: prefix,\n };\n const controller = navigator.serviceWorker.controller;\n if (controller) {\n controller.postMessage(msg);\n lucentInfo(\"[httpuv] Announced host to service worker\");\n return true;\n }\n return false;\n}\n\nasync function waitForServiceWorkerController(\n timeoutMs = 3_000,\n): Promise<ServiceWorker> {\n if (navigator.serviceWorker.controller) {\n return navigator.serviceWorker.controller;\n }\n\n await navigator.serviceWorker.ready;\n if (navigator.serviceWorker.controller) {\n return navigator.serviceWorker.controller;\n }\n\n return new Promise((resolve, reject) => {\n const deadline = setTimeout(() => {\n navigator.serviceWorker.removeEventListener(\"controllerchange\", onController);\n reject(new Error(\"timeout\"));\n }, timeoutMs);\n\n const onController = () => {\n if (navigator.serviceWorker.controller) {\n clearTimeout(deadline);\n navigator.serviceWorker.removeEventListener(\"controllerchange\", onController);\n resolve(navigator.serviceWorker.controller);\n }\n };\n\n navigator.serviceWorker.addEventListener(\"controllerchange\", onController);\n // Race: controller may appear between ready check and listener attach.\n onController();\n });\n}\n\nasync function waitForServiceWorkerInstall(\n reg: ServiceWorkerRegistration,\n timeoutMs = 15_000,\n): Promise<void> {\n const worker = reg.waiting ?? reg.installing ?? reg.active;\n if (!worker) {\n await navigator.serviceWorker.ready;\n return;\n }\n\n if (\n worker.state === \"activated\" ||\n worker.state === \"installed\"\n ) {\n return;\n }\n\n await new Promise<void>((resolve, reject) => {\n const onStateChange = () => {\n if (\n worker.state === \"activated\" ||\n worker.state === \"installed\" ||\n worker.state === \"redundant\"\n ) {\n cleanup();\n resolve();\n }\n };\n\n const deadline = setTimeout(() => {\n cleanup();\n if (worker.state === \"installed\") {\n resolve();\n return;\n }\n reject(new Error(`Service worker activation timed out (state: ${worker.state})`));\n }, timeoutMs);\n\n const cleanup = () => {\n clearTimeout(deadline);\n worker.removeEventListener(\"statechange\", onStateChange);\n };\n\n worker.addEventListener(\"statechange\", onStateChange);\n onStateChange();\n });\n}\n\nfunction serviceWorkerScriptPath(): string {\n return serviceWorkerScriptUrl().href.split(\"?\")[0];\n}\n\nfunction controllerMatchesExpectedScript(): boolean {\n const expected = serviceWorkerScriptPath();\n const current = navigator.serviceWorker.controller?.scriptURL.split(\"?\")[0];\n return current === expected;\n}\n\n/** Drop httpuv-sw registrations from an older script URL. */\nasync function cleanupStaleHttpuvServiceWorkers(): Promise<void> {\n const expected = serviceWorkerScriptPath();\n for (const reg of await navigator.serviceWorker.getRegistrations()) {\n const scriptUrls = [reg.active, reg.waiting, reg.installing]\n .filter((worker): worker is ServiceWorker => worker != null)\n .map((worker) => worker.scriptURL.split(\"?\")[0]);\n const isHttpuv = scriptUrls.some((url) => url.endsWith(\"/httpuv-sw.js\"));\n if (!isHttpuv) {\n continue;\n }\n if (!scriptUrls.includes(expected)) {\n lucentInfo(\"[httpuv] Unregistering stale service worker\", scriptUrls);\n await reg.unregister();\n }\n }\n}\n\nasync function registerHttpuvServiceWorker(): Promise<ServiceWorkerRegistration | null> {\n if (!(\"serviceWorker\" in navigator)) {\n console.warn(\"[httpuv] Service workers are not supported in this browser\");\n return null;\n }\n\n try {\n await cleanupStaleHttpuvServiceWorkers();\n\n const reg = await navigator.serviceWorker.register(serviceWorkerScriptUrl(), {\n scope: serviceWorkerScope(),\n updateViaCache: \"none\",\n });\n await waitForServiceWorkerInstall(reg);\n\n if (reg.waiting) {\n reg.waiting.postMessage({ type: \"SKIP_WAITING\" });\n await waitForServiceWorkerInstall(reg, 5_000).catch(() => undefined);\n }\n\n if (!navigator.serviceWorker.controller || !controllerMatchesExpectedScript()) {\n const reloaded = sessionStorage.getItem(HTTPUV_SW_RELOAD_KEY);\n if (!reloaded) {\n sessionStorage.setItem(HTTPUV_SW_RELOAD_KEY, \"1\");\n lucentInfo(\"[httpuv] Service worker installed — reloading once to activate\");\n window.location.reload();\n await new Promise(() => {});\n }\n console.warn(\n \"[httpuv] Page still not controlled by the expected worker; check Application → Service Workers for httpuv-sw.js errors\",\n );\n } else {\n sessionStorage.removeItem(HTTPUV_SW_RELOAD_KEY);\n }\n\n await waitForServiceWorkerController().catch(() => undefined);\n announceHostToServiceWorker();\n lucentInfo(\"[httpuv] Service worker registered\", {\n scope: reg.scope,\n shinyPrefix: shinyPrefix(),\n controller: Boolean(navigator.serviceWorker.controller),\n });\n return reg;\n } catch (err) {\n console.error(\"[httpuv] Service worker registration failed:\", err);\n throw err;\n }\n}\n\nfunction ensureHttpuvServiceWorker(): Promise<ServiceWorkerRegistration | null> {\n if (!swRegistrationPromise) {\n swRegistrationPromise = registerHttpuvServiceWorker();\n }\n return swRegistrationPromise;\n}\n\nfunction postToRWorker(\n worker: Worker,\n msg: Record<string, unknown>,\n transfer: Transferable[] = [],\n): Promise<RWorkerMessage> {\n const id = (msg.id as string | undefined) ?? `m${++evalSeq}`;\n const payload = { ...msg, id };\n\n return new Promise((resolve, reject) => {\n const onMessage = (event: MessageEvent) => {\n const data = event.data as RWorkerMessage | undefined;\n if (!data || data.id !== id) {\n if (data?.type === RWASM.ERROR && !msg.id) {\n worker.removeEventListener(\"message\", onMessage);\n reject(new Error(data.message ?? \"R worker failed\"));\n }\n return;\n }\n\n if (\n data.type === RWASM.EVAL_RESULT ||\n data.type === RWASM.STOPPED ||\n data.type === RWASM.RESOURCE_PATHS\n ) {\n worker.removeEventListener(\"message\", onMessage);\n if (data.type === RWASM.STOPPED || data.type === RWASM.RESOURCE_PATHS || data.ok) {\n resolve(data);\n } else {\n reject(new Error(data.error ?? \"eval failed\"));\n }\n }\n };\n\n worker.addEventListener(\"message\", onMessage);\n worker.postMessage(payload, transfer);\n });\n}\n\n/**\n * Serialize the host's resolved config into an absolute-URL payload for the\n * worker. Base URLs are made absolute against the host page so the worker (which\n * lives at a different path, /lucent/dist/) resolves them identically — the host\n * is the single source of truth for config.\n */\nfunction workerConfigParam(): string {\n const base = self.location.href;\n const abs = (u?: string): string | undefined => (u == null ? undefined : new URL(u, base).href);\n const payload: Partial<LucentConfig> = {\n transportBaseUrl: abs(config.transportBaseUrl),\n serviceWorkerUrl: abs(config.serviceWorkerUrl),\n rRuntimeBaseUrl: abs(config.rRuntimeBaseUrl),\n empackMetaUrl: abs(config.empackMetaUrl),\n empackPackagesBaseUrl: abs(config.empackPackagesBaseUrl),\n shinyBaseUrl: abs(config.shinyBaseUrl),\n };\n return JSON.stringify(payload);\n}\n\nfunction dispatchLucentEvent(\n name: \"lucent:download-progress\" | \"lucent:boot-status\" | \"lucent:ready\" | \"lucent:error\",\n detail?: Record<string, unknown>,\n): void {\n window.dispatchEvent(new CustomEvent(name, { detail }));\n}\n\nfunction reportBootStatus(\n phase: string,\n message: string,\n percent: number | null,\n): void {\n dispatchLucentEvent(\"lucent:boot-status\", { phase, message, percent });\n}\n\n/** Forward worker progress/log side-channels for the whole worker lifetime. */\nfunction installWorkerUiEvents(worker: Worker): void {\n worker.addEventListener(\"message\", (event: MessageEvent) => {\n const data = event.data as RWorkerMessage | undefined;\n if (data?.type === RWASM.LOG) {\n forwardRWorkerLog(data.level === \"error\" ? \"error\" : \"log\", data.text ?? \"\");\n return;\n }\n if (data?.type === RWASM.DOWNLOAD_PROGRESS) {\n dispatchLucentEvent(\"lucent:download-progress\", {\n percent: data.percent ?? null,\n downloadedBytes: data.downloadedBytes ?? 0,\n totalBytes: data.totalBytes ?? 0,\n });\n return;\n }\n if (data?.type === RWASM.BOOT_STATUS) {\n dispatchLucentEvent(\"lucent:boot-status\", {\n phase: data.phase ?? \"\",\n message: data.message ?? \"\",\n percent: data.percent ?? null,\n });\n }\n });\n}\n\nfunction createRWorker(): Promise<Worker> {\n const workerUrl = new URL(\"./rWasmWorker.js\", import.meta.url);\n workerUrl.searchParams.set(LUCENT_CONFIG_PARAM, workerConfigParam());\n if (requireTransport().isHttpuvDebug()) {\n workerUrl.searchParams.set(\"httpuvDebug\", \"1\");\n }\n const worker = new Worker(workerUrl, { type: \"module\" });\n installWorkerUiEvents(worker);\n\n return new Promise((resolve, reject) => {\n const onBoot = (event: MessageEvent) => {\n const data = event.data as RWorkerMessage | undefined;\n if (\n data?.type === RWASM.LOG ||\n data?.type === RWASM.DOWNLOAD_PROGRESS ||\n data?.type === RWASM.BOOT_STATUS\n ) {\n // Handled by installWorkerUiEvents.\n return;\n }\n if (data?.type === RWASM.READY) {\n worker.removeEventListener(\"message\", onBoot);\n lucentInfo(\"[runApp] R.wasm worker ready\");\n resolve(worker);\n return;\n }\n if (data?.type === RWASM.ERROR) {\n worker.removeEventListener(\"message\", onBoot);\n reject(new Error(data.message ?? \"R worker bootstrap failed\"));\n }\n };\n\n worker.addEventListener(\"message\", onBoot);\n worker.addEventListener(\"error\", (event) => {\n worker.removeEventListener(\"message\", onBoot);\n const detail = [event.message, event.filename, event.lineno]\n .filter(Boolean)\n .join(\" \");\n reject(new Error(detail ? `R worker failed to load: ${detail}` : \"R worker failed to load\"));\n });\n });\n}\n\nasync function ensureRWorker(): Promise<Worker> {\n if (rWorker) {\n return rWorker;\n }\n if (!rWorkerPromise) {\n rWorkerPromise = createRWorker().then((worker) => {\n rWorker = worker;\n if (!serviceDriver) {\n serviceDriver = createServiceDriver({\n onHadWork: scheduleDebouncedResourcePathSync,\n });\n }\n serviceDriver.attach(worker);\n return worker;\n });\n }\n return rWorkerPromise;\n}\n\n/**\n * Establish the host <-> service worker <-> R worker Comlink link, coalescing\n * every caller onto a single handshake.\n *\n * Two handshakes in flight at once are destructive: each COMLINK_PORT resets the\n * worker's readiness flags, so the second handoff can clear the first one's\n * delivery registration, and the host cannot tell the two acks apart. A\n * controllerchange during boot used to start exactly such a competing handshake.\n */\nfunction ensureComlinkConnected(): Promise<void> {\n if (comlinkPromise && (comlinkConnected || comlinkHandshakeInFlight)) {\n return comlinkPromise;\n }\n\n comlinkHandshakeInFlight = true;\n const handshake = (async () => {\n lucentInfo(\"[runApp] Waiting for R worker and service worker…\");\n const [worker] = await Promise.all([ensureRWorker(), ensureHttpuvServiceWorker()]);\n if (!navigator.serviceWorker.controller || !controllerMatchesExpectedScript()) {\n throw new Error(\"Service worker controller is not available\");\n }\n lucentInfo(\"[runApp] Connecting Comlink…\");\n const { COMLINK } = requireTransport();\n await connectHttpuvComlink(worker, COMLINK.PORT_HANDOFF, {\n ackType: COMLINK.PORT_HANDOFF_ACK,\n });\n comlinkConnected = true;\n })();\n\n const clearInFlight = (): void => {\n comlinkHandshakeInFlight = false;\n };\n handshake.then(clearInFlight, clearInFlight);\n\n comlinkPromise = handshake;\n return handshake;\n}\n\n/**\n * Force the next ensureHttpuvReady() to redo the handshake. An in-flight\n * handshake is left in place as the coalescing target rather than raced.\n */\nfunction invalidateComlink(): void {\n comlinkConnected = false;\n httpuvReadyPromise = null;\n if (!comlinkHandshakeInFlight) {\n comlinkPromise = null;\n }\n}\n\nfunction reconnectComlinkAfterServiceWorkerUpdate(): void {\n invalidateComlink();\n announceHostToServiceWorker();\n void ensureComlinkConnected().catch((err) => {\n console.warn(\"[httpuv] Comlink reconnect after service worker update failed:\", err);\n });\n}\n\nexport async function ensureHttpuvReady(): Promise<void> {\n const t = requireTransport();\n t.setShinyPrefix(shinyPrefix());\n // Do not treat a stale resolved promise as ready after SW reset/reconnect.\n if (comlinkConnected && comlinkPromise) {\n return comlinkPromise;\n }\n httpuvReadyPromise = ensureComlinkConnected();\n return httpuvReadyPromise;\n}\n\nfunction stopRunningApp(): void {\n navigator.serviceWorker.controller?.postMessage({ type: requireTransport().MSG.STOP });\n\n serviceDriver?.stop();\n\n if (rWorker) {\n rWorker.postMessage({ type: RWASM.STOP_APP });\n }\n lucentInfo(\"[runApp] App stopped\");\n}\n\nfunction loadViewerFrame(): void {\n const frame = document.getElementById(\"app-frame\") as HTMLIFrameElement | null;\n const url = appUrl();\n if (frame) {\n frame.src = url;\n }\n lucentInfo(\"[runApp] Viewer iframe →\", url);\n}\n\nfunction clearAppDocumentCache(): void {\n lastResourcePaths = {};\n navigator.serviceWorker.controller?.postMessage({\n type: requireTransport().MSG.CLEAR_APP_CACHE,\n });\n}\n\nconst RESOURCE_PATH_SYNC_DEBOUNCE_MS = 100;\nlet resourcePathSyncTimer: ReturnType<typeof setTimeout> | null = null;\nlet lastResourcePaths: Record<string, string> = {};\nlet resourcePathSyncInFlight = false;\n\nfunction scheduleDebouncedResourcePathSync(): void {\n if (resourcePathSyncTimer) {\n clearTimeout(resourcePathSyncTimer);\n }\n resourcePathSyncTimer = setTimeout(() => {\n resourcePathSyncTimer = null;\n if (rWorker) {\n void syncResourcePathsIncremental(rWorker);\n }\n }, RESOURCE_PATH_SYNC_DEBOUNCE_MS);\n}\n\nfunction rememberResourcePaths(paths: Record<string, string>): void {\n lastResourcePaths = { ...paths };\n}\n\nasync function syncResourcePathsToServiceWorker(worker: Worker): Promise<void> {\n const controller = navigator.serviceWorker.controller;\n if (!controller) {\n return;\n }\n\n try {\n const data = await postToRWorker(worker, { type: RWASM.GET_RESOURCE_PATHS });\n const paths = data.paths ?? {};\n rememberResourcePaths(paths);\n controller.postMessage({ type: requireTransport().MSG.REGISTER_RESOURCE_PATHS, paths });\n if (Object.keys(paths).length > 0) {\n lucentInfo(\"[runApp] synced\", Object.keys(paths).length, \"resource path(s) to SW\");\n }\n } catch (err) {\n console.warn(\"[runApp] resource path sync failed; SW will fall through to R\", err);\n }\n}\n\n/** Diff resourcePaths() against the last SW snapshot and send incremental updates. */\nasync function syncResourcePathsIncremental(worker: Worker): Promise<void> {\n if (resourcePathSyncInFlight) {\n scheduleDebouncedResourcePathSync();\n return;\n }\n const controller = navigator.serviceWorker.controller;\n if (!controller) {\n return;\n }\n\n resourcePathSyncInFlight = true;\n try {\n const data = await postToRWorker(worker, { type: RWASM.GET_RESOURCE_PATHS });\n const paths = data.paths ?? {};\n const updateType = requireTransport().MSG.UPDATE_RESOURCE_PATH;\n let changed = 0;\n for (const prefix of Object.keys(paths)) {\n if (lastResourcePaths[prefix] !== paths[prefix]) {\n controller.postMessage({ type: updateType, prefix, dir: paths[prefix] });\n changed += 1;\n }\n }\n for (const prefix of Object.keys(lastResourcePaths)) {\n if (!(prefix in paths)) {\n controller.postMessage({ type: updateType, prefix, dir: \"\" });\n changed += 1;\n }\n }\n rememberResourcePaths(paths);\n if (changed > 0) {\n lucentInfo(\"[runApp] updated\", changed, \"resource path(s) on SW\");\n }\n } catch (err) {\n console.warn(\"[runApp] incremental resource path sync failed\", err);\n } finally {\n resourcePathSyncInFlight = false;\n }\n}\n\nasync function waitForShinyHttpReady(worker: Worker): Promise<void> {\n const t = requireTransport();\n const url = appUrl();\n reportBootStatus(\"warmup\", \"Warming up Shiny…\", 92);\n lucentInfo(\"[runApp] Warming up Shiny (may take a minute on first load)…\", url);\n const res = await fetch(url, {\n cache: \"no-store\",\n headers: { [t.WARMUP_REQUEST_HEADER]: \"1\" },\n signal: AbortSignal.timeout(t.REQUEST_TIMEOUT_MS),\n });\n if (!res.ok) {\n throw new Error(`Shiny warmup GET ${url} failed: HTTP ${res.status}`);\n }\n lucentInfo(\"[runApp] Shiny warmup OK (HTTP\", res.status + \")\");\n await syncResourcePathsToServiceWorker(worker);\n}\n\n/**\n * Start (or restart) the Shiny app already present in the VFS at `/webApp`\n * (populated via empack pack dir + append during R bootstrap).\n */\nexport async function runApp(): Promise<number> {\n const worker = await ensureRWorker();\n\n clearAppDocumentCache();\n await postToRWorker(worker, { type: RWASM.STOP_APP });\n\n // Remount only when forced (?remountRHome=1) or when the worker detects that\n // the empack / runtime URLs changed since the last populate.\n const forceRemount =\n new URLSearchParams(self.location.search).get(\"remountRHome\") === \"1\";\n await postToRWorker(worker, { type: RWASM.REMOUNT_R_HOME, force: forceRemount });\n\n lucentInfo(\"[runApp] worker eval\", RUN_WEB_APP_R);\n reportBootStatus(\"start-app\", \"Starting Shiny…\", 85);\n await postToRWorker(worker, {\n type: RWASM.EVAL,\n code: RUN_WEB_APP_R,\n });\n\n // Host rAF owns service ticks after startApp; wake once so init/flush can run.\n serviceDriver?.attach(worker);\n serviceDriver?.wake();\n\n return 0;\n}\n\nasync function startShinyApp(): Promise<void> {\n await ensureHttpuvReady();\n const worker = await ensureRWorker();\n await runApp();\n // Remount / SW activate can drop the worker link after the first handshake.\n // Re-assert Comlink before warmup so GET /shiny/ does not race PORT_HANDOFF.\n invalidateComlink();\n await ensureHttpuvReady();\n await waitForShinyHttpReady(worker);\n loadViewerFrame();\n dispatchLucentEvent(\"lucent:ready\");\n}\n\nfunction installHostServiceWorkerListeners(): void {\n navigator.serviceWorker.addEventListener(\"controllerchange\", () => {\n reconnectComlinkAfterServiceWorkerUpdate();\n });\n\n navigator.serviceWorker.addEventListener(\"message\", (event) => {\n if (event.data?.type === requireTransport().MSG.REQUEST_COMLINK) {\n reconnectComlinkAfterServiceWorkerUpdate();\n }\n });\n\n // Chromium stops the SW while idle and forgets hostClientId. Re-announce the\n // Lucent shell (not the /shiny/ iframe) whenever we become visible again.\n const reassertHost = () => {\n announceHostToServiceWorker();\n if (!comlinkConnected) {\n reconnectComlinkAfterServiceWorkerUpdate();\n }\n };\n document.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"visible\") {\n reassertHost();\n }\n });\n window.addEventListener(\"pageshow\", reassertHost);\n window.addEventListener(\"focus\", () => {\n announceHostToServiceWorker();\n });\n}\n\nfunction installGlobalHelpers(): void {\n const lucent = {\n shinyUrl: (subpath = \"\") => appUrl(subpath),\n ensureHttpuvReady,\n stopRunningApp,\n enableHttpuvDebug: () => requireTransport().enableHttpuvDebug(),\n /** Quick check that the worker responds. */\n ping: () => lucent.evalR(\"1+1\"),\n async evalR(code: string): Promise<void> {\n const worker = await ensureRWorker();\n await postToRWorker(worker, {\n type: RWASM.EVAL,\n code,\n });\n },\n startShinyApp: () => startShinyApp(),\n async testVirtualSocket(message = '{\"method\":\"ping\"}') {\n await ensureHttpuvReady();\n const controller = navigator.serviceWorker.controller;\n if (!controller) {\n console.warn(\n \"[lucent] No service worker controller — fetch may not be intercepted; unregister old workers and hard-refresh\",\n );\n throw new Error(\"no service worker controller\");\n }\n\n const openUrl = new URL(\"__session__/open\", appUrl());\n lucentInfo(\"[lucent] testVirtualSocket: open\", openUrl.href);\n const openRes = await fetch(openUrl, { method: \"POST\" });\n if (!openRes.ok) {\n throw new Error(`session open failed: HTTP ${openRes.status} ${await openRes.text()}`);\n }\n const { handle } = (await openRes.json()) as { handle: string };\n lucentInfo(\"[lucent] testVirtualSocket: handle\", handle);\n\n const channel = new MessageChannel();\n const ack = new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => reject(new Error(\"session ACK timed out\")), 5_000);\n channel.port1.onmessage = (event: MessageEvent<{ type?: string }>) => {\n if (event.data?.type === requireTransport().MSG.SESSION_ACK) {\n clearTimeout(timer);\n resolve();\n }\n };\n });\n controller.postMessage(\n { type: requireTransport().MSG.REGISTER_SESSION, handle },\n [channel.port2],\n );\n await ack;\n lucentInfo(\"[lucent] testVirtualSocket: session port registered\");\n\n const sendUrl = new URL(`__session__/send?handle=${encodeURIComponent(handle)}`, appUrl());\n const sendRes = await fetch(sendUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"text/plain\" },\n body: message,\n });\n if (!sendRes.ok && sendRes.status !== 204) {\n throw new Error(`session send failed: HTTP ${sendRes.status}`);\n }\n\n channel.port1.close();\n const result = { handle, registered: true, sendStatus: sendRes.status };\n lucentInfo(\"[lucent] testVirtualSocket: result\", result);\n return result;\n },\n };\n (globalThis as unknown as { __lucent?: typeof lucent }).__lucent = lucent;\n}\n\nasync function main(): Promise<void> {\n transport = await loadTransport(config.transportBaseUrl);\n transport.setShinyPrefix(shinyPrefix());\n\n installHostServiceWorkerListeners();\n installGlobalHelpers();\n\n if (isLucentDebug()) {\n lucentInfo(\"[runApp] httpuv debug tracing enabled (?httpuvDebug=1)\");\n }\n\n void ensureHttpuvServiceWorker().catch((err) => {\n console.error(\"[httpuv] Service worker setup failed:\", err);\n });\n\n await startShinyApp();\n}\n\nvoid main().catch((err) => {\n console.error(\"[runApp] Failed to start:\", err);\n dispatchLucentEvent(\"lucent:error\", {\n message: err instanceof Error ? err.message : String(err),\n });\n});\n"]}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Virtual WebSocket for Shiny in the browser.
3
+ * Loaded as a module in the Shiny app iframe; overrides Shiny.createSocket.
4
+ *
5
+ * Server→client frames arrive on a dedicated MessagePort registered with the
6
+ * httpuv service worker (no recv long-poll). open/send/close still use fetch.
7
+ *
8
+ * After the browser stops the SW while idle, the port is gone but the socket
9
+ * stays logically open: we re-REGISTER_SESSION on send, visibilitychange, and
10
+ * when the SW asks via REQUEST_SESSION_PORT.
11
+ */
12
+ /** Minimal WebSocket stand-in using session fetch + MessagePort push delivery. */
13
+ declare class VirtualShinySocket {
14
+ static readonly CONNECTING = 0;
15
+ static readonly OPEN = 1;
16
+ static readonly CLOSING = 2;
17
+ static readonly CLOSED = 3;
18
+ readyState: number;
19
+ binaryType: BinaryType;
20
+ private _handle;
21
+ private _active;
22
+ private _port;
23
+ private _registering;
24
+ /** Last time a WS_PUSH arrived — used to detect orphaned ports after SW idle kill. */
25
+ private _lastPushAt;
26
+ onopen: ((event: Event) => void) | null;
27
+ onmessage: ((event: MessageEvent) => void) | null;
28
+ onclose: ((event: CloseEvent) => void) | null;
29
+ onerror: ((event: Event) => void) | null;
30
+ constructor();
31
+ private _connect;
32
+ /**
33
+ * Ensure the SW has a live MessagePort for this session.
34
+ * Safe to call repeatedly after idle SW restarts.
35
+ * @param force when true, replace any existing port (recovery / stale paths).
36
+ * Ordinary rapid send() must not force — re-registering mid-flight drops
37
+ * SW→iframe frames on Chromium. After idle, force once so a dead port
38
+ * (SW stopped, client still holds MessagePort) is replaced before replies.
39
+ */
40
+ ensurePort(force?: boolean): Promise<void>;
41
+ /** Hand a MessagePort to the SW and wait for SESSION_ACK. */
42
+ private _registerSessionPort;
43
+ private _ackPush;
44
+ private _onPortMessage;
45
+ private _teardownPort;
46
+ send(data: string | ArrayBuffer | ArrayBufferView): void;
47
+ close(code?: number, reason?: string): void;
48
+ private _finishClose;
49
+ }
50
+ /** Install VirtualShinySocket as Shiny.createSocket (call before Shiny connects). */
51
+ declare function installVirtualShinySocket(): void;
52
+
53
+ export { VirtualShinySocket, installVirtualShinySocket };
@@ -0,0 +1,388 @@
1
+ // src/httpuv/constants.ts
2
+ var WS_FRAME = {
3
+ SEND: "websocket.send",
4
+ CLOSE: "websocket.close"
5
+ };
6
+ var MSG = {
7
+ REGISTER_HOST: "httpuv_register_host",
8
+ HTTP_REQUEST: "httpuv_http_request",
9
+ HTTP_RESPONSE: "httpuv_http_response",
10
+ WS_PUSH: "httpuv_ws_push",
11
+ /** Iframe → SW (on session port): frame delivered to Shiny.createSocket. */
12
+ WS_PUSH_ACK: "httpuv_ws_push_ack",
13
+ STOP: "httpuv_stop",
14
+ /** Drop cached GET /shiny/ without tearing down the R worker (app restart). */
15
+ CLEAR_APP_CACHE: "httpuv_clear_app_cache",
16
+ /** Host -> SW: full shiny::resourcePaths() map (warmup). */
17
+ REGISTER_RESOURCE_PATHS: "httpuv_register_resource_paths",
18
+ /** Host -> SW: upsert or remove one addResourcePath prefix (empty dir removes). */
19
+ UPDATE_RESOURCE_PATH: "httpuv_update_resource_path",
20
+ /** SW -> host: Comlink to the R worker was lost (e.g. after SW update). */
21
+ REQUEST_COMLINK: "httpuv_request_comlink",
22
+ /** Iframe → SW: transfer a MessagePort for session WS push delivery. */
23
+ REGISTER_SESSION: "httpuv_register_session",
24
+ /** SW → iframe (on session port): registration accepted. */
25
+ SESSION_ACK: "httpuv_session_ack",
26
+ /** SW → iframe client: session MessagePort was lost (e.g. SW idle restart); re-REGISTER_SESSION. */
27
+ REQUEST_SESSION_PORT: "httpuv_request_session_port"
28
+ };
29
+
30
+ // src/httpuv/debug.ts
31
+ function isHttpuvDebug() {
32
+ if (globalThis.__HTTPUV_DEBUG__) {
33
+ return true;
34
+ }
35
+ try {
36
+ if (typeof location !== "undefined") {
37
+ const params = new URLSearchParams(location.search);
38
+ if (params.has("httpuvDebug") || params.get("debug") === "httpuv") {
39
+ return true;
40
+ }
41
+ }
42
+ if (typeof localStorage !== "undefined" && localStorage.getItem("shinyForgeDebug") === "1") {
43
+ return true;
44
+ }
45
+ if (typeof self !== "undefined" && self.location?.href) {
46
+ const params = new URL(self.location.href).searchParams;
47
+ if (params.has("httpuvDebug") || params.get("debug") === "httpuv") {
48
+ return true;
49
+ }
50
+ }
51
+ } catch {
52
+ }
53
+ return false;
54
+ }
55
+ function httpuvDebugLog(stage, ...args) {
56
+ if (!isHttpuvDebug()) {
57
+ return;
58
+ }
59
+ console.info(`[httpuv-debug:${stage}]`, ...args);
60
+ }
61
+
62
+ // src/httpuv/shiny-socket.ts
63
+ var SESSION_REGISTER_TIMEOUT_MS = 5e3;
64
+ var SESSION_PORT_STALE_MS = 15e3;
65
+ function sessionUrl(action, opts = {}) {
66
+ const base = new URL("__session__/", location.href);
67
+ const url = new URL(action.replace(/^\//, ""), base);
68
+ if (opts.handle) {
69
+ url.searchParams.set("handle", opts.handle);
70
+ }
71
+ return url.href;
72
+ }
73
+ var socketsByHandle = /* @__PURE__ */ new Map();
74
+ var _VirtualShinySocket = class _VirtualShinySocket {
75
+ constructor() {
76
+ this.readyState = _VirtualShinySocket.CONNECTING;
77
+ this.binaryType = "arraybuffer";
78
+ this._handle = null;
79
+ this._active = false;
80
+ this._port = null;
81
+ this._registering = null;
82
+ /** Last time a WS_PUSH arrived — used to detect orphaned ports after SW idle kill. */
83
+ this._lastPushAt = 0;
84
+ this.onopen = null;
85
+ this.onmessage = null;
86
+ this.onclose = null;
87
+ this.onerror = null;
88
+ void this._connect();
89
+ }
90
+ async _connect() {
91
+ try {
92
+ const openUrl = sessionUrl("open");
93
+ httpuvDebugLog("socket-open", openUrl);
94
+ const res = await fetch(openUrl, { method: "POST" });
95
+ if (!res.ok) {
96
+ throw new Error(`session open failed: HTTP ${res.status}`);
97
+ }
98
+ const { handle } = await res.json();
99
+ if (!handle) {
100
+ throw new Error("session open response missing handle");
101
+ }
102
+ this._handle = String(handle);
103
+ this.readyState = _VirtualShinySocket.OPEN;
104
+ this._active = true;
105
+ socketsByHandle.set(this._handle, this);
106
+ await this.ensurePort();
107
+ this.onopen?.(new Event("open"));
108
+ } catch (err) {
109
+ console.error("[shiny-socket] connect failed", err);
110
+ this._teardownPort();
111
+ this.readyState = _VirtualShinySocket.CLOSED;
112
+ this.onerror?.(new Event("error"));
113
+ this.onclose?.(new CloseEvent("close", { code: 1006, wasClean: false }));
114
+ }
115
+ }
116
+ /**
117
+ * Ensure the SW has a live MessagePort for this session.
118
+ * Safe to call repeatedly after idle SW restarts.
119
+ * @param force when true, replace any existing port (recovery / stale paths).
120
+ * Ordinary rapid send() must not force — re-registering mid-flight drops
121
+ * SW→iframe frames on Chromium. After idle, force once so a dead port
122
+ * (SW stopped, client still holds MessagePort) is replaced before replies.
123
+ */
124
+ ensurePort(force = false) {
125
+ if (!this._active || !this._handle) {
126
+ return Promise.resolve();
127
+ }
128
+ if (!force && this._port) {
129
+ return Promise.resolve();
130
+ }
131
+ if (this._registering) {
132
+ return this._registering;
133
+ }
134
+ this._registering = this._registerSessionPort(this._handle).finally(() => {
135
+ this._registering = null;
136
+ });
137
+ return this._registering;
138
+ }
139
+ /** Hand a MessagePort to the SW and wait for SESSION_ACK. */
140
+ async _registerSessionPort(handle) {
141
+ const controller = navigator.serviceWorker?.controller;
142
+ if (!controller) {
143
+ throw new Error("no service worker controller for session port");
144
+ }
145
+ if (this._port) {
146
+ try {
147
+ this._port.close();
148
+ } catch {
149
+ }
150
+ this._port = null;
151
+ }
152
+ const channel = new MessageChannel();
153
+ this._port = channel.port1;
154
+ const acked = new Promise((resolve, reject) => {
155
+ const timer = setTimeout(() => {
156
+ reject(new Error("session port registration timed out"));
157
+ }, SESSION_REGISTER_TIMEOUT_MS);
158
+ this._port.onmessage = (event) => {
159
+ const data = event.data;
160
+ if (data?.type === MSG.SESSION_ACK) {
161
+ clearTimeout(timer);
162
+ this._port.onmessage = (ev) => this._onPortMessage(ev);
163
+ resolve();
164
+ return;
165
+ }
166
+ this._onPortMessage(event);
167
+ };
168
+ this._port.onmessageerror = () => {
169
+ clearTimeout(timer);
170
+ reject(new Error("session port messageerror"));
171
+ };
172
+ });
173
+ httpuvDebugLog("socket-register-session", { handle });
174
+ controller.postMessage({ type: MSG.REGISTER_SESSION, handle }, [channel.port2]);
175
+ await acked;
176
+ }
177
+ _ackPush(pushId) {
178
+ if (typeof pushId !== "number" || !this._port) {
179
+ return;
180
+ }
181
+ try {
182
+ this._port.postMessage({ type: MSG.WS_PUSH_ACK, pushId });
183
+ } catch (err) {
184
+ console.warn("[shiny-socket] WS_PUSH_ACK failed", err);
185
+ }
186
+ }
187
+ _onPortMessage(event) {
188
+ if (!this._active) {
189
+ return;
190
+ }
191
+ const data = event.data;
192
+ if (!data || typeof data !== "object") {
193
+ return;
194
+ }
195
+ if (data.type !== MSG.WS_PUSH && data.wsType == null && data.message === void 0) {
196
+ return;
197
+ }
198
+ const wsType = data.wsType ?? WS_FRAME.SEND;
199
+ if (wsType === WS_FRAME.CLOSE) {
200
+ let code = 1e3;
201
+ let reason = "";
202
+ try {
203
+ const raw = data.message;
204
+ if (typeof raw === "string" && raw) {
205
+ const payload2 = JSON.parse(raw);
206
+ code = Number(payload2.code ?? code);
207
+ reason = String(payload2.reason ?? "");
208
+ }
209
+ } catch {
210
+ }
211
+ this._ackPush(data.pushId);
212
+ this._finishClose(code, reason, true);
213
+ return;
214
+ }
215
+ const binary = Boolean(data.binary);
216
+ let payload;
217
+ if (binary) {
218
+ if (data.message instanceof ArrayBuffer) {
219
+ payload = data.message;
220
+ } else if (ArrayBuffer.isView(data.message)) {
221
+ const view = data.message;
222
+ payload = view.buffer.slice(
223
+ view.byteOffset,
224
+ view.byteOffset + view.byteLength
225
+ );
226
+ } else if (typeof data.message === "string") {
227
+ payload = data.message;
228
+ } else {
229
+ payload = new ArrayBuffer(0);
230
+ }
231
+ } else if (typeof data.message === "string") {
232
+ payload = data.message;
233
+ } else if (data.message instanceof ArrayBuffer) {
234
+ payload = new TextDecoder().decode(data.message);
235
+ } else if (ArrayBuffer.isView(data.message)) {
236
+ payload = new TextDecoder().decode(data.message);
237
+ } else {
238
+ payload = String(data.message ?? "");
239
+ }
240
+ const bytes = typeof payload === "string" ? payload.length : payload.byteLength;
241
+ httpuvDebugLog("socket-recv", {
242
+ wsType,
243
+ binary,
244
+ bytes
245
+ });
246
+ this._lastPushAt = Date.now();
247
+ this.onmessage?.(new MessageEvent("message", { data: payload }));
248
+ this._ackPush(data.pushId);
249
+ }
250
+ _teardownPort() {
251
+ this._active = false;
252
+ if (this._handle) {
253
+ socketsByHandle.delete(this._handle);
254
+ }
255
+ if (this._port) {
256
+ try {
257
+ this._port.close();
258
+ } catch {
259
+ }
260
+ this._port = null;
261
+ }
262
+ }
263
+ send(data) {
264
+ if (this.readyState !== _VirtualShinySocket.OPEN || !this._handle) {
265
+ throw new Error("WebSocket is not open");
266
+ }
267
+ let body;
268
+ let byteLen;
269
+ let isBinary;
270
+ if (typeof data === "string") {
271
+ body = data;
272
+ byteLen = data.length;
273
+ isBinary = false;
274
+ } else if (data instanceof ArrayBuffer) {
275
+ body = data;
276
+ byteLen = data.byteLength;
277
+ isBinary = true;
278
+ } else {
279
+ body = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
280
+ byteLen = data.byteLength;
281
+ isBinary = true;
282
+ }
283
+ const handle = this._handle;
284
+ const sendUrl = sessionUrl("send", { handle });
285
+ httpuvDebugLog("socket-send", sendUrl, {
286
+ binary: isBinary,
287
+ bytes: byteLen
288
+ });
289
+ const stale = !this._port || !this._lastPushAt || Date.now() - this._lastPushAt > SESSION_PORT_STALE_MS;
290
+ void this.ensurePort(stale).catch((err) => {
291
+ console.warn("[shiny-socket] ensurePort before send failed", err);
292
+ }).then(
293
+ () => fetch(sendUrl, {
294
+ method: "POST",
295
+ headers: isBinary ? {} : { "Content-Type": "text/plain; charset=UTF-8" },
296
+ body
297
+ })
298
+ ).catch((err) => {
299
+ console.error("[shiny-socket] send failed", err);
300
+ });
301
+ }
302
+ close(code = 1e3, reason = "") {
303
+ if (this.readyState === _VirtualShinySocket.CLOSED || this.readyState === _VirtualShinySocket.CLOSING) {
304
+ return;
305
+ }
306
+ this.readyState = _VirtualShinySocket.CLOSING;
307
+ const handle = this._handle;
308
+ this._active = false;
309
+ if (handle) {
310
+ const closeUrl = sessionUrl("close", { handle });
311
+ void fetch(closeUrl, {
312
+ method: "POST",
313
+ headers: { "Content-Type": "application/json" },
314
+ body: JSON.stringify({ code, reason })
315
+ }).catch((err) => {
316
+ console.error("[shiny-socket] close failed", err);
317
+ });
318
+ }
319
+ this._finishClose(code, reason, true);
320
+ }
321
+ _finishClose(code, reason, wasClean) {
322
+ if (this.readyState === _VirtualShinySocket.CLOSED) {
323
+ return;
324
+ }
325
+ this._teardownPort();
326
+ this.readyState = _VirtualShinySocket.CLOSED;
327
+ this.onclose?.(new CloseEvent("close", { code, reason, wasClean }));
328
+ }
329
+ };
330
+ _VirtualShinySocket.CONNECTING = 0;
331
+ _VirtualShinySocket.OPEN = 1;
332
+ _VirtualShinySocket.CLOSING = 2;
333
+ _VirtualShinySocket.CLOSED = 3;
334
+ var VirtualShinySocket = _VirtualShinySocket;
335
+ function reregisterAllSockets() {
336
+ for (const sock of socketsByHandle.values()) {
337
+ void sock.ensurePort(true).catch((err) => {
338
+ console.warn("[shiny-socket] ensurePort failed", err);
339
+ });
340
+ }
341
+ }
342
+ function installSessionPortRecovery() {
343
+ if (typeof navigator === "undefined" || !navigator.serviceWorker) {
344
+ return;
345
+ }
346
+ navigator.serviceWorker.addEventListener("message", (event) => {
347
+ const data = event.data;
348
+ if (!data || data.type !== MSG.REQUEST_SESSION_PORT) {
349
+ return;
350
+ }
351
+ const handle = data.handle ? String(data.handle) : "";
352
+ const sock = handle ? socketsByHandle.get(handle) : void 0;
353
+ if (sock) {
354
+ void sock.ensurePort(true).catch((err) => {
355
+ console.warn("[shiny-socket] REQUEST_SESSION_PORT ensurePort failed", err);
356
+ });
357
+ return;
358
+ }
359
+ reregisterAllSockets();
360
+ });
361
+ document.addEventListener("visibilitychange", () => {
362
+ if (document.visibilityState === "visible") {
363
+ reregisterAllSockets();
364
+ }
365
+ });
366
+ navigator.serviceWorker.addEventListener("controllerchange", () => {
367
+ reregisterAllSockets();
368
+ });
369
+ }
370
+ function installVirtualShinySocket() {
371
+ const factory = () => new VirtualShinySocket();
372
+ const apply = () => {
373
+ if (typeof globalThis.Shiny === "object" && globalThis.Shiny !== null) {
374
+ globalThis.Shiny.createSocket = factory;
375
+ } else {
376
+ globalThis.Shiny = { createSocket: factory };
377
+ }
378
+ };
379
+ apply();
380
+ document.addEventListener("DOMContentLoaded", apply, { once: true });
381
+ installSessionPortRecovery();
382
+ httpuvDebugLog("shiny-socket-installed");
383
+ }
384
+ installVirtualShinySocket();
385
+
386
+ export { VirtualShinySocket, installVirtualShinySocket };
387
+ //# sourceMappingURL=shiny-socket.js.map
388
+ //# sourceMappingURL=shiny-socket.js.map