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

5.4 KiB

Tasks — storage-browser-opfs

Every checkbox MUST reflect work actually done in this change.

1. Spec authoring

  • 1.1 Read ../suaveplan/enterprise/storage-browser-opfs.md end-to-end
  • 1.2 Read openspec/specs/storage/spec.md and confirm capability boundary
  • 1.3 Read openspec/AGENTS.md Sections 13 and 14
  • 1.4 Draft proposal.md from openspec/templates/proposal.md
  • 1.5 Fill in ## Source mapping table — every requirement cites a line range OR appears in the "no source line" table
  • 1.6 Draft specs/storage-browser-opfs/spec.md from openspec/templates/spec-delta.md
  • 1.7 Every requirement in the spec delta carries a **Verified by:** line naming concrete it(...) titles

2. Scaffolding

  • 2.1 Create packages/storage/storage-browser-opfs/ mirroring packages/storage/storage-file/ conventions
  • 2.2 Write package.json v0.0.0, "sideEffects": false, "browser" field, subpath exports per feature module
  • 2.3 Wire deps: @suaveplan/error, @suaveplan/storage, @suaveplan/types, @opentelemetry/api, zod, tslib
  • 2.4 Wire devDeps: @suaveplan/testing, @vitest/coverage-istanbul, fast-check, typescript, vite, vite-plugin-dts, vitest
  • 2.5 Write tsconfig.json, tsconfig.lib.json, vite.config.ts, vitest.config.ts
  • 2.6 Write tests/setup/polyfills.ts and README.md skeleton

3. Implementation

  • 3.1 src/error-codes.ts — defineCodes("OPFS", [9 codes]), OpfsError class, key discriminant
  • 3.2 src/types/opfs-storage.types.ts — OpfsStorageOptions interface + OpfsStorageOptionsSchema Zod schema
  • 3.3 src/types/opfs-like.types.ts — OpfsLike structural interface + companion FileSystemDirectoryHandle-shaped types
  • 3.4 src/opfs-adapter/opfs-adapter.ts — defaultOpfs() factory + isOpfsAvailable() feature detector
  • 3.5 src/key-sanitizer/key-sanitizer.ts — sanitizeKey(key) strict boundary
  • 3.6 src/filename-codec/filename-codec.ts — base64url encode/decode over UTF-8 bytes
  • 3.7 src/otel/otel.ts — meters/histograms/counters/tracer, recordOp(...), setStorageBrowserOpfsMeterProvider
  • 3.8 src/opfs-storage/opfs-storage.ts — OpfsStorage extends AbstractStorage, all abstract methods, AbortSignal, capabilities matrix, DOMException mapping
  • 3.9 src/in-memory-opfs/in-memory-opfs.ts — test-double directory handle exposed under ./in-memory-opfs subpath for downstream test packages
  • 3.10 src/registry/registry.ts — declare module "@suaveplan/storage/factory" + registerOpfsProvider()
  • 3.11 src/index.ts — explicit named re-exports per §6a

4. Tests

  • 4.1 src/key-sanitizer/key-sanitizer.test.ts — valid, traversal, absolute, null bytes, control chars, overlong, separator normalisation
  • 4.2 src/filename-codec/filename-codec.test.ts — round-trip, unicode, fast-check identity property
  • 4.3 src/opfs-adapter/opfs-adapter.test.ts — defaultOpfs resolves dir handle when present; throws OPFS.UNAVAILABLE when absent; isOpfsAvailable returns boolean without throwing
  • 4.4 src/otel/otel.test.ts — metrics observed via real in-memory MeterProvider
  • 4.5 src/opfs-storage/opfs-storage.test.ts — full CRUD + metadata + list + clear + getSize + getPartial + setPartial + streams + AbortSignal + DOMException mapping
  • 4.6 src/opfs-storage/opfs-storage.spec-conformance.test.ts — type conformance, capabilities, OTel instruments emitted, options validation, error-code exhaustion
  • 4.7 src/registry/registry.test.ts — registers opfs slot, factory dispatch, idempotency
  • 4.8 src/in-memory-opfs/in-memory-opfs.test.ts — the test double itself
  • 4.9 Every it(...) carries { timeout: 5000 } (or 30000 for genuinely async)

5. Documentation

  • 5.1 Sibling .md for every implementation .ts (≥200 words, basic + advanced examples, full API reference)
  • 5.2 README.md links every module under ## Modules

6. Gates

  • 6.1 bun run check
  • 6.2 bunx turbo lint typecheck test --filter=@suaveplan/storage-browser-opfs
  • 6.3 bunx turbo test:coverage --filter=@suaveplan/storage-browser-opfs (100/100/100/100)
  • 6.4 bun scripts/openspec-conformance.ts @suaveplan/storage-browser-opfs
  • 6.5 bunx turbo build --filter=@suaveplan/storage-browser-opfs

7. Pre-archive 9-row checklist

  • 7.1 Structural injectable seams (OpfsLike, Clock)
  • 7.2 Zod schemas wired at every declared boundary
  • 7.3 Every error code thrown by at least one production path
  • 7.4 OTel instruments emitted from production paths; asserted via real in-memory MeterProvider
  • 7.5 Capabilities matrix matches the spec (partialReads/partialWrites/nativeStreams = true; atomicWrites/contentAddressable = false)
  • 7.6 No export * in feature-module barrels (§6a)
  • 7.7 No direct vitest / bun:test imports in tests (§7)
  • 7.8 No banned patterns in src/ (TODO/FIXME/ts-ignore/.skip/.only)
  • 7.9 README + sibling .md files complete

8. Archive

  • 8.1 Fold spec delta into openspec/specs/storage-browser-opfs/spec.md
  • 8.2 Move openspec/changes/storage-browser-opfs/ → openspec/archive/<yyyy-mm-dd>-storage-browser-opfs/
  • 8.3 Refresh MANIFEST.md via bun scripts/folder-reorg/generate-manifest.ts
  • 8.4 Update CLAUDE.md package listing under storage family