Initial Commit
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# resolver.writes
|
||||
|
||||
## Purpose
|
||||
|
||||
Implements the `write(uri, body, signal?)` semantics. Accepts either
|
||||
`Uint8Array` or `ReadableStream<Uint8Array>` for the body, forwards a native
|
||||
`createWriteStream` when the adapter exposes one and the body is a stream,
|
||||
and otherwise drains the stream (via `new Response(stream).arrayBuffer()`)
|
||||
into a single `adapter.set` call. The drain path increments
|
||||
`storage_uri.buffered_write_total{scheme}` so operators can alert on
|
||||
mis-composed adapters that quietly buffer large payloads.
|
||||
|
||||
`SuaveplanError` subclasses thrown by `adapter.set` (any package's
|
||||
namespaced error — `DriveUriError`, `StorageHttpError`, etc.) pass through
|
||||
unchanged so consumers can route on the original `code`. Non-namespaced
|
||||
throwables (plain `Error`, foreign objects) are wrapped as
|
||||
`STORAGE_URI.WRITE_UNSUPPORTED` with the original preserved as `cause`,
|
||||
giving a normalised failure mode for read-only adapters that lack their
|
||||
own error class.
|
||||
|
||||
## Features
|
||||
|
||||
- Branch on `body` shape via `getReader` duck-test.
|
||||
- Forward `createWriteStream` only when present AND body is a stream.
|
||||
- Drain-and-set fallback for both buffered bodies and missing
|
||||
`createWriteStream`.
|
||||
- `SuaveplanError` pass-through on `adapter.set` throw; `WRITE_UNSUPPORTED`
|
||||
wrap with `cause` preserved for non-namespaced throwables only.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { writeViaPlugin } from "@suaveplan/storage-uri/resolver";
|
||||
|
||||
await writeViaPlugin(plugin, "file:///a.bin", "a.bin", new Uint8Array([1, 2, 3]), undefined);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
async function writeStream(resolver: StorageUriResolver, uri: string, src: AsyncIterable<Uint8Array>): Promise<void> {
|
||||
const stream = new ReadableStream<Uint8Array>({
|
||||
async start(ctrl) {
|
||||
for await (const chunk of src) ctrl.enqueue(chunk);
|
||||
ctrl.close();
|
||||
},
|
||||
});
|
||||
await resolver.write(uri, stream);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `function writeViaPlugin(plugin, uri, key, body, signal): Promise<void>`
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`new Response(stream).arrayBuffer()` is the cheapest cross-runtime way to
|
||||
drain a Web Stream into a contiguous buffer; it works in Node 18+, Bun, and
|
||||
every browser without any polyfill. The `WRITE_UNSUPPORTED` re-wrap is
|
||||
distinct from the `ADAPTER_ERROR` wrap in `resolver.ts` because callers
|
||||
typically branch on these two conditions differently — `WRITE_UNSUPPORTED`
|
||||
is a capability miss while `ADAPTER_ERROR` is a transient upstream fault.
|
||||
Reference in New Issue
Block a user