db

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


[![typescript-image][typescript-badge]][typescript-url] [![FSL-1.1-Apache-2.0 licence][license-badge]][license] [![npm version][npm-version-badge]][npm-version] [![npm downloads][npm-downloads-badge]][npm-downloads] [![PRs Welcome][prs-welcome-badge]][prs-welcome]
---

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

--- A [TanStack DB](https://tanstack.com/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](https://github.com/anolilab/lunora) framework — a type-safe, real-time backend on Cloudflare Workers + Durable Objects with a Vite-first DX. ## Install ```sh npm install @lunora/db ``` ```sh yarn add @lunora/db ``` ```sh pnpm add @lunora/db ``` ## Usage ```ts 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, "_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. ### 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](https://lunora.sh/docs/concepts/local-first)**. > This README covers the basics. For the full API, options, and guides, see the **[documentation](https://lunora.sh/docs/addons/db)**. ## Related - [`@lunora/client`](https://www.npmjs.com/package/@lunora/client) — the browser SDK this layer syncs over. - [`@lunora/react`](https://www.npmjs.com/package/@lunora/react) — React hooks for Lunora queries and mutations. - [`@lunora/server`](https://www.npmjs.com/package/@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](https://github.com/nodejs/release#release-schedule). Here's [a post on why we think this is important](https://medium.com/the-node-js-collection/maintainers-should-consider-following-node-js-release-schedule-ab08ed4de71a). ## Contributing If you would like to help take a look at the [list of issues](https://github.com/anolilab/lunora/issues) and check our [Contributing](https://github.com/anolilab/lunora/blob/alpha/.github/CONTRIBUTING.md) 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 - [Daniel Bannert](https://github.com/prisis) - [All Contributors](https://github.com/anolilab/lunora/graphs/contributors) ## 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](https://www.anolilab.com/open-source) is a Development and AI Studio. Contact us at [hello@anolilab.com](mailto: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][license]. [license-badge]: https://img.shields.io/badge/license-FSL--1.1--Apache--2.0-blue.svg?style=for-the-badge [license]: https://github.com/anolilab/lunora/blob/alpha/LICENSE.md [npm-version-badge]: https://img.shields.io/npm/v/@lunora/db?style=for-the-badge [npm-version]: https://www.npmjs.com/package/@lunora/db [npm-downloads-badge]: https://img.shields.io/npm/dm/@lunora/db?style=for-the-badge [npm-downloads]: https://www.npmjs.com/package/@lunora/db [prs-welcome-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=for-the-badge [prs-welcome]: https://github.com/anolilab/lunora/blob/alpha/.github/CONTRIBUTING.md [typescript-badge]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript [typescript-url]: https://www.typescriptlang.org/