Skip to content

test(worker-bus): export v2 duckdb/inference handlers + parity gate tests - #286

Merged
qnbs merged 2 commits into
mainfrom
feat/worker-v2-parity-gate
Jul 29, 2026
Merged

test(worker-bus): export v2 duckdb/inference handlers + parity gate tests#286
qnbs merged 2 commits into
mainfrom
feat/worker-v2-parity-gate

Conversation

@qnbs

@qnbs qnbs commented Jul 29, 2026

Copy link
Copy Markdown
Owner

Summary

First of 5 PRs consolidating the v1/WorkerBus-v2 worker duplication tracked in ADR-0014. Plan: .claude/plans/worker-generation-v1-vs-enumerated-fox.md.

  • Export initDuckDb/handleQuery/handleExec/handleShutdown (workers/v2/duckdb.worker.ts) and handleInference (workers/v2/inference.worker.ts), matching how webllm.worker.ts's handleWebLlm is already exported and unit-tested.
  • Add tests/unit/duckdbWorkerHandler.test.ts (10 tests) and tests/unit/inferenceWorkerHandlerV2.test.ts (10 tests), mirroring tests/unit/webllmWorkerHandler.test.ts's pattern — mock the external library, exercise the real handler logic directly, no live worker/WorkerBus needed.
  • Real bug found and fixed: initDuckDb()'s OPFS-unavailable catch block silently swallowed the failure. v1 (workers/duckdbWorker.ts) posts an out-of-band OPFS_FALLBACK message so the UI can warn the user their analytics won't persist across reloads (private browsing, old Safari); v2 had the identical catch block but emitted nothing. Fixed by threading ctx.emitProgress into initDuckDb() and emitting an 'opfs-fallback' progress stage — reuses the existing progress channel (same one WebLLM uses for download progress), no new message-protocol/schema change.

Both v2 worker files had zero production callers before this PR (confirmed via repo-wide grep) — they were registered as live WorkerBus v2 pools but never exercised by real traffic, so this parity gate exists specifically to catch drift like the OPFS gap before any consumer (duckdbClient.ts, localEmbeddingService.ts, localNlpService.ts) cuts over in the next 3 PRs.

