Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
# drive-transport-https-v1
## Why
`@suaveplan/drive-mesh-protocol` defines the wire format for chunk
discovery / request / delivery envelopes. To put those envelopes on
the wire, drive-mesh consumers need a `TransportLike<MessageEnvelope>`
implementation. This change ships the first one — an HTTPS-relay
backed transport that works in browsers, sits behind any TLS
proxy, and only requires the relay to host an HTTP server.
The HTTPS path is the lowest-friction connectivity tier in the drive
stack: every browser, every server, every CI runner can speak it.
WebRTC and WebSocket transports follow.
## What Changes
- New package `@suaveplan/drive-transport-https` at
`packages/drive/drive-transport-https/` with full Vite + Vitest +
Biome scaffolding.
- `HttpsTransport` class implementing
`TransportLike<MessageEnvelope>` from `@suaveplan/types/transport`
with explicit `start()` / `stop()` lifecycle.
- Long-poll receive loop (`GET /recv?for=...&since=cursor&timeoutMs=...`)
with exponential backoff, equal jitter, AbortSignal cancellation,
and a `lastAuthError` diagnostic getter for credential-refresh
flows.
- Stateless send (`POST /send` with `{ to, envelope }` body) with
Zod-validated request and response shapes.
- Nine frozen `HTTPS_TRANSPORT_CODES` (`NOT_CONNECTED` / `CLOSED` /
`SEND_FAILED` / `RECV_FAILED` / `AUTH_FAILED` /
`RELAY_UNAVAILABLE` / `MALFORMED_RESPONSE` / `ABORTED` /
`PEER_UNKNOWN`).
- Auth-failure short-circuit: a `401`/`403` from `/recv` stops the
loop instead of looping forever — back-pressure belongs to the
consumer.
- 58 tests across 6 files at 100/100/100/100 coverage; 5/5 docs
coverage.
## Impact
- New public package. No consumers yet — drive-mesh wiring will
follow.
- Browser-friendly: no Node-only imports. Works against any HTTP
relay that implements the documented `/send` and `/recv`
endpoints.

View File

@@ -0,0 +1,77 @@
# drive-transport-https spec — v1
## ADDED Requirements
### Requirement: Implements TransportLike<MessageEnvelope>
`HttpsTransport` SHALL implement the structural
`TransportLike<MessageEnvelope>` contract from
`@suaveplan/types/transport`: `connect(peerId, address)`,
`disconnect(peerId)`, `send(peerId, envelope)`,
`onMessage(handler) → Unsubscribe`, `getConnectedPeers()`. It SHALL
add lifecycle methods `start()` / `stop()` so the long-poll loop
does not begin until the consumer is ready and so the loop can be
cleanly torn down on shutdown.
**Verified by:** `tests/lifecycle.test.ts` (eleven scenarios).
### Requirement: Long-poll receive with cursor
The transport SHALL maintain a string `cursor` initialised to `""`.
Every long-poll request SHALL include the cursor as the `since`
query parameter when non-empty; on response, the cursor SHALL be
replaced with the `nextCursor` field from the parsed
`RecvResponse`.
**Verified by:** `tests/recv.test.ts`::"includes since=cursor on
subsequent /recv calls" AND "cursor starts empty and updates after
a successful /recv" (`tests/lifecycle.test.ts`).
### Requirement: Auth-failure short-circuit
A `401` or `403` response from `/recv` SHALL terminate the receive
loop. The transport's `state` SHALL transition to `"stopped"` and
the `lastAuthError` getter SHALL expose the typed
`HttpsTransportError(HTTPS_TRANSPORT.AUTH_FAILED, ...)`. The
transport SHALL NOT auto-retry on auth failure — credential refresh
belongs to the consumer.
**Verified by:** `tests/recv.test.ts`::"AUTH_FAILED on /recv stops
the loop" AND "AUTH_FAILED on /recv propagates via lastAuthError".
### Requirement: Exponential backoff with equal jitter
On a transient receive failure (`5xx` /
`HTTPS_TRANSPORT.RECV_FAILED` /
`HTTPS_TRANSPORT.MALFORMED_RESPONSE`), the loop SHALL back off and
retry. Wait times SHALL follow an equal-jitter formula
`exp / 2 + rand(0, exp/2)` clamped to `[backoffBaseMs,
backoffMaxMs]` with `exp = backoffBaseMs * 2^(failures-1)`.
**Verified by:** `tests/recv.test.ts`::"backs off on 503 and
retries", "backs off on 4xx other than auth (RECV_FAILED) and
retries", "backs off on malformed JSON body (MALFORMED_RESPONSE)
and retries".
### Requirement: Send wire contract
`send(peerId, envelope)` SHALL `POST` to `${relayUrl}/send` with
`{ to, envelope }` as JSON. The peer SHALL be in the `connected`
set or `HTTPS_TRANSPORT.PEER_UNKNOWN` is thrown. `401`/`403`
responses SHALL throw `AUTH_FAILED`; `5xx` responses SHALL throw
`RELAY_UNAVAILABLE`; other non-2xx responses SHALL throw
`SEND_FAILED`. `200` responses SHALL be Zod-validated against
`SendResponseSchema`; `ok: false` SHALL throw `SEND_FAILED` with
the relay's `code` (or `"unknown"`) in the message.
**Verified by:** `tests/send.test.ts` (fifteen scenarios).
### Requirement: Lifecycle invariants
`start()` SHALL throw `HTTPS_TRANSPORT.CLOSED` if called after
`stop()`. `start()` SHALL be idempotent while `state === "running"`.
`stop()` SHALL be idempotent. `connect()` and `send()` SHALL throw
`HTTPS_TRANSPORT.NOT_CONNECTED` if the transport has not been
started, and `HTTPS_TRANSPORT.CLOSED` if it has been stopped.
**Verified by:** `tests/lifecycle.test.ts` and `tests/send.test.ts`.

