Skip to content
UniKVS
English
Esc
↑↓navigate↵open⌘Jpreview
On this page

Streaming

Explains how to store and read large data with streams.

Choosing types

Keys used with streams are defined with StreamValue<T> or Value<T>. Keys defined with PlainValue<T> cannot use stream().

const kvs = UniKvs.config<{
  logs: StreamValue<Uint8Array>;
  blob: Value<Uint8Array>;
}>()
  .appendStorage(new Memory())
  .create();
Type set get stream
PlainValue<T> Supported. Supported. Not supported.
StreamValue<T> Supports values or streams. Not supported. Supported.
Value<T> Supports values or streams. Supported. Supported.

When schema is specified, each chunk is validated. Bad write chunks are reported as PluginOperationAggregateError containing InvalidInputError, and bad read chunks are reported as InvalidOutputError.

Writing

You can pass either a plain value or a ReadableStream.

Save a single value

Pass a plain value for small data.

await kvs.set("logs", new Uint8Array([1, 2, 3]));

Save with a stream

Pass a ReadableStream to write large data incrementally.

const src = new ReadableStream({
  start(controller) {
    controller.enqueue(new Uint8Array([1]));
    controller.enqueue(new Uint8Array([2]));
    controller.close();
  },
});
await kvs.set("logs", src);

Reading

stream() returns a ValueStream. Choose from three patterns for your use case.

Use for fine-grained control over each chunk.

const reader = (await kvs.stream("logs")).getReader();
while (true) {
  const { done, value } = await reader.read();
  if (done) {
    break;
  }
  console.log(value);
}

Use for concise code.

for await (const chunk of await kvs.stream("logs")) {
  console.log(chunk);
}

Use for automatic release of the read lock.

await using (const valueStream = await kvs.stream("logs")) {
  const reader = valueStream.getReader();
  const { value } = await reader.read();
  console.log(value);
}

Notes by Storage

  • Files, S3, and OPFS are suitable for streaming byte data. See each package reference for details.
  • IndexedDB can store arbitrary data, but check the implementation constraints for stream handling.
  • Some Transformers do not support stream conversion. See each package reference for support status.

Cancellation

Long transfers can be interrupted with an AbortSignal.

const ac = new AbortController();
setTimeout(() => ac.abort(), 1000);

await kvs.set("logs", src, { signal: ac.signal });

Was this page helpful?