Skip to content

Fix critical reliability bugs across extension#1

Open
ashrielbrian wants to merge 4 commits intomasterfrom
fix/reliability-bugs
Open

Fix critical reliability bugs across extension#1
ashrielbrian wants to merge 4 commits intomasterfrom
fix/reliability-bugs

Conversation

@ashrielbrian
Copy link
Owner

@ashrielbrian ashrielbrian commented Mar 20, 2026

Summary

Commit 1: Core reliability fixes

  • Unified DB storage path: popup used idb://casper.db while background used idb://casper — two separate databases, so search always returned empty. Both now share DB_STORAGE constant.
  • Fixed missing page inserts: added getOrCreatePage() so pages are inserted before embeddings, eliminating orphaned rows with page_id = null.
  • Fixed race conditions: consolidated process_page handler into a single lock acquisition (was 3 separate lock/unlock cycles). sendResponse now called after the lock releases.
  • Fixed hung message channels: added try/catch to all 3 background message handlers so sendResponse is always called, even on errors.
  • Fixed silent filter failures: saveFilterSites and removeFilterSites used forEach(async ...) which doesn't await — transactions committed with zero queries. Replaced with for...of.
  • Fixed SQL injection: parameterized embedding arrays, INTERVAL values, and added table name allowlist for countRows.
  • Fixed React bugs: null guards on worker, try/catch/finally on search, corrected useEffect dependency arrays in Search and Settings, null-safe rendering in SearchResults.
  • Hardened utilities: extractDomain wrapped in try/catch, zip handles mismatched array lengths.
  • Operational fixes: getDB() error recovery, cached tokenizer singleton, content script error handling, worker cleanup on unmount.
  • Cleanup: removed dead getDBName, unused PGliteWorker import, no-op saveModelType, console.logs.

Commit 2: Logging, HNSW index fix, PGliteWorker.create()

  • Added [casper]-prefixed logging to all background.ts message handlers — processing decisions (skip/process/done) and errors are now visible in the service worker console. Previously there was zero logging, making it impossible to diagnose "embeddings not generated" reports.
  • Content script checks background response and logs a warning on failure (errors were silently discarded).
  • Fixed HNSW index DDLCREATE INDEX ON embedding USING hnsw ... was missing IF NOT EXISTS, causing initSchema to fail on second invocation and breaking all subsequent DB operations in that process lifetime.
  • Added initSchema idempotency test to prevent the HNSW index bug from regressing.
  • Switched popup to PGliteWorker.create() — documented async API with proper TypeScript extension types.

Commit 3: Fix search result anchor navigation

  • Fixed chunk ID tracking: chunk IDs were set to the last node in each chunk instead of the first, causing search result links to scroll to the wrong section of the page. Now curr_id is set once from the first node and reset correctly when a new chunk begins.
  • Cleaned up empty fragment anchors: SearchResults.tsx no longer appends a bare # when chunk_tag_id is null/empty.

Commit 4: Fix Settings page reliability

  • nukeDb: wrapped in transaction, removed redundant deletes already handled by ON DELETE CASCADE.
  • onSettingsSave: moved setHasChanged(false) after the async updateSites() call so the Save button stays enabled if the save fails. Added try/catch with error logging.
  • Auto-dismiss confirmation: "Database cleared!" message now disappears after 3 seconds instead of persisting for the entire popup session.
  • Test crypto polyfill: added tests/setup.ts to polyfill globalThis.crypto for Node 18 — crypto.randomUUID() in initSchema was causing all tests to fail under the tsx loader.
  • Added nukeDb test: verifies page/embedding/cache are cleared while filter sites are preserved.

Test plan

  • pnpm test — all 9 tests pass (including nukeDb and idempotency tests)
  • pnpm build — production build succeeds
  • Load unpacked extension in Chrome (build/chrome-mv3-prod)
  • Browse pages → service worker console shows [casper] Processing <url> / [casper] Done processing <url>
  • Revisit same page → console shows [casper] Skipping <url> (already processed)
  • Open popup → search returns results (validates unified DB + page inserts)
  • Click search result → browser scrolls to the beginning of the matched content section, not the end
  • Settings → Clear Database → confirmation appears and auto-dismisses after 3s; filter list unchanged
  • Settings → add filter → Save → reopen popup → filter persists
  • Settings → remove filter → Save → reopen popup → filter gone
  • If errors occur, they're now visible in both the service worker and page consoles

🤖 Generated with Claude Code

ashrielbrian and others added 4 commits March 20, 2026 15:21
…ection, error handling

- Unify popup/background DB storage path (idb://casper) so search actually returns results
- Add getOrCreatePage() so pages are inserted before embeddings (fixes orphaned rows)
- Consolidate process_page into single lock acquisition (fixes race conditions)
- Add try/catch to all background message handlers (fixes hung responses)
- Replace forEach(async...) with for...of in filter transactions (fixes silent failures)
- Parameterize all SQL queries (fixes SQL injection in storeEmbeddings, intervals, countRows)
- Add null safety and fix React dependency arrays in Search/Settings/SearchResults
- Wrap extractDomain in try/catch, fix zip for mismatched arrays
- Cache tokenizer singleton, add getDB error recovery, clean up dead code

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add [casper]-prefixed console logging to all background.ts message
  handlers so processing decisions and errors are visible in the
  service worker console
- Content script now checks background response and warns on failure
- Fix HNSW index CREATE missing IF NOT EXISTS (caused initSchema to
  fail on second invocation, breaking all subsequent DB operations)
- Add initSchema idempotency regression test
- Switch popup to PGliteWorker.create() (documented async API)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Chunk IDs were tracking the last node instead of the first, causing
search result links to scroll to the wrong location. Also cleaned up
empty fragment anchors in SearchResults.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…iss confirmation

- nukeDb: wrap in transaction, remove redundant cascade-covered deletes
- onSettingsSave: move setHasChanged after await, add try/catch
- deleteDb: auto-dismiss "Database cleared!" message after 3s
- Add nukeDb test verifying page/embedding/cache cleared, filters preserved
- Fix pre-existing crypto polyfill issue for Node 18 test environment

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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