View File

@@ -0,0 +1,50 @@
# tasks — drive-transport-https-v1
## 1. Package scaffolding
- [x] 1.1 `package.json` with subpath exports for root, types,
schemas, errors.
- [x] 1.2 `vite.config.ts` with the standard externals list.
- [x] 1.3 `tsconfig.lib.json` extending the base config.
- [x] 1.4 `vitest.config.ts` via `createTestConfig()`.
## 2. Error registry
- [x] 2.1 Define the nine `HTTPS_TRANSPORT_CODES` and `HttpsTransportError`.
- [x] 2.2 Co-located `error-codes.md` (≥200-word doc).
## 3. Public types
- [x] 3.1 `HttpsTransportOptions`, `FetchFn`, `RecvResponse`,
`SendBody`, `SendResponse`, `Unsubscribe` in `types/transport.types.ts`.
- [x] 3.2 Co-located `transport.types.md`.
## 4. Boundary schemas
- [x] 4.1 Zod schemas: `HttpsTransportOptionsSchema`,
`SendBodySchema`, `SendResponseSchema`, `RecvResponseSchema`.
- [x] 4.2 Co-located `transport.schema.md`.
## 5. Transport runtime
- [x] 5.1 `HttpsTransport` class implementing `TransportLike`.
- [x] 5.2 Long-poll receive loop with backoff + jitter.
- [x] 5.3 `lastAuthError` diagnostic getter for the auth-fail
termination path.
- [x] 5.4 `defaults.ts` constants module.
- [x] 5.5 Co-located `https-transport.md` and `defaults.md`.
## 6. Tests
- [x] 6.1 `error-codes.spec-conformance.test.ts`.
- [x] 6.2 `schemas.test.ts`.
- [x] 6.3 `lifecycle.test.ts`.
- [x] 6.4 `send.test.ts`.
- [x] 6.5 `recv.test.ts`.
- [x] 6.6 `default-fetch.test.ts` (isolated globalThis.fetch tests).
## 7. Gates
- [x] 7.1 `bunx turbo lint typecheck test --filter=...` green.
- [x] 7.2 `bunx turbo test:coverage --filter=...` at 100/100/100/100.
- [x] 7.3 `bun run docs:check` reports 5/5 files.