CrSql overview
CR-SQLite service for conflict-free replicated database operations.
This module provides a high-level Effect service interface for working with CR-SQLite (Conflict-free Replicated SQLite) databases. CR-SQLite enables multi-master replication with automatic conflict resolution, allowing seamless data synchronization across distributed systems without manual conflict handling.
Core Capabilities:
- Site Management: Getting unique site identifiers and database versions
- Change Synchronization: Pulling and applying change sets between replicas
- Peer Tracking: Managing replication cursors for distributed peers
- Schema Migration: Automated schema evolution with crsql_automigrate
- Fractional Indexing: Ordered list support for collaborative editing
Multi-Master Replication: All operations support CR-SQLite’s CRDT (Conflict-free Replicated Data Type) semantics, enabling partition-tolerant systems where multiple replicas can accept writes independently and later converge to a consistent state.
All operations are Effect-based for composable error handling, dependency injection, and integration with the broader Effect ecosystem.
Security Note: This module uses Effect SQL’s tagged template literals, which automatically handle parameterization and SQL injection protection. The ${variable} syntax is safe - Effect SQL converts these to proper parameterized queries under the hood.
Added in v0.1.0
Table of contents
Construction
fromSqliteClient
Creates a CrSql service from an existing SqlClient setup.
Accepts optional parameters (each value or Effect) for providing the CR-SQLite extension path, precomputed extension metadata, or an alternative SqlClient. Missing dependencies are resolved from the ambient environment when available.
Signature
export declare const fromSqliteClient: _fromSqliteClient
Added in v0.1.0
Layer
layerFromSqliteClient
Builds a Layer that wires CR-SQLite services from an existing SqlClient.
The parameters can be provided eagerly or as Effects, allowing callers to defer expensive initialization until layer evaluation.
Signature
export declare const layerFromSqliteClient: <E = never, R = never>(
_: MaybeEffect<FromSqliteClientParams<E, R>, E, R>
) => Layer.Layer<
SqlClient.SqlClient | CrSql | CrSqliteExtension.ExtInfoLoaded,
CrSqlErrors.CrSqliteExtensionMissing | E | CrSqlErrors.UnhexUnavailable,
Scope | R
>
Added in v0.2.0
utils
CrSql (class)
CR-SQLite service accessor class for conflict-free replicated database operations.
This Effect service provides a complete interface for working with CR-SQLite (Conflict-free Replicated SQLite) databases. CR-SQLite enables multi-master replication with automatic conflict resolution using CRDT semantics.
Service Usage: Use CrSql.CrSql accessors in Effect programs to interact with CR-SQLite-backed databases. The service automatically handles extension loading, connection management, and resource cleanup.
Core Features:
- Automatic setup: Extension loading and connection verification
- Type safety: Full TypeScript integration with Effect schemas
- Resource management: Automatic cleanup via Effect finalizers
- Multi-replica sync: Built-in peer tracking and change synchronization
- Schema evolution: Declarative migrations with
automigrate - Collaborative editing: Fractional indexing for ordered data
Signature
export declare class CrSql
Example
Basic usage:
```typescript
import { CrSql } from "@effect-native/crsql"
import * as NodeSqlite from "@effect/sql-sqlite-node"
import { Effect, Layer } from "effect"
const program = Effect.gen(function* () {
// Get site identifier
const siteId = yield* CrSql.CrSql.getSiteIdHex
// Set up a replicated table
yield* CrSql.CrSql.automigrate`
CREATE TABLE IF NOT EXISTS todos (
id BLOB PRIMARY KEY,
text TEXT NOT NULL DEFAULT '',
completed INTEGER NOT NULL DEFAULT 0
);
SELECT crsql_as_crr('todos');
`
// Make changes that will be replicated
const sql = yield* CrSql.CrSql.sql
yield* sql`INSERT INTO todos VALUES (randomblob(16), 'Hello World', 0)`
// Export changes for synchronization
const changes = yield* CrSql.CrSql.pullChanges("0")
console.log(`Generated ${changes.length} changes`)
})
// Run with SQLite layer
const layers = Layer.mergeAll(
NodeSqlite.SqliteClient.layer({ filename: "app.db" }),
CrSql.CrSql.Default
)
Effect.provide(program, layers)
Example
Service creation from existing client:
```typescript
import * as CrSql from "@effect-native/crsql/CrSql"
import * as NodeSqlite from "@effect/sql-sqlite-node"
import * as LibCrSql from "@effect-native/libcrsql/effect"
import { Effect } from "effect"
const program = Effect.gen(function* () {
// Create CrSql service from existing client
const crsql = yield* CrSql.fromSqliteClient({
pathToCrSqliteExtension: yield* LibCrSql.getCrSqliteExtensionPath(),
sql: yield* NodeSqlite.SqliteClient.make({ filename: ":memory:" }),
})
// Use the service
const version = yield* crsql.getDbVersion
})
Added in v0.1.0