feat(sdk): stage 7 step 1 — http persist adapter (#1441)

## What

Adds `createHttpAdapter` — a browser-native `PersistAdapter` that reads and writes composition files through the Studio dev-server's `/api/projects/:id/files/...` endpoints using the Fetch API. Exported as a subpath: `@hyperframes/sdk/adapters/http`.

## Why

The SDK's `PersistAdapter` interface previously had filesystem (`fs`) and in-memory (`memory`) implementations, both Node-only. Studio runs in the browser and needs to persist compositions back to the dev server. This adapter is the browser-compatible plug that lets `openComposition` work in a Studio context without Node I/O.

## How

- `HttpAdapter` implements `PersistAdapter`: `read` → GET, `write` → PUT with per-path queue to serialize concurrent writes to the same file (at-most-once in-flight per path)
- `flush()` waits for all in-flight queues to drain
- `listVersions` / `loadFrom` proxy the server's version history endpoints
- `on('persist:error')` fires on network/non-2xx failures without throwing; callers can surface errors non-fatally
- Retry is caller's responsibility; the adapter does not retry

## Test plan

- `http.test.ts`: read/write round-trip with MSW, concurrent write serialization, persist:error event on 503, flush drains queue
- Contract suite (`persistAdapter.contract.test.ts`) passes for the http adapter against a mock server
This commit is contained in:
Vance Ingalls
2026-06-15 13:52:20 -07:00
committed by GitHub
parent 9175eced45
commit c19898e799
4 changed files with 434 additions and 0 deletions
+8
View File
@@ -29,6 +29,10 @@
"./adapters/headless": {
"import": "./src/adapters/headless.ts",
"types": "./src/adapters/headless.ts"
},
"./adapters/http": {
"import": "./src/adapters/http.ts",
"types": "./src/adapters/http.ts"
}
},
"publishConfig": {
@@ -49,6 +53,10 @@
"./adapters/headless": {
"import": "./dist/adapters/headless.js",
"types": "./dist/adapters/headless.d.ts"
},
"./adapters/http": {
"import": "./dist/adapters/http.js",
"types": "./dist/adapters/http.d.ts"
}
},
"main": "./dist/index.js",