docs(roadmap): document Gate A worker unbundled relative imports bug and 0.1.1 fix
Browse files- ROADMAP.md +26 -3
ROADMAP.md
CHANGED
|
@@ -33,9 +33,32 @@ from the other side.
|
|
| 33 |
- [~] **Gate A — a bare Vite page loads a prebuilt model and generates.**
|
| 34 |
[examples/bare/](examples/bare/) exists and the GPU-free half is proven: `vite build` resolves
|
| 35 |
through the `exports` map and splits into an entry chunk, the decode worker as its own chunk,
|
| 36 |
-
and the 6 MB WebLLM bundle as a lazy one.
|
| 37 |
-
|
| 38 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
- [ ] **Gate A′ — the same page ingests a local folder.** `cache.put()` against the synthetic
|
| 40 |
`local-model.invalid` key is proven only on an extension origin. Gates the *offline* route,
|
| 41 |
not the library.
|
|
|
|
| 33 |
- [~] **Gate A — a bare Vite page loads a prebuilt model and generates.**
|
| 34 |
[examples/bare/](examples/bare/) exists and the GPU-free half is proven: `vite build` resolves
|
| 35 |
through the `exports` map and splits into an entry chunk, the decode worker as its own chunk,
|
| 36 |
+
and the 6 MB WebLLM bundle as a lazy one.
|
| 37 |
+
|
| 38 |
+
**Broke on real-browser run: worker unbundled imports in production.**
|
| 39 |
+
When deployed to a static host (Hugging Face Spaces), `engine.load()` threw
|
| 40 |
+
`PACKAGE_INCOMPLETE`: *"The decode worker failed to load from .../assets/engine-worker-dJUbtWsb.js"*.
|
| 41 |
+
|
| 42 |
+
*Root cause:* Rollup's `new Worker(new URL(..., import.meta.url), { type: "module" })` handling
|
| 43 |
+
copies `engine-worker.js` verbatim as an asset chunk without bundling or rewriting its internal
|
| 44 |
+
ESM imports. The emitted worker still carries:
|
| 45 |
+
`import { WebWorkerMLCEngineHandler } from "../../vendor/web-llm.js"`
|
| 46 |
+
`import { WORKER_CONFIGURE } from "./constants.js"`
|
| 47 |
+
`import { DEFAULT_DECODE_STEPS } from "./multistep.js"`
|
| 48 |
+
On a static production deployment, these relative URLs resolve to 404s on the root domain,
|
| 49 |
+
killing the worker silently before handshake. `vite dev` hid this because `optimizeDeps.exclude`
|
| 50 |
+
served files directly from source where siblings exist. `test/consumer/verify.mjs` line 130
|
| 51 |
+
missed it because it asserted file *existence* (`assets.some(f => f.startsWith("engine-worker"))`),
|
| 52 |
+
never executing the worker in a browser.
|
| 53 |
+
|
| 54 |
+
*Remediation:*
|
| 55 |
+
- [x] **Demo workaround:** Pre-bundle `engine-worker.js` with `esbuild --bundle --format=esm` into a
|
| 56 |
+
standalone 6.58 MB file (`public/engine-worker.js`) with zero external imports, and pass explicit
|
| 57 |
+
`workerUrl: new URL("engine-worker.js", window.location.href)`.
|
| 58 |
+
- [ ] **Library permanent fix for 0.1.1:** In `build.mjs`, pre-bundle `engine-worker.js` into
|
| 59 |
+
a self-contained `dist/worker.bundle.js` at package build time. Point `DEFAULT_WORKER_URL`
|
| 60 |
+
at the bundle so zero consumer configuration or `workerUrl` is required. Update
|
| 61 |
+
`verify-consumer` with a headless browser fetch/execute assertion to prevent regressions.
|
| 62 |
- [ ] **Gate A′ — the same page ingests a local folder.** `cache.put()` against the synthetic
|
| 63 |
`local-model.invalid` key is proven only on an extension origin. Gates the *offline* route,
|
| 64 |
not the library.
|