Test plan

  • pnpm exec vitest run tests/unit/duckdbWorkerHandler.test.ts tests/unit/inferenceWorkerHandlerV2.test.ts tests/unit/webllmWorkerHandler.test.ts — 25/25 passing
  • pnpm run typecheck (exact CI command) — clean
  • pnpm run lint (Biome, staged files) — clean via pre-commit hook
  • CI quality gate green (full coverage run — not run locally per this repo's low-end-hardware CI-cloud-first policy)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • DuckDB now emits progress details when OPFS setup fails and cleanly falls back to a supported connection path.
    • DuckDB query, execution, and shutdown behaviors are now more consistent, including initialization error handling.
    • Inference results are normalized consistently across embedding/sentiment/summary/text-generation, with proper cancellation handling.
  • Tests

    • Added unit tests for the DuckDB worker v2 lifecycle, OPFS fallback scenarios, query/exec, and shutdown.
    • Added unit tests for inference handling across supported task types, output normalization, cancellation, and inference option forwarding.

…ests

Neither workers/v2/duckdb.worker.ts's handlers nor
workers/v2/inference.worker.ts's handleInference were exported or
unit-tested against real logic (only webllm.worker.ts had that,
tests/unit/webllmWorkerHandler.test.ts) despite both already being
registered as live WorkerBus v2 pools with zero production callers —
docs/adr/0014-worker-generation-duplication.md's deferred migration
needs these to actually match v1 before any consumer cuts over.

Testing surfaced a real gap: initDuckDb()'s OPFS-unavailable catch
block silently swallowed the failure, unlike v1's out-of-band
OPFS_FALLBACK message that lets the UI warn users their analytics
won't persist. Fixed by threading ctx.emitProgress into initDuckDb()
and emitting an 'opfs-fallback' progress stage from the catch block —
reuses the existing progress channel WebLLM already uses for download
progress, no new message-protocol/schema change needed.

First PR of the ADR-0014 consolidation sprint (5 PRs total, see
.claude/plans/worker-generation-v1-vs-enumerated-fox.md).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
worldscript-studio Ready Ready Preview, Comment Jul 29, 2026 5:46pm

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c003d8fd-470b-41f6-988b-786d99d5197c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds direct unit-test coverage for v2 DuckDB and inference worker handlers. DuckDB initialization now reports OPFS fallback progress, and both workers export handlers for test access.

Changes

DuckDB worker handlers

Layer / File(s) Summary
Handler exports and OPFS fallback reporting
workers/v2/duckdb.worker.ts
Exports DuckDB handlers, accepts an optional progress emitter during initialization, cleans up partial OPFS connections, and emits opfs-fallback when OPFS setup fails.
Handler behavior tests
tests/unit/duckdbWorkerHandler.test.ts
Tests mocked initialization, OPFS behavior, query and exec responses, initialization errors, and shutdown cleanup.

Inference worker handler

Layer / File(s) Summary
Handler export
workers/v2/inference.worker.ts
Exports handleInference without changing its runtime logic or task wiring.
Inference behavior tests
tests/unit/inferenceWorkerHandlerV2.test.ts
Tests abort handling, embedding normalization, progress events, sentiment formatting, text extraction, and option forwarding.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the PR’s main change: exporting v2 DuckDB/inference handlers and adding parity-focused tests.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/worker-v2-parity-gate

Comment @coderabbitai help to get the list of available commands.

@codeant-ai

codeant-ai Bot commented Jul 29, 2026

Copy link
Copy Markdown

🏁 CodeAnt Quality Gate Results

Commit: bcc41c27
Scan Time: 2026-07-29 17:46:34 UTC

✅ Overall Status: PASSED

Quality Gate Details

Quality Gate Status Details
Secrets ✅ PASSED 0 secrets found
Duplicate Code ✅ PASSED 1.8% duplicated
SAST ✅ PASSED No security issues
Bugs ✅ PASSED Rating S: No bugs
IAC ✅ PASSED No IAC issues

View Full Results

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@workers/v2/duckdb.worker.ts`:
- Around line 45-46: Replace the multi-line QNBS-v3 annotations with one
immediate comment in the required “// QNBS-v3: [Reason / impact / creative
value]” format: workers/v2/duckdb.worker.ts lines 45-46 for the export rationale
and lines 76-79 for the fallback-channel rationale;
tests/unit/duckdbWorkerHandler.test.ts lines 2-5 for the suite rationale, 17-18
for hoisting, 31-32 for constructability, 58 for import order, 91-92 for the
shutdown mock, and 99-101 for state reset. Preserve each annotation’s original
rationale while collapsing it to a single bracketed line.
- Around line 75-85: Update workers/v2/duckdb.worker.ts lines 75-85 to retain
the OPFS connection separately, close it in the ATTACH failure catch path, then
create and assign the fallback connection. Update
tests/unit/duckdbWorkerHandler.test.ts lines 150-157 to use distinct OPFS and
fallback connections and assert the OPFS connection’s close() method is called.

In `@workers/v2/inference.worker.ts`:
- Around line 45-46: Replace the multi-line QNBS annotations with adjacent
single-line bracketed comments using the required “QNBS-v3: [Grund / Impact /
Kreativer Mehrwert]” format: update the handler export annotation in
workers/v2/inference.worker.ts at lines 45-46, collapse the file-purpose
annotation in tests/unit/inferenceWorkerHandlerV2.test.ts at lines 2-6, and
reformat the import-order annotation at line 17. Preserve each annotation’s
original intent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4df0d1fa-34af-4230-be78-c6bafca5f8de

📥 Commits

Reviewing files that changed from the base of the PR and between dc14bc0 and b4b1bbf.

📒 Files selected for processing (4)
  • tests/unit/duckdbWorkerHandler.test.ts
  • tests/unit/inferenceWorkerHandlerV2.test.ts
  • workers/v2/duckdb.worker.ts
  • workers/v2/inference.worker.ts

Comment thread workers/v2/duckdb.worker.ts Outdated
Comment thread workers/v2/duckdb.worker.ts
Comment thread workers/v2/inference.worker.ts Outdated
@codecov

codecov Bot commented Jul 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…S-v3 format

CodeRabbit review on #286 found a real bug: initDuckDb()'s OPFS catch
block overwrote `connection` with the fallback connection without
closing the first (partially-attached) one, leaking a DuckDB
connection on every OPFS-attach failure. Fixed by tracking the OPFS
attempt in its own local variable and closing it in the catch path
before falling back. New regression test asserts close() is called.

Also collapsed several multi-line QNBS-v3 comments in
workers/v2/duckdb.worker.ts, workers/v2/inference.worker.ts, and both
new test files to the required single bracketed-line format.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@qnbs

qnbs commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
workers/v2/duckdb.worker.ts (1)

81-87: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Keep OPFS fallback running if cleanup fails. await opfsConnection?.close() can reject inside this catch, which skips emitProgress('opfs-fallback', ...) and the fallback newDb.connect(), and also hides the original OPFS error. Make cleanup best-effort, log the close failure separately, and still continue to the fallback connection. Add a regression test where close() rejects but fallback init succeeds.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@workers/v2/duckdb.worker.ts` around lines 81 - 87, Make OPFS cleanup in the
fallback catch best-effort: wrap opfsConnection.close() in its own error
handling, log any close failure separately without replacing the original OPFS
error, then always emit the opfs-fallback progress event and run
newDb.connect(). Add a regression test covering a rejecting close() with
successful fallback initialization.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@workers/v2/duckdb.worker.ts`:
- Around line 81-87: Make OPFS cleanup in the fallback catch best-effort: wrap
opfsConnection.close() in its own error handling, log any close failure
separately without replacing the original OPFS error, then always emit the
opfs-fallback progress event and run newDb.connect(). Add a regression test
covering a rejecting close() with successful fallback initialization.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 061cd04e-91f6-4502-9d44-911a9ca35e0a

📥 Commits

Reviewing files that changed from the base of the PR and between b4b1bbf and bcc41c2.

📒 Files selected for processing (4)
  • tests/unit/duckdbWorkerHandler.test.ts
  • tests/unit/inferenceWorkerHandlerV2.test.ts
  • workers/v2/duckdb.worker.ts
  • workers/v2/inference.worker.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • workers/v2/inference.worker.ts
  • tests/unit/duckdbWorkerHandler.test.ts
  • tests/unit/inferenceWorkerHandlerV2.test.ts

@qnbs
qnbs merged commit ea879e4 into main Jul 29, 2026
26 checks passed
@qnbs
qnbs deleted the feat/worker-v2-parity-gate branch July 29, 2026 18:10
@qnbs

qnbs commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

Addressed the outside-diff-range finding from the second CodeRabbit pass (workers/v2/duckdb.worker.ts:81-87, "Keep OPFS fallback running if cleanup fails") in dbebf5c: opfsConnection?.close() is now wrapped in its own try/catch — a rejecting close() no longer skips the opfs-fallback progress emit or the fallback connect(), and no longer replaces the original ATTACH error. Added a regression test covering a rejecting close() with successful fallback init.

@qnbs

qnbs commented Jul 29, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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