client.storage
This content is for the 0.2.0-alpha.3 version. Switch to the latest version for up-to-date documentation.
See the Storage guide for usage and patterns. The key/value
API is on client.storage; the file API is the standalone
FileStorage class.
Methods
Section titled “Methods”set(collection, id, value, opts?)
Section titled “set(collection, id, value, opts?)”set<T>(collection: string, id: string, value: T, opts?: { encrypt?: boolean }): Promise<void>Stores value under collection/id. Encrypted at rest by default; pass
{ encrypt: false } to store plaintext. Needs an unlocked identity for
encrypted writes.
get(collection, id)
Section titled “get(collection, id)”get<T>(collection: string, id: string): Promise<T | null>Returns the value (transparently decrypted) or null if absent.
delete(collection, id)
Section titled “delete(collection, id)”delete(collection: string, id: string): Promise<boolean>Removes the key; resolves to whether it existed.
list(collection)
Section titled “list(collection)”list(collection: string): Promise<string[]>Returns the ids in a collection (not values). There is no server-side query — filter client-side after fetching (see Querying).
on(event, handler)
Section titled “on(event, handler)”on(event: "change", handler: (e: StorageChangeEvent) => void): () => voidSubscribes to the realtime change feed for the signed-in user (across devices).
Returns an unsubscribe function. Requires a WebSocket global.
interface StorageChangeEvent<T = unknown> { collection: string; id: string; type: "set" | "delete"; data: T | null; // decrypted value on "set"; null on "delete"}query(...)
Section titled “query(...)”Reserved. Server-side query is intentionally unsupported (encrypted-at-rest);
calling it throws. Use list() + client-side filtering.
Errors
Section titled “Errors”| Message contains | Meaning |
|---|---|
not signed in | No active session — sign in first. |
identity | Encrypted op needs an unlocked identity — login() or unlock(). |
FileStorage
Section titled “FileStorage”Chunked, AES-256-GCM-encrypted, Reed–Solomon-erasure-coded file storage. See the Files guide for the model and the two usage modes. Available in the browser and server builds (not the edge/serverless build).
import { FileStorage, ShardClient, SharedSpaceClient } from "@muhkoo/connect";
const storage = new FileStorage(options);Constructor options
Section titled “Constructor options”| Option | Type | Default | Description |
|---|---|---|---|
shards | ShardClient | — (required) | Content-addressed shard store transport. |
space | SharedSpaceClient | — | Gated manifest + ACL store. Required only for writeFile / readFile / deleteFile / listFiles / readManifest. |
chunkSize | number | 4 MiB | Plaintext bytes per chunk. |
dataShards | number | 4 | RS data shards per chunk. |
parityShards | number | 2 | RS parity shards per chunk. |
concurrency | number | 8 | Cap on concurrent shard uploads/downloads. |
rsWasmModule | WebAssembly.Module | bundled | Pre-compiled Reed–Solomon WASM (for runtimes where the bundled loader path isn’t available). |
Methods
Section titled “Methods”writeFileToShards(input)
Section titled “writeFileToShards(input)”writeFileToShards(input: WriteToShardsInput): Promise<{ manifest: FileManifest; stat: FileStat }>Chunk, encrypt, encode, and upload the shards. Returns the manifest — the
caller is responsible for delivering it to readers. Does not need a space.
interface WriteToShardsInput { data: Uint8Array | Blob | File; metadata: { name: string; type: string; path?: string; lastModified?: number }; fileId?: string; // pre-allocate an id (resumable uploads); defaults to a fresh one}readFileFromShards(manifest)
Section titled “readFileFromShards(manifest)”readFileFromShards(manifest: FileManifest): Promise<{ data: Uint8Array; stat: FileStat }>Fetch shards, decode, decrypt, and concatenate back to the original bytes.
writeFile(input)
Section titled “writeFile(input)”writeFile(input: WriteToShardsInput & { spaceId: string }): Promise<FileStat>Like writeFileToShards, then POST the manifest to the gated space. Requires
a SharedSpaceClient; the caller must have write on the space.
readFile(spaceId, fileId)
Section titled “readFile(spaceId, fileId)”readFile(spaceId: string, fileId: string): Promise<{ data: Uint8Array; stat: FileStat }>Fetch the manifest from the space, then reassemble the file.
listFiles(spaceId) · deleteFile(spaceId, fileId) · readManifest(spaceId, fileId)
Section titled “listFiles(spaceId) · deleteFile(spaceId, fileId) · readManifest(spaceId, fileId)”listFiles(spaceId: string): Promise<FileStat[]>deleteFile(spaceId: string, fileId: string): Promise<boolean>readManifest(spaceId: string, fileId: string): Promise<FileManifest>Directory listing, delete (resolves to whether it existed), and fetching a manifest without downloading the file.
interface FileStat { id: string; name: string; size: number; // total plaintext bytes type: string; // MIME type the app supplied path?: string; lastModified: number; createdAt: number; chunkCount: number; shardCount: number;}
interface FileManifest { id: string; name: string; size: number; type: string; path?: string; lastModified: number; createdAt: number; chunks: ChunkManifest[]; // per-chunk keys, IVs, RS params, shard hashes version: 1;}ShardClient
Section titled “ShardClient”Transport for the open, content-addressed shard store
(PUT/GET/HEAD /api/shards/:hash).
new ShardClient(options: { baseUrl: string; // accelerator base URL pathPrefix?: string; // default "/api/shards"; e.g. "/api/spaces/{id}/shards" to scope to a space fetch?: typeof fetch;});shardHash(bytes: Uint8Array): Promise<string> // lowercase hex SHA-256, the shard's addressSharedSpaceClient
Section titled “SharedSpaceClient”ZK-gated transport for the multi-user manifest + ACL store. Every call fetches a
challenge nonce, generates a Groth16 proof for the preimagePoK circuit, and
sends it with the operation. Constructed with the caller’s ZK identity material
(commitment, secret, salt, ecdsaPub, ecdsaPubHash) plus baseUrl and
circuits. Depends on snarkjs (browser/server builds only).