2.4 KiB
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
bodyshape viagetReaderduck-test. - Forward
createWriteStreamonly when present AND body is a stream. - Drain-and-set fallback for both buffered bodies and missing
createWriteStream. SuaveplanErrorpass-through onadapter.setthrow;WRITE_UNSUPPORTEDwrap withcausepreserved for non-namespaced throwables only.
Usage: Basic
import { writeViaPlugin } from "@suaveplan/storage-uri/resolver";
await writeViaPlugin(plugin, "file:///a.bin", "a.bin", new Uint8Array([1, 2, 3]), undefined);
Usage: Advanced
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.