IPC (multi-process)
LioranManager supports multiple process modes so you can safely use one database root from multiple Node processes.
Modes
primary: owns the lock and performs database work locallyclient: forwards DB operations to the primary via an IPC queuereadonly: opens databases in read-only mode (no WAL, no writes)
Auto-detect behavior (default)
If you do not pass ipc, the manager tries to acquire a lock file:
- if it succeeds -> acts as
primary - if it fails -> acts as
client
The lock is stored at:
<rootPath>/.lioran.lock
Recommended usage
- One primary process per root path.
- Any additional processes should use
ipc: "client"(or rely on auto-detect). - Use
ipc: "readonly"for safe read replicas that never write (no WAL, no writes). - Use
ipc: "replica"when you run a replication topology and want a non-writer process mode that can still participate in replication flows (advanced).
Example: log which mode you are in
- TypeScript
- JavaScript
import { LioranManager } from "@liorandb/core";
const manager = new LioranManager({ rootPath: "./.liorandb" });
console.log({
primary: manager.isPrimary(),
client: manager.isClient(),
readonly: manager.isReadOnly(),
});
await manager.close();
Sandbox output (example)
{ primary: true, client: false, readonly: false }
import { LioranManager } from "@liorandb/core";
const manager = new LioranManager({ rootPath: "./.liorandb" });
console.log({
primary: manager.isPrimary(),
client: manager.isClient(),
readonly: manager.isReadOnly(),
});
await manager.close();
Sandbox output (example)
{ primary: true, client: false, readonly: false }
Example: two-process setup (primary + client)
primary (writer / lock owner)
- TypeScript
- JavaScript
import { LioranManager } from "@liorandb/core";
const manager = new LioranManager({ rootPath: "./.liorandb", ipc: "primary" });
const db = await manager.db("app");
await db.collection("events").insertOne({ name: "primary-ready" });
console.log("primary ready");
import { LioranManager } from "@liorandb/core";
const manager = new LioranManager({ rootPath: "./.liorandb", ipc: "primary" });
const db = await manager.db("app");
await db.collection("events").insertOne({ name: "primary-ready" });
console.log("primary ready");
client (forwards operations)
- TypeScript
- JavaScript
import { LioranManager } from "@liorandb/core";
const manager = new LioranManager({ rootPath: "./.liorandb", ipc: "client" });
const db = await manager.db("app");
await db.collection("events").insertOne({ name: "client-write" });
console.log("client wrote");
await manager.close();
import { LioranManager } from "@liorandb/core";
const manager = new LioranManager({ rootPath: "./.liorandb", ipc: "client" });
const db = await manager.db("app");
await db.collection("events").insertOne({ name: "client-write" });
console.log("client wrote");
await manager.close();
Sandbox output (example)
primary ready
client wrote