Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

@loro-dev/unisqlite

Package Overview
Dependencies
Maintainers
2
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@loro-dev/unisqlite

Cross-platform concurrent SQLite access layer

npmnpm
Version
0.0.1
Version published
Weekly downloads
118
-31.79%
Maintainers
2
Weekly downloads
 
Created
Source

UniSQLite

Universal SQLite adapter for Node.js, Cloudflare Workers, and browsers.

Features

  • Cross-platform: Works in Node.js, Cloudflare Workers, and browsers
  • Type-safe: Full TypeScript support with strong typing
  • Transaction support: Both synchronous and asynchronous transactions
  • Connection type detection: Identify and enforce proper transaction usage
  • Leader election: Browser adapter uses leader election for multi-tab coordination
  • Cloudflare DO Support: Native adapter for Cloudflare Durable Objects' SQLite persistence API

Usage

Standard Usage

import { openStore } from "@loro-dev/unisqlite";

const store = await openStore({ path: "my-database.db" });

// Basic operations
await store.run("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)");
await store.run("INSERT INTO users (name) VALUES (?)", ["Alice"]);
const users = await store.query("SELECT * FROM users");

// Transactions
await store.transaction(async (txn) => {
  await txn.run("INSERT INTO users (name) VALUES (?)", ["Bob"]);
  await txn.run("INSERT INTO users (name) VALUES (?)", ["Charlie"]);
});

await store.close();

Cloudflare Durable Objects

For Cloudflare Durable Objects with the new SQLite persistence API:

import { CloudflareDOAdapter, createCloudflareDOAdapter } from "@loro-dev/unisqlite";

export class MyDurableObject extends DurableObject {
  private db: CloudflareDOAdapter;

  constructor(ctx: DurableObjectState, env: Env) {
    super(ctx, env);
    // Use the factory function for easy setup
    this.db = createCloudflareDOAdapter(ctx.storage.sql);
  }

  async fetch(request: Request) {
    // Use the adapter like any other UniSQLite connection
    await this.db.run("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)");
    await this.db.run("INSERT INTO users (name) VALUES (?)", ["Alice"]);
    const users = await this.db.query("SELECT * FROM users");

    return Response.json({ users });
  }
}

Connection Types

UniSQLite provides three types of connections with different transaction capabilities:

Direct Connection ("direct")

  • Primary database connections
  • Can execute both transaction() and asyncTransaction()
  • Entry point for all database operations
const store = await openStore({ path: "database.db" });
console.log(store.getConnectionType()); // "direct"

// Both transaction types are supported
await store.transaction(async (txn) => {
  /* sync transaction */
});
await store.asyncTransaction(async (txn) => {
  /* async transaction */
});

Sync Transaction Connection ("syncTxn")

  • Created within transaction() calls
  • Can call transaction() using itself (for nested operations)
  • Cannot call asyncTransaction() - will throw an error
await store.transaction(async (txn) => {
  console.log(txn.getConnectionType()); // "syncTxn"

  // ✅ Allowed: nested transaction using same connection
  await txn.transaction(async (nested) => {
    // nested === txn (same connection)
    await nested.run("INSERT INTO users (name) VALUES (?)", ["user"]);
  });

  // ❌ Not allowed: will throw error
  await txn.asyncTransaction(async (nested) => {
    // Error: "asyncTransaction is not supported in syncTxn connections"
  });
});

Async Transaction Connection ("asyncTxn")

  • Created within asyncTransaction() calls
  • Can call both transaction() and asyncTransaction() using itself
  • Supports timeout configuration and async operations
await store.asyncTransaction(
  async (txn) => {
    console.log(txn.getConnectionType()); // "asyncTxn"

    // ✅ Both transaction types are supported
    await txn.transaction(async (nested) => {
      // nested === txn (same connection)
    });

    await txn.asyncTransaction(async (nested) => {
      // nested === txn (same connection)
    });
  },
  { timeoutMs: 30000 }
);

Platform-specific entrypoints

The default unisqlite export stays minimal and uses dynamic imports so optional peers are only loaded when their platform adapter is actually needed. To make bundling and installations more intentional, use platform-specific entrypoints:

  • Node (requires peer better-sqlite3): import { openNodeStore, NodeAdapter } from "unisqlite/node";
  • Browser (needs broadcast-channel, and @sqlite.org/sqlite-wasm if you load SQLite from npm): import { openStore } from "unisqlite/browser";
  • Cloudflare Durable Objects: import { openCloudflareStore, CloudflareDOAdapter, createCloudflareDOAdapter } from "unisqlite/cloudflare";

These entrypoints avoid pulling in other platform adapters, keeping browser bundles slim and Node installs free from WASM/downloaded assets.

API Reference

Connection Type Detection

interface UniStoreConnection {
  getConnectionType(): "direct" | "syncTxn" | "asyncTxn";
  // ... other methods
}

Transaction Method Signatures

// Synchronous transaction - function cannot return Promise
transaction<T>(fn: (tx: UniStoreConnection) => T extends Promise<unknown> ? never : T): T extends Promise<unknown> ? never : T;

// Asynchronous transaction - function can return Promise
asyncTransaction<T>(fn: (tx: UniStoreConnection) => Promise<T>, options?: { timeoutMs?: number }): Promise<T>;

Transaction Enforcement Rules

Connection Typetransaction()asyncTransaction()
"direct"✅ Supported✅ Supported
"syncTxn"✅ Supported❌ Throws Error
"asyncTxn"✅ Supported✅ Supported

TypeScript Constraints

The transaction() method enforces synchronous functions at compile time:

// ✅ Valid - returns non-Promise value
const result = store.transaction((txn) => {
  return "sync-result";
});

// ❌ TypeScript Error - returns Promise
const invalid = store.transaction((txn) => {
  return Promise.resolve("async-result"); // Type error!
});

// ❌ TypeScript Error - async function
const invalid2 = store.transaction(async (txn) => {
  return "result"; // Type error!
});

This design ensures:

  • Type safety at the connection level
  • Prevention of async operations in sync-only contexts
  • Clear error messages for invalid usage patterns
  • Consistent behavior across all adapter implementations
  • Compile-time enforcement of synchronous transaction functions

Keywords

sqlite

FAQs

Package last updated on 01 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts