From 319d778b40114e1d104bf2a4c9ef93e5656fc524 Mon Sep 17 00:00:00 2001 From: Ronald Tse Date: Sat, 5 Sep 2026 13:00:41 +0200 Subject: [PATCH] =?UTF-8?q?fix(neural):=20bundle=20onnxruntime-web=20?= =?UTF-8?q?=E2=80=94=20the=20deployed=20demo=20could=20not=20load=20the=20?= =?UTF-8?q?ML=20engine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rolldownOptions.external listed onnxruntime-web (a build-noise workaround for the uninstalled @litertjs/core), leaving a bare specifier the browser cannot resolve: the deployed /neural demo failed with 'Failed to resolve module specifier'. @litertjs/core is now a real dependency and only the node-only backend stays external; the ORT runtime and its wasm binaries bundle (ort.bundle.min.*.js + ort-wasm-*.wasm in dist). New live e2e spec (LIVE_NEURAL=1) downloads the real 95MB lite artifact and asserts vocalized output — passing against a local preview. --- astro.config.mjs | 7 +++- e2e/neural-live.spec.ts | 23 +++++++++++ package-lock.json | 88 ++++++++--------------------------------- package.json | 1 + 4 files changed, 46 insertions(+), 73 deletions(-) create mode 100644 e2e/neural-live.spec.ts diff --git a/astro.config.mjs b/astro.config.mjs index 6f5e1c4e..0655cb5b 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -23,9 +23,14 @@ export default defineConfig({ // imports; the transliteration path never loads them, but the dev // scanner and rolldown still try to resolve them. optimizeDeps: { exclude: ["interscript-ts"] }, + // onnxruntime-web must NOT be externalized: the /neural demo loads + // the ML engine lazily in the browser, and an externalized bare + // specifier is unresolvable at runtime (the deployed demo failed + // with "Failed to resolve module specifier 'onnxruntime-web'"). + // Node-only backends stay external — the client never imports them. build: { rolldownOptions: { - external: ["onnxruntime-web", "@litertjs/core", "onnxruntime-node"], + external: ["onnxruntime-node"], }, }, }, diff --git a/e2e/neural-live.spec.ts b/e2e/neural-live.spec.ts new file mode 100644 index 00000000..9d20f275 --- /dev/null +++ b/e2e/neural-live.spec.ts @@ -0,0 +1,23 @@ +// LIVE /neural verification — downloads the real artifact through the +// assets proxy and decodes in the browser. Opt-in (LIVE_NEURAL=1) so +// CI never pulls 95MB; run against the deployed site: +// LIVE_NEURAL=1 npx playwright test e2e/neural-live.spec.ts +import { expect, test } from "@playwright/test" + +test.skip(!process.env.LIVE_NEURAL, "live download test — set LIVE_NEURAL=1") + +test("lite int4 tier downloads, verifies, and vocalizes in the browser", async ({ page }) => { + test.setTimeout(420_000) + await page.goto(`${process.env.LIVE_NEURAL_BASE ?? "https://interscript.org"}/neural`) + await page.selectOption("#model", "ara-diac-layerdrop-1.0-int4") + await page.fill("#input", "قوله فحكمها في الوفاة") + await page.click("#run") + // progress must appear (index resolve + download), then the model decodes + await expect(page.locator("#progress")).toBeVisible({ timeout: 30_000 }) + const output = page.locator("#output") + await expect(output).not.toBeEmpty({ timeout: 420_000 }) + const text = (await output.textContent()) ?? "" + // fully vocalized output carries haraqat bytes and no error surface + expect(text).toMatch(/[ً-ْٰٓ-ٕ]/) + expect(text).not.toMatch(/Error|cause:/) +}) diff --git a/package-lock.json b/package-lock.json index 46935043..9e0aa089 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@fontsource/jetbrains-mono": "^5.3.0", "@iso24229/iso15924-data": "^0.2.0", "@iso24229/iso639-data": "^0.2.0", + "@litertjs/core": "^2.5.3", "@tailwindcss/vite": "^4.0.0", "astro": "^7.0.0", "interscript": "^5.2.1", @@ -144,9 +145,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -163,9 +161,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -182,9 +177,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -201,9 +193,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -941,9 +930,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -957,9 +943,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -973,9 +956,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -989,9 +969,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1997,9 +1974,6 @@ "cpu": [ "arm" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2016,9 +1990,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2035,9 +2006,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2054,9 +2022,6 @@ "cpu": [ "riscv64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2073,9 +2038,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2092,9 +2054,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2111,9 +2070,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2130,9 +2086,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -2149,9 +2102,6 @@ "cpu": [ "arm" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2174,9 +2124,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2199,9 +2146,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2224,9 +2168,6 @@ "cpu": [ "riscv64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2249,9 +2190,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2274,9 +2212,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2299,9 +2234,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2324,9 +2256,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -2566,6 +2495,21 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@litertjs/core": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@litertjs/core/-/core-2.5.3.tgz", + "integrity": "sha512-PlGmbMOq9WitX7FO0jhbdJw9GthatsyuCQXjTt/wJZo0FLaw48q4tz8IwqgqCIkviYGr9OFDL1kCnN4nzWoyJQ==", + "license": "Apache-2.0", + "dependencies": { + "@litertjs/wasm-utils": "^2.5.3" + } + }, + "node_modules/@litertjs/wasm-utils": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@litertjs/wasm-utils/-/wasm-utils-2.5.3.tgz", + "integrity": "sha512-4fJiw6tBQnIs+0jH/OQ16nYOiSl8/+zZnn5h2ul8aTKHi05sVqZW580Tmk78pC2kT39A9OYBVdFawteZ/sI1kQ==", + "license": "Apache-2.0" + }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.0.tgz", diff --git a/package.json b/package.json index e7ca94ee..7098a0a7 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "@fontsource/jetbrains-mono": "^5.3.0", "@iso24229/iso15924-data": "^0.2.0", "@iso24229/iso639-data": "^0.2.0", + "@litertjs/core": "^2.5.3", "@tailwindcss/vite": "^4.0.0", "astro": "^7.0.0", "interscript": "^5.2.1",