npm.io
2026.7.5 • Published 1 week ago

@bytecask/core

Licence
AGPL-3.0-only
Version
2026.7.5
Deps
1
Size
150 kB
Vulns
0
Weekly
0
Stars
1

@bytecask/core

Browser-native, content-addressed blob storage.

Store binary data in IndexedDB, OPFS, or memory behind one typed API with BLAKE3 addressing, deduplication, lifecycle accounting, and recovery tools.

pnpm add @bytecask/core

npm downloads license TypeScript

Quick Start · Backends · API · Browser Support · Documentation


What It Is

@bytecask/core is the framework-neutral Bytecask storage engine. It accepts Blob, Uint8Array, or streamed bytes and returns a lowercase BLAKE3 content hash. Identical content is stored once, while lifecycle metadata determines whether the object is live, collectible, or missing.

It provides It deliberately leaves to the host
Content-addressed binary storage Records and relational data
IndexedDB, OPFS, and memory adapters User authorization and synchronization
Deduplication, references, GC, reconciliation Signing and publisher identity
Quota and integrity errors The only copy of irreplaceable data
Portable blobs/<hash> packing Product-specific attachment workflows

Highlights

  • BLAKE3 content identity: stable hashes support deduplication and portable manifests.
  • IndexedDB-first persistence: broad cross-browser storage without a database dependency.
  • Optional OPFS streaming: worker-backed large-file I/O is loaded only when selected.
  • Explicit lifecycle models: use refcounts or reconcile against a canonical host manifest.
  • Failure-aware writes: partial objects are removed after quota, metadata, integrity, or streaming failures.
  • ESM and TypeScript: typed public exports with no top-level browser-global access, so importing during SSR is safe.

Installation

Install the core package for IndexedDB, memory, and automatic backend selection:

pnpm add @bytecask/core

Add the worker package only when using OPFS:

pnpm add @bytecask/core @bytecask/worker

Quick Start

import { createBlobStore } from '@bytecask/core'

const store = await createBlobStore({ backend: 'idb' })
const hash = await store.put(new Blob(['hello, Bytecask']))

console.log(hash) // lowercase BLAKE3 hex

const blob = await store.getBlob(hash)
const bytes = await store.get(hash)

await store.close()

Automatic selection tries IndexedDB, then OPFS, then memory and exposes the result as store.backend. Force a persistent backend for archives that must never degrade to session memory.

Storage Backends

Backend Selection Persistence Best fit
IndexedDB Default persistent tier Browser-managed, evictable General files and attachments
OPFS Explicit or automatic fallback Browser-managed, evictable Streaming and large binary objects
Memory Explicit or final fallback Session only Tests, previews, and ephemeral data
const store = await createBlobStore({
  backend: 'idb',
  idb: { databaseName: 'archive-blobs' },
  metadata: { databaseName: 'archive-metadata' },
  verifyOnRead: true,
})

const persistenceGranted = await store.requestPersistence()
const report = await store.reconcile(liveAttachmentHashes)

A forced backend rejects when unavailable. It never silently changes the requested durability model.

Lifecycle Models

Choose one authority per store:

  1. Store-managed: put() creates a reference; balance ownership with ref() and unref(), then collect with gc().
  2. Host-managed: retain hashes in a canonical manifest and call reconcile(liveHashes) to repair metadata and identify missing or unreferenced bytes.

Do not maintain independent refcount systems for the same archive.

Main API

Export Purpose
createBlobStore(options) Select or force a storage backend
put, get, getBlob, has, delete Store and retrieve bytes by hash
ref, unref, gc Store-managed lifecycle accounting
reconcile(liveHashes) Repair state from a host-authoritative manifest
subscribe(listener) Observe local byte-store mutation outcomes
estimate, requestPersistence Observe browser storage and persistence
packBlobs, unpackBlobs Move portable blobs/<hash> entries
BytecaskError, QuotaError, IntegrityError Handle typed storage failures
const unsubscribe = store.subscribe((event) => {
  if (event.type === 'put') {
    console.log(event.hash, event.refcount)
  }
})

The change feed is store-level and local to the BlobStore instance. It emits Bytecask byte/lifecycle outcomes, not host record semantics or cross-tab sync messages.

Browser Support

  • IndexedDB behavior is tested in Chromium, Firefox, and Playwright WebKit.
  • OPFS worker behavior is tested in Chromium and Firefox.
  • Memory storage works in browser and JavaScript test environments.
  • The package is ESM-only and targets modern browsers.

Playwright WebKit is an engine proxy, not Apple's shipping Safari binary. Treat browser storage as a rebuildable local copy because persistence requests reduce eviction risk but cannot eliminate it.

Package Purpose
@bytecask/worker Optional OPFS worker and streaming I/O
@bytecask/react Optional React provider and hooks

Documentation

Security

Bytecask verifies content identity, not publisher identity. Verify signed containers or shards before hydrating untrusted bytes. Report vulnerabilities through the project's security policy, not a public issue.

License

AGPL-3.0-only. See LICENSE.

Keywords