Skip to content

fix(sw): stop silently dropping pending events when no deliveryUrl - #10

Merged
joelshejar merged 1 commit into
mainfrom
fix/sw-drain-respects-delivery-url
May 10, 2026
Merged

joelshejar merged 1 commit into
mainfrom
fix/sw-drain-respects-delivery-url

Conversation

@joelshejar

Copy link
Copy Markdown
Member

Summary

Fixes a silent data-loss bug in the Service Worker handoff path.

Two compounding bugs:

  1. `ServiceWorkerClient.register()` never forwarded `deliveryUrl` to the SW config message, so even when apps configured one, the SW couldn't see it.
  2. When `config.deliveryUrl` was unset (the only path the SW ever saw), the SW would mark every pending event as 'delivered' without sending it anywhere — then the cleanup transaction deleted them from IndexedDB. The inline comment claiming "events will be picked up by the next Hub" was wrong: by the time another Hub started, the SW had already deleted them.

What changes

  • Add `deliveryUrl` to `ServiceWorkerConfig`.
  • `ServiceWorkerClient.register()` now forwards `deliveryUrl` to the SW.
  • SW drain handler only marks entries delivered when `fetch()` returns ok. Without a `deliveryUrl`, leave pending entries in the outbox so the next Hub session drains them. TTL-expired entries are still GC'd.

Test plan

  • `pnpm --filter @tabmesh/core exec vitest --run` — 99/99 pass (was 98/98)
  • New test: `forwards deliveryUrl to the service worker config`
  • Existing config-shape test updated to expect the new field
  • Biome clean

Follow-up

  • The full SW handoff (Background Sync firing → IDB drain → fetch → next Hub picks up) should be exercised in the upcoming Playwright harness.

🤖 Generated with Claude Code

The Service Worker drain handler had a silent data-loss bug:

1. ServiceWorkerClient never forwarded `deliveryUrl` to the SW config
   message, so even when apps configured one, the SW couldn't see it.
2. When `config.deliveryUrl` was unset (the only path possible given
   #1), the SW marked every pending event as 'delivered' without
   sending it anywhere — and then the cleanup transaction deleted them
   from IndexedDB. The "events will be picked up by the next Hub" claim
   in the inline comment was wrong: the SW had already removed them.

Fix:

- Add `deliveryUrl` to ServiceWorkerConfig and pass it through
  ServiceWorkerClient.register() to the SW config message.
- In the SW drain, only mark entries delivered when fetch() returns ok.
  Without a deliveryUrl, leave pending entries in the outbox so the
  next Hub session drains them; still GC TTL-expired entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@joelshejar
joelshejar merged commit d3769b0 into main May 10, 2026
3 of 4 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