insieme
v2.1.2
Published
An offline-first collaborative library with authoritative server for real-time data synchronization
Maintainers
Readme
Insieme
Insieme is an offline-first sync library built around an authoritative server. Clients create local drafts, submit them when transport is available, and converge on a server-ordered committed event stream.
TypeScript declaration files are bundled with the package, and the published entry points are split by environment so browser-safe imports stay distinct from Node-only adapters.
Install
bun add insiemeEntry Points
Use the package entry point that matches your runtime.
| Import path | Use for | Includes |
| --- | --- | --- |
| insieme | Portable client surface. Alias of insieme/client. | createSyncClient, client transports, client stores, createReducer |
| insieme/client | Explicit client-only imports. | Same surface as insieme |
| insieme/browser | Browser-explicit imports. | Same surface as insieme/client |
| insieme/node | Node-only client + server work. | Everything in insieme/client, plus createSyncServer, WS server helpers, and Node persistence adapters |
| insieme/server | Backward-compatible server alias. | Same surface as insieme/node |
Quick rule:
- Browser app: import from
insiemeorinsieme/client. - Node client using SQLite: import from
insieme/node. - Sync server: import from
insieme/nodeorinsieme/server.
Client Quick Start
import {
createOfflineTransport,
createInMemoryClientStore,
createSyncClient,
} from "insieme/client";
const clientStore = createInMemoryClientStore();
const transport = createOfflineTransport();
const client = createSyncClient({
transport,
store: clientStore,
token: "jwt",
clientId: "C1",
projectId: "workspace-1",
});
await client.start();
await client.submitEvent({
partition: "workspace-1",
type: "counter.increment",
schemaVersion: 1,
payload: { amount: 1 },
});Attach a real transport later without replacing the client instance:
await transport.setOnlineTransport(realWebSocketTransport);Server Quick Start
import { createInMemorySyncStore, createSyncServer } from "insieme/node";
const serverStore = createInMemorySyncStore();
const server = createSyncServer({
auth: {
verifyToken: async () => ({ clientId: "C1", claims: {} }),
},
authz: {
authorizeProject: async () => true,
},
validation: {
validate: async () => {},
},
store: serverStore,
clock: { now: () => Date.now() },
});Persistence Adapters
Client-side stores:
createInMemoryClientStore()frominsieme/clientfor tests and dev.createIndexedDbClientStore()frominsieme/clientfor browser persistence.createLibsqlClientStore(client)frominsieme/clientfor@libsql/client.createAsyncSqliteClientStore({ driver })frominsieme/clientfor injected async SQLite runtimes such as Tauri-backed adapters.createSqliteClientStore(db)frominsieme/nodeforbetter-sqlite3style SQLite APIs.
Server-side sync stores:
createInMemorySyncStore()frominsieme/node.createLibsqlSyncStore(client)frominsieme/node.createSqliteSyncStore(db)frominsieme/node.
LibSQL example:
import { createClient } from "@libsql/client";
import { createLibsqlClientStore } from "insieme/client";
import { createLibsqlSyncStore } from "insieme/node";
const clientDb = createClient({ url: "file:./insieme-client.db" });
const serverDb = createClient({ url: "file:./insieme-server.db" });
const clientStore = createLibsqlClientStore(clientDb);
const syncStore = createLibsqlSyncStore(serverDb);createCommandSyncSession accepts submitBatch: { maxEvents, maxBytes } and
forwards it to createSyncClient. Configure this when a validated project
bootstrap exceeds the default 64 KiB batch ceiling. The default remains unchanged;
client and server transport limits must agree.
Event schema versions
SQLite, async SQLite, libSQL, and IndexedDB client stores expose one
schemaVersion: a positive safe integer number. Stored integer representations
such as 2, "2", and 2n all read as schemaVersion: 2, including during
materialized-view replay. Decimal strings must use the canonical integer spelling;
whitespace, leading zeros, fractions, and exponent notation are rejected.
insertDraft, insertDrafts, and applyCommittedBatch require numeric positive
safe integers. Invalid batches fail with invalid_schema_version before writing
rows, deleting drafts, or advancing the cursor. Applications decide which valid
versions they support; for example, version 999 is structurally valid.
This tightens historical reads: malformed stored versions such as "2junk" or
2.9 now throw invalid_schema_version when read or promoted to committed events,
instead of silently becoming 2. Malformed rows must be repaired or migrated
before they can be read or replayed. Valid existing rows need no migration.
Materialized Views
Built-in client stores support optional partition-scoped materialized views.
import { createLibsqlClientStore, createReducer } from "insieme/client";
const reducer = createReducer({
schemaHandlers: {
"counter.increment": ({ state, payload }) => {
state.count = (state.count ?? 0) + payload.amount;
},
},
});
const store = createLibsqlClientStore(db, {
materializedViews: [
{
name: "event-count",
version: "1",
initialState: () => ({ count: 0 }),
reduce: reducer,
},
],
});
const view = await store.loadMaterializedView({
viewName: "event-count",
partition: "workspace-1",
});Materialized views update only when a committed event is newly inserted. Duplicate committed deliveries are ignored by the built-in stores.
Subscribe to a hot materialized view partition:
const unsubscribe = await store.subscribeMaterializedView({
viewName: "event-count",
partition: "workspace-1",
onChange: ({ value, lastCommittedId }) => {
console.log(value, lastCommittedId);
},
});Public API Highlights
createSyncClient: project-scoped client runtime (start,submitEvent,syncNow,flushDrafts,stop,close).createSyncServer: authoritative server runtime (attachConnection,shutdown).createOfflineTransport: local-first transport that buffers submits until an online transport is attached.createBrowserWebSocketTransport: browserWebSockettransport adapter.- Built-in client stores: stable inspection (
listDraftsOrdered,listCommitted,listCommittedAfter,getCursor), view subscriptions (subscribeMaterializedView), and explicitclose(). attachWsConnection/createWsServerRuntime: Node WebSocket bridge helpers for the server runtime.createReducer: event-type dispatcher for replay and materialized-view reducers.
Docs
- Docs index
- Package entry points
- JavaScript interface reference
- Client storage model
- Materialized views
- Protocol messages
- Production checklist
Examples
Production-style examples live in examples/real-client-usage.
Ops Helper
Run SQLite integrity checks:
bun run ops:sqlite:integrity -- /path/to/client.db /path/to/server.db