Files
suaveplan/openspec/archive/2026-05-12-storage-browser-opfs/tasks.md
2026-05-27 23:29:53 +01:00

81 lines
5.4 KiB
Markdown

# Tasks — storage-browser-opfs
> Every checkbox MUST reflect work actually done in this change.
## 1. Spec authoring
- [x] 1.1 Read `../suaveplan/enterprise/storage-browser-opfs.md` end-to-end
- [x] 1.2 Read `openspec/specs/storage/spec.md` and confirm capability boundary
- [x] 1.3 Read `openspec/AGENTS.md` Sections 13 and 14
- [x] 1.4 Draft `proposal.md` from `openspec/templates/proposal.md`
- [x] 1.5 Fill in `## Source mapping` table — every requirement cites a line range OR appears in the "no source line" table
- [x] 1.6 Draft `specs/storage-browser-opfs/spec.md` from `openspec/templates/spec-delta.md`
- [x] 1.7 Every requirement in the spec delta carries a `**Verified by:**` line naming concrete `it(...)` titles
## 2. Scaffolding
- [x] 2.1 Create `packages/storage/storage-browser-opfs/` mirroring `packages/storage/storage-file/` conventions
- [x] 2.2 Write `package.json` v0.0.0, `"sideEffects": false`, `"browser"` field, subpath exports per feature module
- [x] 2.3 Wire deps: `@suaveplan/error`, `@suaveplan/storage`, `@suaveplan/types`, `@opentelemetry/api`, `zod`, `tslib`
- [x] 2.4 Wire devDeps: `@suaveplan/testing`, `@vitest/coverage-istanbul`, `fast-check`, `typescript`, `vite`, `vite-plugin-dts`, `vitest`
- [x] 2.5 Write `tsconfig.json`, `tsconfig.lib.json`, `vite.config.ts`, `vitest.config.ts`
- [x] 2.6 Write `tests/setup/polyfills.ts` and `README.md` skeleton
## 3. Implementation
- [x] 3.1 `src/error-codes.ts` — `defineCodes("OPFS", [9 codes])`, `OpfsError` class, `key` discriminant
- [x] 3.2 `src/types/opfs-storage.types.ts` — `OpfsStorageOptions` interface + `OpfsStorageOptionsSchema` Zod schema
- [x] 3.3 `src/types/opfs-like.types.ts` — `OpfsLike` structural interface + companion `FileSystemDirectoryHandle`-shaped types
- [x] 3.4 `src/opfs-adapter/opfs-adapter.ts` — `defaultOpfs()` factory + `isOpfsAvailable()` feature detector
- [x] 3.5 `src/key-sanitizer/key-sanitizer.ts` — `sanitizeKey(key)` strict boundary
- [x] 3.6 `src/filename-codec/filename-codec.ts` — base64url encode/decode over UTF-8 bytes
- [x] 3.7 `src/otel/otel.ts` — meters/histograms/counters/tracer, `recordOp(...)`, `setStorageBrowserOpfsMeterProvider`
- [x] 3.8 `src/opfs-storage/opfs-storage.ts` — `OpfsStorage extends AbstractStorage`, all abstract methods, AbortSignal, capabilities matrix, DOMException mapping
- [x] 3.9 `src/in-memory-opfs/in-memory-opfs.ts` — test-double directory handle exposed under `./in-memory-opfs` subpath for downstream test packages
- [x] 3.10 `src/registry/registry.ts` — `declare module "@suaveplan/storage/factory"` + `registerOpfsProvider()`
- [x] 3.11 `src/index.ts` — explicit named re-exports per §6a
## 4. Tests
- [x] 4.1 `src/key-sanitizer/key-sanitizer.test.ts` — valid, traversal, absolute, null bytes, control chars, overlong, separator normalisation
- [x] 4.2 `src/filename-codec/filename-codec.test.ts` — round-trip, unicode, fast-check identity property
- [x] 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
- [x] 4.4 `src/otel/otel.test.ts` — metrics observed via real in-memory `MeterProvider`
- [x] 4.5 `src/opfs-storage/opfs-storage.test.ts` — full CRUD + metadata + list + clear + getSize + getPartial + setPartial + streams + AbortSignal + DOMException mapping
- [x] 4.6 `src/opfs-storage/opfs-storage.spec-conformance.test.ts` — type conformance, capabilities, OTel instruments emitted, options validation, error-code exhaustion
- [x] 4.7 `src/registry/registry.test.ts` — registers `opfs` slot, factory dispatch, idempotency
- [x] 4.8 `src/in-memory-opfs/in-memory-opfs.test.ts` — the test double itself
- [x] 4.9 Every `it(...)` carries `{ timeout: 5000 }` (or 30000 for genuinely async)
## 5. Documentation
- [x] 5.1 Sibling `.md` for every implementation `.ts` (≥200 words, basic + advanced examples, full API reference)
- [x] 5.2 `README.md` links every module under `## Modules`
## 6. Gates
- [x] 6.1 `bun run check`
- [x] 6.2 `bunx turbo lint typecheck test --filter=@suaveplan/storage-browser-opfs`
- [x] 6.3 `bunx turbo test:coverage --filter=@suaveplan/storage-browser-opfs` (100/100/100/100)
- [x] 6.4 `bun scripts/openspec-conformance.ts @suaveplan/storage-browser-opfs`
- [x] 6.5 `bunx turbo build --filter=@suaveplan/storage-browser-opfs`
## 7. Pre-archive 9-row checklist
- [x] 7.1 Structural injectable seams (`OpfsLike`, `Clock`)
- [x] 7.2 Zod schemas wired at every declared boundary
- [x] 7.3 Every error code thrown by at least one production path
- [x] 7.4 OTel instruments emitted from production paths; asserted via real in-memory `MeterProvider`
- [x] 7.5 Capabilities matrix matches the spec (partialReads/partialWrites/nativeStreams = true; atomicWrites/contentAddressable = false)
- [x] 7.6 No `export *` in feature-module barrels (§6a)
- [x] 7.7 No direct `vitest` / `bun:test` imports in tests (§7)
- [x] 7.8 No banned patterns in `src/` (`TODO`/`FIXME`/`ts-ignore`/`.skip`/`.only`)
- [x] 7.9 README + sibling `.md` files complete
## 8. Archive
- [x] 8.1 Fold spec delta into `openspec/specs/storage-browser-opfs/spec.md`
- [x] 8.2 Move `openspec/changes/storage-browser-opfs/` → `openspec/archive/<yyyy-mm-dd>-storage-browser-opfs/`
- [x] 8.3 Refresh `MANIFEST.md` via `bun scripts/folder-reorg/generate-manifest.ts`
- [x] 8.4 Update CLAUDE.md package listing under storage family