Skip to content

Latest commit

 

History

History
149 lines (106 loc) · 6.39 KB

File metadata and controls

149 lines (106 loc) · 6.39 KB
db

TanStack DB binding: typed, live-synced collections and a durable offline outbox over the Lunora client


typescript-image FSL-1.1-Apache-2.0 licence npm version npm downloads PRs Welcome


Daniel Bannert's open source work is supported by the community on GitHub Sponsors


A TanStack DB binding for the Lunora client. defineCollections wires your Lunora queries and mutations into live, indexed client collections (reads) and a durable, retried offline-transactions outbox (writes) — so a write renders instantly, survives reloads and offline windows, is superseded by the real server row on acknowledgement, and rolls back if the server rejects it. Peer-depends on @tanstack/db and @tanstack/offline-transactions.

Part of the Lunora framework — a type-safe, real-time backend on Cloudflare Workers + Durable Objects with a Vite-first DX.

Install

npm install @lunora/db
yarn add @lunora/db
pnpm add @lunora/db

Usage

import { defineCollections } from "@lunora/db";
import type { LunoraClient } from "@lunora/react";

import { api } from "./_generated/api";
import type { Doc, Id } from "./_generated/dataModel";

export const createCollections = (client: LunoraClient) =>
    defineCollections(client, {
        messages: {
            list: api.messages.list,
            scopeBy: "channelId", // sharded — re-point with db.scope.messages({ channelId })
            insert: {
                mutation: api.messages.send,
                optimistic: (input: Omit<Doc<"messages">, "_id" | "_creationTime">, id) => ({
                    _id: id as Id<"messages">,
                    _creationTime: Date.now(),
                    ...input,
                }),
                toArgs: (row) => ({ channelId: row.channelId, id: row._id, text: row.text }),
            },
        },
        users: { list: api.users.list }, // read-only
    });

// → db.collections.* (feed useLiveQuery), db.actions.* (optimistic writes),
//   db.scope.* (re-point sharded collections), db.executor (the outbox)

vis generate lunora-collections scaffolds this from your schema.ts + functions.

Keep a single db instance, and treat its collections as the one source of truth per table — don't mirror rows into your own store. A derived index (a tree, a search index, an undo capture) built from a copy of the rows can silently read stale data while the UI renders through useLiveQuery. See One source of truth per table.

Local-first sync engine

Beyond whole-table collections, the @lunora/db/collections and @lunora/db/mutators subpaths expose the local-first sync engine: lunoraCollectionOptions({ shape }) syncs a partial replication shape (only the rows a client needs, scoped by a server-resolved predicate) over the poke diff protocol, and defineMutator + bindMutators run optimistic custom mutators (a local body first, a server-authoritative impl second, rebased on every sync tick). The framework adapters add a useMutator / createMutator / mutator hook over a bound handle. See the local-first guide.

This README covers the basics. For the full API, options, and guides, see the documentation.

Related

  • @lunora/client — the browser SDK this layer syncs over.
  • @lunora/react — React hooks for Lunora queries and mutations.
  • @lunora/server — server primitives that define the queries and mutations you bind.

Supported Node.js Versions

Libraries in this ecosystem make the best effort to track Node.js' release schedule. Here's a post on why we think this is important.

Contributing

If you would like to help take a look at the list of issues and check our Contributing guidelines.

Note: please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

Credits

Made with ❤️ at Anolilab

This is an open source project and will always remain free to use. If you think it's cool, please star it 🌟. Anolilab is a Development and AI Studio. Contact us at hello@anolilab.com if you need any help with these technologies or just want to say hi!

License

The Lunora db package is open-sourced software licensed under the FSL-1.1-Apache-2.0.