Files
2026-05-27 23:29:53 +01:00

5.8 KiB

Tasks: enterprise-browser-pwa

Change ID: enterprise-browser-pwa Package: @suaveplan/pwa Target path: browser/platform/pwa Prerequisite packages on Verdaccio: @suaveplan/cache-browser, @suaveplan/error, @suaveplan/logger, @suaveplan/schema-registry


0. Pre-flight (non-negotiable)

  • 0.1 Confirm clean working tree (git status reports nothing) and no in-flight worktrees with uncommitted work (git worktree list then git status in each)
  • 0.2 If any worktrees exist under .claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
  • 0.3 Confirm the package set in MANIFEST.md matches find packages -maxdepth 3 -name package.json count. Drift here means a prior change archived without regenerating the manifest.

1. Scaffold

  • Create directory tree per proposal.md.
  • package.json v0.0.0, "sideEffects": false.
    • dependencies: @suaveplan/cache-browser workspace:^, @suaveplan/error workspace:^, @suaveplan/types workspace:^, @suaveplan/logger workspace:^, @suaveplan/schema-registry workspace:^, zod catalog:forms, @opentelemetry/api catalog:observability, tslib catalog:build
    • devDependencies: vitest catalog:testing, @vitest/coverage-istanbul catalog:testing, happy-dom catalog:testing, @playwright/test catalog:testing, @suaveplan/testing workspace:^
    • Subpath exports: ".", "./core/service-worker/service-worker", "./core/sync-queue/sync-queue", "./core/push-notifications/push-notifications", "./core/install-prompt/install-prompt", "./core/routing/routing"
  • tsconfig.json, vitest.config.ts (pool: forks, happy-dom environment, fileParallelism: false).

2. Error codes

  • SW_REGISTRATION_FAILED, SW_UPDATE_FAILED, PUSH_PERMISSION_DENIED, PUSH_UNSUPPORTED, SYNC_QUEUE_EXCEEDED.
  • registerPwaErrorCodes() — call eagerly.

3. Types (src/types/common.ts)

  • SwState, SwRegistrationOptions, SwRegistrationResult, PushPermission, PushSubscriptionResult, PushNotificationOptions, SyncQueueConfig, SyncQueueEntry, InstallPromptState, InstallPromptListener.
  • Write common.md.

4. SyncQueueEntry schema (src/schema/sync-queue-schema/)

  • sync-queue-schema.ts — SyncQueueEntrySchema (method, URL, headers, body, metadata); registerSyncQueueSchema().
  • Write sync-queue-schema.md.

5. SyncQueue storage backends (src/core/sync-queue/storage/)

  • storage.ts — StorageBackend interface: enqueue, dequeue, getAll, clear, getDepth.
  • IndexedDBSyncStorage via @suaveplan/cache-browser; LocalStorageSyncStorage fallback; MemorySyncStorage for tests.
  • Write storage.test.ts. Write storage.md.

6. SyncQueue (src/core/sync-queue/)

  • sync-queue.ts — composing StorageBackend; enqueue() validates via SyncQueueEntrySchema; throws SYNC_QUEUE_EXCEEDED over max.
  • flush() with exponential backoff; background-sync hook via SyncManager where supported.
  • Wire OTel metrics.
  • Write sync-queue.test.ts (enqueue, flush, backoff, clear, storage-backend swap). Write sync-queue.md.

7. ServiceWorkerManager (src/core/service-worker/)

  • service-worker.ts — register, unregister, update, skipWaiting, update-interval polling.
  • Throw SW_REGISTRATION_FAILED / SW_UPDATE_FAILED on failure.
  • Split tests into four files ≤ 500 lines: registration, update, lifecycle, events.
  • Write service-worker.md.

8. PushNotificationManager (src/core/push-notifications/)

  • push-notifications.ts — permission query, subscribe/unsubscribe, notify.
  • Throw PUSH_PERMISSION_DENIED / PUSH_UNSUPPORTED on failure.
  • Tests use real PushManager fixture via injectable adapter (no vi.stubGlobal).
  • Write push-notifications.test.ts, push-notifications.md.

9. InstallPromptManager (src/core/install-prompt/)

  • install-prompt.ts — capture beforeinstallprompt, expose prompt(), state listeners.
  • Wire OTel histogram pwa.install_prompt_latency_ms.
  • Write install-prompt.test.ts, install-prompt.md.

10. Routing DSL (src/core/routing/)

  • routing.ts — swRoute(pattern, strategy), networkFirst, cacheFirst, staleWhileRevalidate.
  • Strategies accept ttl, cacheName, fallback options.
  • Write routing.test.ts (pattern matching, strategy selection). Write routing.md.

11. Integration test (tests/integration.test.ts)

  • SyncQueue with MemorySyncStorage — enqueue, flush, backend swap.
  • ServiceWorkerManager registration + update cycle.
  • Routing DSL: register routes, simulate fetch, assert strategy applied.

12. Playwright E2E (e2e/pwa.spec.ts)

  • Chromium, WebKit, Firefox.
  • SW install → page reload → SW active.
  • SW update → skipWaiting → new SW takes over.
  • SyncQueue survives page reload via IndexedDB backend.
  • Push subscribe/unsubscribe (no real push server needed — test the subscribe call).

13. Docs + verify

  • Write .md per module (≥200 words, API reference, examples).
  • Write README.md with IndexedDB migration guide, routing DSL reference.
  • bunx turbo lint typecheck test --filter=@suaveplan/pwa — green.
  • bunx turbo test:coverage — 100%.
  • No @ts-expect-error in src/ or tests. No vi.stubGlobal.
  • Playwright E2E green on Chromium, WebKit, Firefox.
  • bun scripts/publish.ts --package @suaveplan/pwa.
  • Archive to openspec/archive/2026-04-24-enterprise-browser-pwa/.