Who is this for? If you're testing, debugging, or simulating distributed systems with Lix and need predictable, reproducible behavior across runs, deterministic mode is for you.
Use deterministic mode for:
Normal mode (default) - different results each run:
import { openLix, getTimestamp, random } from "@lix-js/sdk";
const lix = await openLix({ blob });
getTimestamp({ lix }); // "2024-03-15T10:32:45.123Z" (current time)
getTimestamp({ lix }); // "2024-03-15T10:32:45.124Z" (real time passes)
random({ lix }); // 0.7234... (unpredictable)
random({ lix }); // 0.1823... (unpredictable)Deterministic mode - same results every run:
const lix = await openLix({
blob,
keyValues: [
{
key: "lix_deterministic_mode",
value: {
enabled: true,
},
lixcol_version_id: "global",
},
],
});
getTimestamp({ lix }); // "1970-01-01T00:00:00.000Z" (always epoch)
getTimestamp({ lix }); // "1970-01-01T00:00:00.001Z" (always +1ms)
random({ lix }); // 0.318... (always this sequence)
random({ lix }); // 0.937... (always this sequence)Enable deterministic mode when opening a Lix:
const lix = await openLix({
blob,
keyValues: [
{
key: "lix_deterministic_mode",
value: {
enabled: true,
},
lixcol_version_id: "global",
},
],
});Or enable it after opening:
await lix.db
.updateTable("key_value_all")
.set({ value: { enabled: true } })
.where("key", "=", "lix_deterministic_mode")
.where("lixcol_version_id", "=", "global")
.execute();The deterministic mode is configured through a single key-value object:
| Key | Type | Description |
|---|---|---|
lix_deterministic_mode | object | Configuration object for deterministic mode |
The configuration object has the following properties:
| Property | Type | Default | Description |
|---|---|---|---|
enabled | boolean | required | Enable/disable deterministic mode |
randomLixId | boolean | false | Use random lix_id for distributed testing |
timestamp | boolean | true | Use deterministic timestamps |
random_seed | string | "lix-deterministic-seed" | Seed for the random number generator |
nano_id | boolean | true | Use deterministic nano ID generation |
uuid_v7 | boolean | true | Use deterministic UUID v7 generation |
For distributed testing scenarios where you need multiple Lix instances with different IDs:
// Creates Lix instances with random IDs for distributed testing
const lix1 = await openLix({
keyValues: [
{
key: "lix_deterministic_mode",
value: {
enabled: true,
randomLixId: true, // Each instance gets a random lix_id
},
lixcol_version_id: "global",
},
],
});
const lix2 = await openLix({
keyValues: [
{
key: "lix_deterministic_mode",
value: {
enabled: true,
randomLixId: true, // Different from lix1
},
lixcol_version_id: "global",
},
],
});enabled: true) for reproducibility testing (e.g., unit tests, regression tests)enabled: true, randomLixId: true) for distributed testing scenarios (e.g., simulating multiple Lix instances syncing)To make multiple Lix instances behave differently in deterministic mode:
// Set seed when opening
const lix1 = await openLix({
blob,
keyValues: [
{
key: "lix_deterministic_mode",
value: {
enabled: true,
random_seed: "instance-1",
},
lixcol_version_id: "global",
},
],
});
// Or update seed after opening using SQLite's json_set function
import { sql } from "@lix-js/sdk";
await lix.db
.updateTable("key_value_all")
.set({
value: sql`json_set(value, '$.random_seed', 'instance-2')`,
})
.where("key", "=", "lix_deterministic_mode")
.where("lixcol_version_id", "=", "global")
.execute();Deterministic state is automatically persisted:
| Event | State Flushed? |
|---|---|
| Successful mutating transaction | ✅ |
lix.toBlob() / lix.close() | ✅ |
| Read-only transaction | ❌ |
| Transaction rollback/error | ❌ |
The following functions provide deterministic behavior when lix_deterministic_mode is enabled:
| Function | Purpose | Docs |
|---|---|---|
getTimestamp({ lix }) | Logical clock timestamps | API docs |
random({ lix }) | Reproducible random numbers | API docs |
uuidV7({ lix }) | Deterministic UUID v7 generation | API docs |
nanoId({ lix }) | Deterministic nano ID generation | API docs |
nextSequenceNumber({ lix }) | Monotonic counter (advanced) | API docs |