MeshKit

Streaming

Upload and download large encrypted content in authenticated chunks.

Use streaming when a file is too large or too incremental for a single files.put call. MeshKit stores encrypted chunks plus a stream manifest and returns a root CID for the stream.

Streaming is still encrypted storage. The provider receives encrypted chunk bytes and manifest metadata, not plaintext chunks.

Upload And Read A Stream

import { meshkit } from "@meshkit/meshkit";

async function* chunks() {
  yield new TextEncoder().encode("part one\n");
  yield new TextEncoder().encode("part two\n");
}

const mesh = await meshkit();

const uploaded = await mesh.files.putStream("logs/export.txt", chunks(), {
  chunkSize: 1024 * 1024,
  onProgress: (event) => {
    console.log(event.bytesProcessed, event.resumeToken?.nextChunkIndex);
  },
});

let text = "";

for await (const chunk of mesh.files.getStream(uploaded.cid)) {
  text += new TextDecoder().decode(chunk);
}

console.log(uploaded.manifest.chunks.length, text);

How Streaming Works

source chunks
-> MeshKit encrypts each chunk
-> provider stores encrypted chunks
-> MeshKit stores encrypted stream manifest
-> caller receives root CID and resume tokens
-> download reads manifest and yields decrypted chunks

putStream returns a MeshStreamFile with a manifest. getStream yields decrypted chunks as an async iterable.

API

await mesh.files.putStream(name, chunks, options);

for await (const chunk of mesh.files.getStream(cid, options)) {
  // write chunk to destination
}
OptionDefaultMeaning
chunkSize1048576Positive byte size for splitting source chunks
resumeTokenundefinedStrict token produced by the same upload or download workflow
onProgressundefinedReceives processed byte counts and the latest resume token
signalundefinedCancels upload or download with operation_aborted

Resume Tokens

Resume tokens are not portable between unrelated streams. Discard a token when any of these change:

  • Direction: upload versus download
  • File name
  • Root CID
  • Chunk size
  • Manifest
  • Provider boundary

Treat tokens as operational state. They are useful for retry UX, but they are not proof that a stream completed.

Failure Modes

Error or symptomMeaningAction
invalid_chunk_sizeChunk size is zero, negative, or unsupportedUse a positive chunk size
invalid_stream_resume_tokenToken does not match this stream workflowRestart or use the latest token from this operation
operation_abortedAbort signal firedPersist the latest resume token and retry intentionally
Download fails after manifest readA chunk is missing or fails CID verificationCheck provider retrieval and metadata consistency

Production Notes

  • Confirm the target runtime can provide real streams. Browser, Node, React Native, and Ionic differ.
  • Store the stream root CID and any app-level upload state outside MeshKit.
  • Use onProgress for UX and retry state, not as durable audit evidence.
  • Validate providers with realistic file sizes before shipping.

Next Steps

  • Store smaller payloads with Files.
  • Queue retryable work with Sync.
  • Choose runtime support in Runtimes.

On this page