Skip to content

fix(worker): make Comunica QueryEngine work in Vite browser worker#9

Merged
ThHanke merged 1 commit into
mainfrom
fix/sparql-worker
May 5, 2026
Merged

fix(worker): make Comunica QueryEngine work in Vite browser worker#9
ThHanke merged 1 commit into
mainfrom
fix/sparql-worker

Conversation

@ThHanke
Copy link
Copy Markdown
Owner

@ThHanke ThHanke commented May 5, 2026

Problem

queryGraph MCP tool always failed in the browser with errors like:

  • "(0, L.channel) is not a function"lru-cache imports node:diagnostics_channel; Vite's browser-external Proxy stub returns undefined for all property accesses
  • "Class extends value undefined is not a constructor or null"promise-polyfill does root = global; global is undefined in browser workers; the broken __commonJS wrapper caches empty {} exports; downstream class inheritance fails

Root cause: two separate failure paths, both in how Vite pre-bundles Comunica's dependency chain for the browser worker context.

Fix

vite-plugin-worker-comunica.ts (new):

  • diagnosticsChannelStub — esbuild plugin that replaces node:diagnostics_channel with a no-op stub providing real channel()/tracingChannel() functions
  • workerComunicaPlugin() — Vite plugin for production Rollup worker builds: intercepts @comunica/query-sparql-rdfjs, pre-bundles it with esbuild (flat ESM, correct init order), serves as a virtual module; same strategy as InProcessWorker tests

vite.config.ts:

  • worker.plugins: () => [workerComunicaPlugin()] — activates the esbuild pre-bundle for Rollup worker builds (production)
  • optimizeDeps.esbuildOptions with define: { global: "globalThis" } and plugins: [diagnosticsChannelStub] — fixes dev mode pre-bundle (Vite serves workers as native ESM in dev; worker.plugins Rollup hooks don't run)

e2e/sparql-worker.spec.ts (new):

  • Playwright regression test calling window.__mcpTools.queryGraph directly in the browser
  • Covers INSERT, SELECT, CONSTRUCT, DELETE + SELECT-after-delete, malformed SPARQL error path

Verification

  • 16 Vitest integration tests pass (InProcessWorker, unchanged)
  • 5 Playwright browser tests pass end-to-end in real browser worker
  • Both dev (vite dev) and production (vite build) modes verified

Branch

Derived from main (not from feat/relay-dispatch-hardening).

Vite's Rollup worker bundler wraps CJS modules in require_libXXX stubs
that break Comunica v5's circular actor/bus/mediator dep graph, causing
every queryGraph call to fail at runtime despite unit tests passing.

Two root causes identified via live browser reproduction:
  1. node:diagnostics_channel (lru-cache) — Vite's browser-external
     Proxy stub returns undefined for all property accesses, so
     (0, L.channel)("lru-cache:metrics") throws at init time.
  2. `global` (promise-polyfill) — not defined in browser workers;
     cascades into broken __commonJS wrappers for downstream actors.

Fix:
  - Add vite-plugin-worker-comunica.ts: intercepts the Comunica import
    in worker.plugins and substitutes an esbuild-compiled flat ESM bundle
    (same strategy as InProcessWorker tests that already pass).
  - optimizeDeps.esbuildOptions: stub node:diagnostics_channel + define
    global→globalThis so the dep-optimizer pre-bundle is also clean.
  - e2e/sparql-worker.spec.ts: browser regression test covering INSERT,
    SELECT, CONSTRUCT, DELETE, and malformed-SPARQL error path.
@ThHanke ThHanke merged commit 7f42bac into main May 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant