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/httpuv/constants.ts","../src/httpuv/debug.ts","../src/httpuv/shiny-socket.ts"],"names":["payload"],"mappings":"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","file":"shiny-socket.js","sourcesContent":["/** WebSocket frame types used by httpuv (mirrors native httpuv). */\nexport const WS_FRAME = {\n SEND: \"websocket.send\",\n CLOSE: \"websocket.close\",\n} as const;\n\n/** R_HOME inside the mounted wasm prefix (VFS root is /). */\nexport const WASM_R_HOME = \"/lib/R\";\n\n/** Max time the service worker waits for the R worker to answer a request. */\nexport const REQUEST_TIMEOUT_MS = 180_000;\n\n/** Message types exchanged between the service worker and the main page. */\nexport const MSG = {\n REGISTER_HOST: \"httpuv_register_host\",\n HTTP_REQUEST: \"httpuv_http_request\",\n HTTP_RESPONSE: \"httpuv_http_response\",\n WS_PUSH: \"httpuv_ws_push\",\n /** Iframe → SW (on session port): frame delivered to Shiny.createSocket. */\n WS_PUSH_ACK: \"httpuv_ws_push_ack\",\n STOP: \"httpuv_stop\",\n /** Drop cached GET /shiny/ without tearing down the R worker (app restart). */\n CLEAR_APP_CACHE: \"httpuv_clear_app_cache\",\n /** Host -> SW: full shiny::resourcePaths() map (warmup). */\n REGISTER_RESOURCE_PATHS: \"httpuv_register_resource_paths\",\n /** Host -> SW: upsert or remove one addResourcePath prefix (empty dir removes). */\n UPDATE_RESOURCE_PATH: \"httpuv_update_resource_path\",\n /** SW -> host: Comlink to the R worker was lost (e.g. after SW update). */\n REQUEST_COMLINK: \"httpuv_request_comlink\",\n /** Iframe → SW: transfer a MessagePort for session WS push delivery. */\n REGISTER_SESSION: \"httpuv_register_session\",\n /** SW → iframe (on session port): registration accepted. */\n SESSION_ACK: \"httpuv_session_ack\",\n /** SW → iframe client: session MessagePort was lost (e.g. SW idle restart); re-REGISTER_SESSION. */\n REQUEST_SESSION_PORT: \"httpuv_request_session_port\",\n} as const;\n\n/** Bypass SW app-document cache (warmup must hit R so deps register). */\nexport const WARMUP_REQUEST_HEADER = \"X-Shiny-Forge-Warmup\";\n\n/** Message types on Module.httpuv.channel (R <-> JS bridge). */\nexport const CHANNEL = {\n HTTP_REQUEST: \"httpuv_http_request\",\n TCP_RESPONSE: \"httpuv_tcp_response\",\n WS_OPEN: \"httpuv_ws_open\",\n WS_MESSAGE: \"httpuv_ws_message\",\n WS_CLOSE: \"httpuv_ws_close\",\n WS_RESPONSE: \"httpuv_ws_response\",\n STDIN: \"stdin\",\n} as const;\n\n/** R option names registered by httpuv::startServer(). */\nexport const HTTPUV_OPTIONS = {\n ON_REQUEST: \"httpuv_onRequest\",\n ON_WS_OPEN: \"httpuv_onWSOpen\",\n ON_WS_MESSAGE: \"httpuv_onWSMessage\",\n ON_WS_CLOSE: \"httpuv_onWSClose\",\n} as const;\n\n/** Comlink MessagePort handshake between host page, service worker, and R worker. */\nexport const COMLINK = {\n PORT_HANDOFF: \"httpuv_comlink_port\",\n /**\n * SW -> host: the handoff port arrived. Sent before the Comlink round-trip so\n * the host can distinguish a dropped handoff (worker evicted mid-boot) from an\n * R worker that never finished setup.\n */\n PORT_HANDOFF_ACK: \"httpuv_comlink_port_ack\",\n} as const;\n","/**\n * Opt-in tracing for the httpuv / Shiny-Forge request pipeline.\n *\n * Enable with either:\n * - URL query: ?httpuvDebug=1\n * - localStorage: localStorage.shinyForgeDebug = \"1\"\n * - console: shinyForge.enableHttpuvDebug()\n */\nexport function isHttpuvDebug(): boolean {\n if (globalThis.__HTTPUV_DEBUG__) {\n return true;\n }\n try {\n if (typeof location !== \"undefined\") {\n const params = new URLSearchParams(location.search);\n if (params.has(\"httpuvDebug\") || params.get(\"debug\") === \"httpuv\") {\n return true;\n }\n }\n if (typeof localStorage !== \"undefined\" && localStorage.getItem(\"shinyForgeDebug\") === \"1\") {\n return true;\n }\n if (typeof self !== \"undefined\" && self.location?.href) {\n const params = new URL(self.location.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\nexport function httpuvDebugLog(stage: string, ...args: unknown[]): void {\n if (!isHttpuvDebug()) {\n return;\n }\n console.info(`[httpuv-debug:${stage}]`, ...args);\n}\n\nexport function enableHttpuvDebug(): void {\n globalThis.__HTTPUV_DEBUG__ = true;\n try {\n localStorage.setItem(\"shinyForgeDebug\", \"1\");\n } catch {\n // ignore\n }\n console.info(\n \"[httpuv-debug] enabled - reload or run shinyForge.enableHttpuvDebug() then re-run app\",\n );\n}\n","/**\n * Virtual WebSocket for Shiny in the browser.\n * Loaded as a module in the Shiny app iframe; overrides Shiny.createSocket.\n *\n * Server→client frames arrive on a dedicated MessagePort registered with the\n * httpuv service worker (no recv long-poll). open/send/close still use fetch.\n *\n * After the browser stops the SW while idle, the port is gone but the socket\n * stays logically open: we re-REGISTER_SESSION on send, visibilitychange, and\n * when the SW asks via REQUEST_SESSION_PORT.\n */\n\nimport { MSG, WS_FRAME } from \"./constants\";\nimport { httpuvDebugLog } from \"./debug\";\n\n/** How long to wait for SESSION_ACK after REGISTER_SESSION. */\nconst SESSION_REGISTER_TIMEOUT_MS = 5_000;\n\n/** After this gap with no SW→iframe push, the next send() force-registers. */\nconst SESSION_PORT_STALE_MS = 15_000;\n\n/** Build an absolute session URL under the Shiny app prefix. */\nfunction sessionUrl(action: string, opts: { handle?: string } = {}): string {\n const base = new URL(\"__session__/\", location.href);\n const url = new URL(action.replace(/^\\//, \"\"), base);\n if (opts.handle) {\n url.searchParams.set(\"handle\", opts.handle);\n }\n return url.href;\n}\n\ntype SessionPortMessage = {\n type?: string;\n handle?: string;\n wsType?: string;\n binary?: boolean;\n message?: unknown;\n pushId?: number;\n};\n\nconst socketsByHandle = new Map<string, VirtualShinySocket>();\n\n/** Minimal WebSocket stand-in using session fetch + MessagePort push delivery. */\nexport class VirtualShinySocket {\n static readonly CONNECTING = 0;\n static readonly OPEN = 1;\n static readonly CLOSING = 2;\n static readonly CLOSED = 3;\n\n readyState: number = VirtualShinySocket.CONNECTING;\n binaryType: BinaryType = \"arraybuffer\";\n\n private _handle: string | null = null;\n private _active = false;\n private _port: MessagePort | null = null;\n private _registering: Promise<void> | null = null;\n /** Last time a WS_PUSH arrived — used to detect orphaned ports after SW idle kill. */\n private _lastPushAt = 0;\n\n onopen: ((event: Event) => void) | null = null;\n onmessage: ((event: MessageEvent) => void) | null = null;\n onclose: ((event: CloseEvent) => void) | null = null;\n onerror: ((event: Event) => void) | null = null;\n\n constructor() {\n void this._connect();\n }\n\n private async _connect(): Promise<void> {\n try {\n const openUrl = sessionUrl(\"open\");\n httpuvDebugLog(\"socket-open\", openUrl);\n const res = await fetch(openUrl, { method: \"POST\" });\n if (!res.ok) {\n throw new Error(`session open failed: HTTP ${res.status}`);\n }\n const { handle } = (await res.json()) as { handle?: string };\n if (!handle) {\n throw new Error(\"session open response missing handle\");\n }\n this._handle = String(handle);\n this.readyState = VirtualShinySocket.OPEN;\n this._active = true;\n socketsByHandle.set(this._handle, this);\n\n await this.ensurePort();\n\n this.onopen?.(new Event(\"open\"));\n } catch (err) {\n console.error(\"[shiny-socket] connect failed\", err);\n this._teardownPort();\n this.readyState = VirtualShinySocket.CLOSED;\n this.onerror?.(new Event(\"error\"));\n this.onclose?.(new CloseEvent(\"close\", { code: 1006, wasClean: false }));\n }\n }\n\n /**\n * Ensure the SW has a live MessagePort for this session.\n * Safe to call repeatedly after idle SW restarts.\n * @param force when true, replace any existing port (recovery / stale paths).\n * Ordinary rapid send() must not force — re-registering mid-flight drops\n * SW→iframe frames on Chromium. After idle, force once so a dead port\n * (SW stopped, client still holds MessagePort) is replaced before replies.\n */\n ensurePort(force = false): Promise<void> {\n if (!this._active || !this._handle) {\n return Promise.resolve();\n }\n if (!force && this._port) {\n return Promise.resolve();\n }\n if (this._registering) {\n return this._registering;\n }\n this._registering = this._registerSessionPort(this._handle).finally(() => {\n this._registering = null;\n });\n return this._registering;\n }\n\n /** Hand a MessagePort to the SW and wait for SESSION_ACK. */\n private async _registerSessionPort(handle: string): Promise<void> {\n const controller = navigator.serviceWorker?.controller;\n if (!controller) {\n throw new Error(\"no service worker controller for session port\");\n }\n\n if (this._port) {\n try {\n this._port.close();\n } catch {\n // ignore\n }\n this._port = null;\n }\n\n const channel = new MessageChannel();\n this._port = channel.port1;\n\n const acked = new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new Error(\"session port registration timed out\"));\n }, SESSION_REGISTER_TIMEOUT_MS);\n\n this._port!.onmessage = (event: MessageEvent<SessionPortMessage>) => {\n const data = event.data;\n if (data?.type === MSG.SESSION_ACK) {\n clearTimeout(timer);\n this._port!.onmessage = (ev) => this._onPortMessage(ev);\n resolve();\n return;\n }\n this._onPortMessage(event);\n };\n\n this._port!.onmessageerror = () => {\n clearTimeout(timer);\n reject(new Error(\"session port messageerror\"));\n };\n });\n\n httpuvDebugLog(\"socket-register-session\", { handle });\n controller.postMessage({ type: MSG.REGISTER_SESSION, handle }, [channel.port2]);\n await acked;\n }\n\n private _ackPush(pushId: number | undefined): void {\n if (typeof pushId !== \"number\" || !this._port) {\n return;\n }\n try {\n this._port.postMessage({ type: MSG.WS_PUSH_ACK, pushId });\n } catch (err) {\n console.warn(\"[shiny-socket] WS_PUSH_ACK failed\", err);\n }\n }\n\n private _onPortMessage(event: MessageEvent<SessionPortMessage>): void {\n if (!this._active) {\n return;\n }\n const data = event.data;\n if (!data || typeof data !== \"object\") {\n return;\n }\n\n if (data.type !== MSG.WS_PUSH && data.wsType == null && data.message === undefined) {\n return;\n }\n\n const wsType = data.wsType ?? WS_FRAME.SEND;\n if (wsType === WS_FRAME.CLOSE) {\n let code = 1000;\n let reason = \"\";\n try {\n const raw = data.message;\n if (typeof raw === \"string\" && raw) {\n const payload = JSON.parse(raw) as { code?: number; reason?: string };\n code = Number(payload.code ?? code);\n reason = String(payload.reason ?? \"\");\n }\n } catch {\n // ignore malformed close payloads\n }\n this._ackPush(data.pushId);\n this._finishClose(code, reason, true);\n return;\n }\n\n const binary = Boolean(data.binary);\n let payload: string | ArrayBuffer;\n if (binary) {\n if (data.message instanceof ArrayBuffer) {\n payload = data.message;\n } else if (ArrayBuffer.isView(data.message)) {\n const view = data.message;\n payload = view.buffer.slice(\n view.byteOffset,\n view.byteOffset + view.byteLength,\n ) as ArrayBuffer;\n } else if (typeof data.message === \"string\") {\n payload = data.message;\n } else {\n payload = new ArrayBuffer(0);\n }\n } else if (typeof data.message === \"string\") {\n payload = data.message;\n } else if (data.message instanceof ArrayBuffer) {\n payload = new TextDecoder().decode(data.message);\n } else if (ArrayBuffer.isView(data.message)) {\n payload = new TextDecoder().decode(data.message);\n } else {\n payload = String(data.message ?? \"\");\n }\n\n const bytes = typeof payload === \"string\" ? payload.length : payload.byteLength;\n httpuvDebugLog(\"socket-recv\", {\n wsType,\n binary,\n bytes,\n });\n this._lastPushAt = Date.now();\n this.onmessage?.(new MessageEvent(\"message\", { data: payload }));\n this._ackPush(data.pushId);\n }\n\n private _teardownPort(): void {\n this._active = false;\n if (this._handle) {\n socketsByHandle.delete(this._handle);\n }\n if (this._port) {\n try {\n this._port.close();\n } catch {\n // ignore\n }\n this._port = null;\n }\n }\n\n send(data: string | ArrayBuffer | ArrayBufferView): void {\n if (this.readyState !== VirtualShinySocket.OPEN || !this._handle) {\n throw new Error(\"WebSocket is not open\");\n }\n\n let body: string | ArrayBuffer;\n let byteLen: number;\n let isBinary: boolean;\n if (typeof data === \"string\") {\n body = data;\n byteLen = data.length;\n isBinary = false;\n } else if (data instanceof ArrayBuffer) {\n body = data;\n byteLen = data.byteLength;\n isBinary = true;\n } else {\n body = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer;\n byteLen = data.byteLength;\n isBinary = true;\n }\n\n const handle = this._handle;\n const sendUrl = sessionUrl(\"send\", { handle });\n httpuvDebugLog(\"socket-send\", sendUrl, {\n binary: isBinary,\n bytes: byteLen,\n });\n\n // After Chromium idle-stops the SW, this._port is orphaned but non-null.\n // Force re-register once when we have been idle; keep the port stable during\n // a reply storm (recent pushes keep _lastPushAt fresh).\n const stale =\n !this._port ||\n !this._lastPushAt ||\n Date.now() - this._lastPushAt > SESSION_PORT_STALE_MS;\n void this.ensurePort(stale)\n .catch((err) => {\n console.warn(\"[shiny-socket] ensurePort before send failed\", err);\n })\n .then(() =>\n fetch(sendUrl, {\n method: \"POST\",\n headers: isBinary ? {} : { \"Content-Type\": \"text/plain; charset=UTF-8\" },\n body,\n }),\n )\n .catch((err) => {\n console.error(\"[shiny-socket] send failed\", err);\n });\n }\n\n close(code = 1000, reason = \"\"): void {\n if (\n this.readyState === VirtualShinySocket.CLOSED ||\n this.readyState === VirtualShinySocket.CLOSING\n ) {\n return;\n }\n this.readyState = VirtualShinySocket.CLOSING;\n const handle = this._handle;\n this._active = false;\n if (handle) {\n const closeUrl = sessionUrl(\"close\", { handle });\n void fetch(closeUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ code, reason }),\n }).catch((err) => {\n console.error(\"[shiny-socket] close failed\", err);\n });\n }\n this._finishClose(code, reason, true);\n }\n\n private _finishClose(code: number, reason: string, wasClean: boolean): void {\n if (this.readyState === VirtualShinySocket.CLOSED) {\n return;\n }\n this._teardownPort();\n this.readyState = VirtualShinySocket.CLOSED;\n this.onclose?.(new CloseEvent(\"close\", { code, reason, wasClean }));\n }\n}\n\nfunction reregisterAllSockets(): void {\n for (const sock of socketsByHandle.values()) {\n void sock.ensurePort(true).catch((err) => {\n console.warn(\"[shiny-socket] ensurePort failed\", err);\n });\n }\n}\n\nfunction installSessionPortRecovery(): void {\n if (typeof navigator === \"undefined\" || !navigator.serviceWorker) {\n return;\n }\n navigator.serviceWorker.addEventListener(\"message\", (event: MessageEvent) => {\n const data = event.data as { type?: string; handle?: string } | null;\n if (!data || data.type !== MSG.REQUEST_SESSION_PORT) {\n return;\n }\n const handle = data.handle ? String(data.handle) : \"\";\n const sock = handle ? socketsByHandle.get(handle) : undefined;\n if (sock) {\n void sock.ensurePort(true).catch((err) => {\n console.warn(\"[shiny-socket] REQUEST_SESSION_PORT ensurePort failed\", err);\n });\n return;\n }\n reregisterAllSockets();\n });\n\n document.addEventListener(\"visibilitychange\", () => {\n if (document.visibilityState === \"visible\") {\n reregisterAllSockets();\n }\n });\n\n navigator.serviceWorker.addEventListener(\"controllerchange\", () => {\n reregisterAllSockets();\n });\n}\n\n/** Install VirtualShinySocket as Shiny.createSocket (call before Shiny connects). */\nexport function installVirtualShinySocket(): void {\n const factory = () => new VirtualShinySocket();\n\n const apply = () => {\n if (typeof globalThis.Shiny === \"object\" && globalThis.Shiny !== null) {\n globalThis.Shiny.createSocket = factory;\n } else {\n globalThis.Shiny = { createSocket: factory };\n }\n };\n\n apply();\n document.addEventListener(\"DOMContentLoaded\", apply, { once: true });\n installSessionPortRecovery();\n httpuvDebugLog(\"shiny-socket-installed\");\n}\n\ninstallVirtualShinySocket();\n"]}
@@ -0,0 +1,7 @@
1
+ <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="m16 27.2c-8.56 0-15.5-4.65-15.5-10.3 0-5.74 6.93-10.3 15.5-10.3 8.57 0 15.5 4.65 15.5 10.3 0 5.74-6.93 10.3-15.5 10.3zm2.38-16.6c-6.51 0-11.8 3.17-11.8 7.1 0 3.93 5.27 7.1 11.8 7.1 6.51 0 11.4-2.17 11.4-7.1 0-4.92-4.8-7.1-11.4-7.1z" fill="#808080" fill-opacity=".5"/>
3
+ <path d="m24.2 22.5s0.937 0.283 1.48 0.559c0.189 0.0957 0.516 0.286 0.752 0.537 0.231 0.245 0.344 0.494 0.344 0.494l3.7 6.22-5.97 0.0027-2.79-5.25s-0.572-0.978-0.924-1.27c-0.293-0.238-0.418-0.322-0.709-0.322h-1.43l0.0011 6.83-5.29 0.0023v-17.5h10.6s4.84 0.0871 4.84 4.69c0 4.6-4.62 4.94-4.62 4.94zm-2.29-5.84-3.19-0.0021-0.0015 2.97 3.2-1e-3s1.48-0.0045 1.48-1.51c0-1.54-1.48-1.46-1.48-1.46z" fill="#3f82d5"/>
4
+ <path d="m13.6 7.99-3.7-1.26-1.05-4.17c-0.0775-0.309-0.355-0.527-0.674-0.527-0.318 0-0.596 0.218-0.674 0.527l-1.05 4.17-3.7 1.26c-0.281 0.096-0.47 0.361-0.47 0.658 0 0.297 0.189 0.562 0.47 0.658l3.7 1.26 1.05 4.17c0.0775 0.309 0.355 0.527 0.674 0.527 0.318 0 0.596-0.218 0.674-0.527l1.05-4.17 3.7-1.26c0.281-0.096 0.47-0.361 0.47-0.658 0-0.297-0.189-0.562-0.47-0.658z" fill="#fdc31d"/>
5
+ <path d="m27.7 6.88-2.15-0.739-0.611-2.45c-0.0454-0.182-0.209-0.308-0.394-0.308s-0.35 0.127-0.394 0.308l-0.611 2.45-2.15 0.739c-0.164 0.0563-0.275 0.21-0.275 0.384s0.111 0.33 0.275 0.384l2.15 0.739 0.611 2.45c0.0454 0.182 0.209 0.308 0.394 0.308s0.35-0.127 0.394-0.308l0.611-2.45 2.15-0.739c0.164-0.0563 0.275-0.21 0.275-0.384s-0.111-0.33-0.275-0.384z" fill="#ffd639"/>
6
+ <path d="m9.06 25.4-1.18-0.405-0.336-1.34c-0.0248-0.0992-0.114-0.169-0.216-0.169-0.102 0-0.191 0.0696-0.216 0.169l-0.336 1.34-1.18 0.405c-0.0903 0.0309-0.15 0.116-0.15 0.212 0 0.0955 0.0607 0.18 0.15 0.212l1.18 0.405 0.336 1.34c0.0248 0.0992 0.114 0.169 0.216 0.169 0.102 0 0.191-0.0696 0.216-0.169l0.336-1.34 1.18-0.405c0.0903-0.0309 0.15-0.116 0.15-0.212 0-0.0955-0.0607-0.18-0.15-0.212z" fill="#fbaf00"/>
7
+ </svg>
@@ -0,0 +1,96 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>{{ title }}</title>
7
+ <link rel="icon" href="favicon.svg" type="image/svg+xml">
8
+ <link rel="stylesheet" href="style.css">
9
+ </head>
10
+ <body>
11
+
12
+ <div id="boot-overlay" class="boot-overlay" aria-live="polite">
13
+ <h3 id="boot-title">Starting</h3>
14
+ <progress id="progress" value="0" max="100"></progress>
15
+ <div id="status">Starting…</div>
16
+ </div>
17
+
18
+ <main class="app-layout">
19
+ <iframe
20
+ id="app-frame"
21
+ class="app-frame"
22
+ title="Viewer"
23
+ sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-downloads allow-popups-to-escape-sandbox"
24
+ ></iframe>
25
+ </main>
26
+ <script>
27
+ // Resolve against the site root so project GitHub Pages mounts
28
+ // (username.github.io/repo/) work without absolute "/..." paths.
29
+ const siteRoot = new URL("./", window.location.href);
30
+ globalThis.__LUCENT__ = {
31
+ transportBaseUrl: new URL("lucent/dist/", siteRoot).href,
32
+ serviceWorkerUrl: new URL("httpuv-sw.js", siteRoot).href,
33
+ rRuntimeBaseUrl: new URL("runtime/", siteRoot).href,
34
+ empackMetaUrl: new URL("packages/empack_env_meta.json", siteRoot).href,
35
+ empackPackagesBaseUrl: new URL("packages/", siteRoot).href,
36
+ shinyBaseUrl: siteRoot.href,
37
+ };
38
+
39
+ const title = document.getElementById("boot-title");
40
+ const progress = document.getElementById("progress");
41
+ const status = document.getElementById("status");
42
+ const overlay = document.getElementById("boot-overlay");
43
+
44
+ const PHASE_TITLES = {
45
+ "load-runtime": "Loading runtime",
46
+ download: "Loading packages",
47
+ filesystem: "Preparing filesystem",
48
+ "init-r": "Initializing R",
49
+ "load-httpuv": "Loading packages",
50
+ "start-app": "Starting Shiny",
51
+ warmup: "Warming up",
52
+ };
53
+
54
+ // Map download % into the overall boot bar (download is ~5–60%).
55
+ function downloadOverallPercent(downloadPercent) {
56
+ if (downloadPercent == null) return null;
57
+ return 5 + (downloadPercent / 100) * 55;
58
+ }
59
+
60
+ window.addEventListener("lucent:boot-status", (event) => {
61
+ const { phase, message, percent } = event.detail;
62
+ title.textContent = PHASE_TITLES[phase] ?? "Starting";
63
+ status.textContent = message;
64
+ if (percent != null) {
65
+ progress.value = percent;
66
+ }
67
+ });
68
+
69
+ window.addEventListener("lucent:download-progress", (event) => {
70
+ const { percent, downloadedBytes, totalBytes } = event.detail;
71
+ title.textContent = PHASE_TITLES.download;
72
+ const overall = downloadOverallPercent(percent);
73
+ if (overall != null) {
74
+ progress.value = overall;
75
+ }
76
+ status.textContent =
77
+ `Loading packages… ${(downloadedBytes / 1024 / 1024).toFixed(1)} MB / ` +
78
+ `${(totalBytes / 1024 / 1024).toFixed(1)} MB ` +
79
+ `(${percent == null ? "?" : percent.toFixed(1)}%)`;
80
+ });
81
+
82
+ window.addEventListener("lucent:ready", () => {
83
+ title.textContent = "Ready";
84
+ progress.value = 100;
85
+ status.textContent = "Ready";
86
+ overlay.hidden = true;
87
+ });
88
+
89
+ window.addEventListener("lucent:error", (event) => {
90
+ status.textContent = `Error: ${event.detail?.message ?? "failed to start"}`;
91
+ overlay.classList.add("boot-overlay--error");
92
+ });
93
+ </script>
94
+ <script type="module" src="./lucent/dist/runApp.js"></script>
95
+ </body>
96
+ </html>
@@ -0,0 +1,73 @@
1
+ /* Lucent CSS */
2
+
3
+ :root {
4
+ --background: hsl(218, 81%, 6%);
5
+ --text: hsl(96, 71%, 99%);
6
+ --text-error: hsl(351, 70%, 70%);
7
+ }
8
+
9
+ @media (prefers-color-scheme: light) {
10
+ :root {
11
+ --background: hsl(96, 71%, 99%);
12
+ --text: hsl(218, 81%, 6%);
13
+ --text-error:hsl(351, 50%, 40%);
14
+ }
15
+ }
16
+
17
+ html,
18
+ body {
19
+ height: 100%;
20
+ margin: 0;
21
+ }
22
+
23
+ body {
24
+ display: flex;
25
+ flex-direction: column;
26
+ background: var(--background);
27
+ color: var(--text);
28
+ }
29
+
30
+ .boot-overlay {
31
+ position: fixed;
32
+ inset: 0;
33
+ z-index: 10;
34
+ display: flex;
35
+ flex-direction: column;
36
+ align-items: center;
37
+ justify-content: center;
38
+ gap: 0.75rem;
39
+ background: var(--background);
40
+ color: var(--text);
41
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
42
+ }
43
+
44
+ .boot-overlay[hidden] {
45
+ display: none;
46
+ }
47
+
48
+ .boot-overlay h3 {
49
+ margin: 0;
50
+ font-weight: 600;
51
+ }
52
+
53
+ .boot-overlay progress {
54
+ width: min(400px, 80vw);
55
+ height: 0.85rem;
56
+ }
57
+
58
+ .boot-overlay--error #status {
59
+ color: var(--text-error);
60
+ }
61
+
62
+ .app-layout {
63
+ flex: 1 1 auto;
64
+ display: flex;
65
+ min-height: 0;
66
+ }
67
+
68
+ .app-frame {
69
+ flex: 1 1 auto;
70
+ width: 100%;
71
+ min-height: 0;
72
+ border: none;
73
+ }
@@ -0,0 +1,90 @@
1
+ Metadata-Version: 2.5
2
+ Name: lucent-pack
3
+ Version: 0.1.0
4
+ Summary: Pack a Shiny app and a WebAssembly R environment into a static Lucent site
5
+ Project-URL: Homepage, https://github.com/IsabelParedes/lucent-pack
6
+ Project-URL: Repository, https://github.com/IsabelParedes/lucent-pack
7
+ Author: Isabel Paredes
8
+ License-Expression: BSD-3-Clause
9
+ License-File: LICENSE
10
+ Keywords: emscripten,lucent,r,shiny,wasm
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: BSD License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Software Development :: Build Tools
17
+ Requires-Python: >=3.10
18
+ Requires-Dist: empack<7,>=6
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Lucent-Pack
22
+
23
+ Pack a Shiny app and a WebAssembly R environment into a static site.
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ pip install lucent-pack
29
+ # OR
30
+ micromamba install lucent-pack
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ 1. Create a wasm environment with your favorite package manager.
36
+
37
+ ```bash
38
+ micromamba create -f environment.yaml --platform=emscripten-wasm32
39
+ ```
40
+
41
+ ```yaml
42
+ # Sample environment.yaml
43
+ name: shinyapp-env
44
+ channels:
45
+ - https://repo.prefix.dev/emscripten-forge-4x
46
+ - conda-forge
47
+ dependencies:
48
+ # Minimum requirements
49
+ - r-main
50
+ - r-shiny
51
+ # Any additional packages required for the app
52
+ - r-bslib
53
+ - r-plotly
54
+ ```
55
+
56
+ 2. Build the site.
57
+
58
+ ```bash
59
+ lucent build --prefix-dir /path/to/wasm/env/ --app /path/to/app --outdir ./_site
60
+ ```
61
+
62
+ 3. Check results.
63
+ ```bash
64
+ lucent serve ./_site # the output directory
65
+ ```
66
+
67
+ ## Development
68
+
69
+ Requirements:
70
+ - python
71
+ - pip
72
+ - nodejs
73
+
74
+ ```bash
75
+ pip install -e .
76
+
77
+ # Browser runtime — required before `python -m build` (wheel)
78
+ cd js && npm ci && npm run build
79
+ mkdir -p ../src/lucent_pack/static/lucent/dist
80
+ cp -a dist/. ../src/lucent_pack/static/lucent/dist/
81
+ ```
82
+
83
+ The hatch wheel hook fails the build if the bundles (`src/lucent_pack/static/lucent/dist/`) are missing.
84
+
85
+ ## CLI
86
+
87
+ | Command | Purpose |
88
+ |---------|---------|
89
+ | `lucent build` | Pack an existing `--prefix-dir` + `--app` into `--outdir` |
90
+ | `lucent serve` | Serve a built site directory (`python -m http.server` style) |
@@ -0,0 +1,28 @@
1
+ lucent_pack/__init__.py,sha256=8phLoMx1VLWfK0rTOHAuw3QqHjvIoAk3gu-PsPhPcLc,102
2
+ lucent_pack/__main__.py,sha256=Pv45l9mrwTtFGqggAhEbu0_c01HTVD8JCJ39Bv5nqvo,59
3
+ lucent_pack/build.py,sha256=n8kJNgOA3irBwgdLvKSeFmvgT15sATPGocZMCUaNLlA,7759
4
+ lucent_pack/cli.py,sha256=C2qmG8kDa338U4Z5f1Td3e-IkOu3tADv5f-BL5aQvDc,3057
5
+ lucent_pack/serve.py,sha256=6YXbs_Vjca69FcpK1hus1W_HPVDnUbok772GvipaEEw,1402
6
+ lucent_pack/templates/favicon.svg,sha256=omoxODxdOSnQW-8kg7Pmx_Xr3_g2eNu3GTCQZjV0kX0,1952
7
+ lucent_pack/templates/index.html,sha256=5C2_TBsL6TTvPj_OxdpbUav7kMZyjDBHsTM0R0JQLKo,3620
8
+ lucent_pack/templates/style.css,sha256=i8kvSdYN-_XBANFJ16dvAxaLAMxF90njYdlg9BzcnCM,1208
9
+ lucent_pack/static/lucent/dist/httpuv-sw.d.ts,sha256=bKoLBL3BBYKjcp2ukkTyHFvsC5_-fiqEmZwvho9d2b4,13
10
+ lucent_pack/static/lucent/dist/httpuv-sw.js,sha256=XLYxK5ta9T5FjszdQbg1KPUb4YmEf3M4JKJ8_pubN2w,44885
11
+ lucent_pack/static/lucent/dist/httpuv-sw.js.map,sha256=CM5gGw_BBeaeHxdKCC_NnNnPSWhtsbfrsnmKvAao6Yo,115207
12
+ lucent_pack/static/lucent/dist/httpuv-web.d.ts,sha256=NqAgf2szc0wmxjYU1Rzo7KZTEXK0GXPPmyrPUaRHeEs,12358
13
+ lucent_pack/static/lucent/dist/httpuv-web.js,sha256=J1qEA9Uh0r6QjigjdEdinmCuEuNHq7_WgnhsAIYaOdE,23732
14
+ lucent_pack/static/lucent/dist/httpuv-web.js.map,sha256=W9aEOR1T8KwqJ80uFSU_cgd1jJzRNSxL9e_X29ZXzc4,53940
15
+ lucent_pack/static/lucent/dist/rWasmWorker.d.ts,sha256=bKoLBL3BBYKjcp2ukkTyHFvsC5_-fiqEmZwvho9d2b4,13
16
+ lucent_pack/static/lucent/dist/rWasmWorker.js,sha256=pBcbMOhJjHYy2Hs6KGk01AS3QMZCwWWaYJjliw1PdqQ,49727
17
+ lucent_pack/static/lucent/dist/rWasmWorker.js.map,sha256=PhbZHp0YPOs2wR3-Ku2ZwcGj6urBDQ3yJ2XHQ9ld_9w,140859
18
+ lucent_pack/static/lucent/dist/runApp.d.ts,sha256=mn_DLDD8CaAL-SWf2Dc6XXHF0CiLPFmZ0uWMd_oHO9g,284
19
+ lucent_pack/static/lucent/dist/runApp.js,sha256=KuV2GoJkzONP23msEKlYMjdvAt8GYaFsujN-hvbcCcI,33332
20
+ lucent_pack/static/lucent/dist/runApp.js.map,sha256=XU02IRQaUXNH_AE8P4LLz2n8XvIePvJyyBokt1K3x1o,87691
21
+ lucent_pack/static/lucent/dist/shiny-socket.d.ts,sha256=WEha01TBvZYQzf7k4pgI9v0ttTFTAMYn14Ypep2fwRk,2264
22
+ lucent_pack/static/lucent/dist/shiny-socket.js,sha256=BBI4WDwDinUzIbBcgVzH1T0RkCOitz21NqkV-PCaxbw,12689
23
+ lucent_pack/static/lucent/dist/shiny-socket.js.map,sha256=HZGv6o8_6aqeADXp5ENTGtT-6QeoYv5h3XzkP7td6Ls,30150
24
+ lucent_pack-0.1.0.dist-info/METADATA,sha256=QNkt2LdMb9LP3wUIROmTLyfbqTVaPVojGIf42e_xb68,2141
25
+ lucent_pack-0.1.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
26
+ lucent_pack-0.1.0.dist-info/entry_points.txt,sha256=jYmCozPgj7CD-T2_z1KXmIk5aw47jDey71DQhdzy9TU,48
27
+ lucent_pack-0.1.0.dist-info/licenses/LICENSE,sha256=HMhLU8QNHc9SWGhCQeG_AtBxiNCINK0a1ShYOTa3ML8,1501
28
+ lucent_pack-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ lucent = lucent_pack.cli:main
@@ -0,0 +1,28 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, Isabel Paredes
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ 3. Neither the name of the copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.