
Product
Introducing Webhook Events for Alert Changes
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.
@decaf-ts/for-nano
Advanced tools
A lightweight adapter layer and utilities to use CouchDB via the Nano client within the decaf-ts ecosystem. It provides a NanoAdapter with repository-friendly CRUD, bulk operations, indexing, user/database management helpers, and a change feed dispatcher, plus typed flags and configuration for ergonomic, testable data access.
Documentation available here
This package integrates CouchDB via the Nano client into the decaf-ts data stack. It exposes a focused set of primitives that make CouchDB usage consistent with other decaf-ts backends (TypeORM, HTTP, Pouch, etc.), while retaining Nano’s flexibility.
Core elements and their intents:
NanoAdapter
NanoDispatch
NanoRepository
Types and constants
Design considerations:
This guide shows practical, non-duplicated examples for all public APIs in @decaf-ts/for-nano using the repository pattern. The adapter class is not meant to be accessed directly; instead, always obtain a repository with Repository.forModel(Model).
Prerequisites:
Description: Declare a model with table/primary-key decorators and get a Nano-powered repository for it. The flavour is auto-wired by importing @decaf-ts/for-nano.
import {
BaseModel,
Repository,
pk,
uses,
} from "@decaf-ts/core";
import { model, Model, ModelArg, required } from "@decaf-ts/decorator-validation";
import type { NanoRepository } from "@decaf-ts/for-nano";
@uses("nano")
@model()
class UserModel extends BaseModel implements Model {
@pk({ type: "String" })
id!: string; // primary key
@required()
name!: string;
constructor(arg?: ModelArg<UserModel>) {
super(arg);
}
}
const repo: NanoRepository<UserModel> = Repository.forModel<UserModel, NanoRepository<UserModel>>(UserModel);
Description: Pass NanoFlags in repository calls; the user info is propagated to operations by the adapter under the hood.
import type { NanoFlags } from "@decaf-ts/for-nano";
const flags: NanoFlags = {
user: { name: "tester", roles: ["writer"] },
};
Description: Insert a document and read it back. CouchDB revisions are stored in PersistenceKeys.METADATA transparently.
import { PersistenceKeys } from "@decaf-ts/core";
const created = await repo.create(new UserModel({ id: "user:1", name: "Ada" }));
// created[PersistenceKeys.METADATA] contains the new revision string, e.g., "1-a"
const loaded = await repo.read("user:1");
console.log(loaded.name);
Description: Insert multiple documents and then fetch them by IDs. Bulk operations aggregate errors.
const users = [
new UserModel({ id: "user:2", name: "Lin" }),
new UserModel({ id: "user:3", name: "Grace" }),
];
const createdMany = await repo.createAll(users);
const fetchedMany = await repo.readAll(["user:2", "user:3"]);
Description: Update requires the previous revision in metadata. The new revision is written back into metadata.
let u = await repo.read("user:1");
// ... mutate
u.name = "Ada Lovelace";
// u already has PersistenceKeys.METADATA from read()
u = await repo.update(u);
// Bulk update requires each model to carry its matching metadata
const u2 = await repo.read("user:2");
const u3 = await repo.read("user:3");
const updatedMany = await repo.updateAll([u2, u3]);
Description: Delete a single document, or delete in bulk by IDs.
const deleted = await repo.delete("user:3");
const deletedMany = await repo.deleteAll(["user:1", "user:2"]);
Description: Use the Repository query API to filter and project results.
import { Condition, OrderDirection } from "@decaf-ts/core";
// Select all as full UserModel objects
const all = await repo.select().execute();
// Select only specific attributes
const projected = await repo.select(["name"]).execute();
// Conditional queries
const nameEq = Condition.attribute<UserModel>("name").eq("Ada Lovelace");
const named = await repo.select().where(nameEq).execute();
// Ordering (requires proper indexes configured for CouchDB)
const ordered = await repo.select().orderBy(["name", OrderDirection.ASC]).execute();
Description: Subscribe to CREATE/UPDATE/DELETE events using the Observer interface. The repository wires Nano’s change feed internally.
import type { Observer } from "@decaf-ts/core";
import { OperationKeys } from "@decaf-ts/db-decorators";
const observer: Observer = {
async refresh(table: string, operation: OperationKeys | string, ids: string[]) {
if (operation.toString() === OperationKeys.DELETE.toString()) {
console.log(`Deleted from ${table}:`, ids);
}
},
};
await repo.observe(observer);
// ... later
await repo.unObserve(observer);
Description: Use NanoFlavour as an identifier in multi-backend setups.
import { NanoFlavour } from "@decaf-ts/for-nano";
console.log(NanoFlavour); // "nano"
Description: Bind your model type to a repository powered by the Nano backend.
import type { NanoRepository } from "@decaf-ts/for-nano";
import type { Model } from "@decaf-ts/decorator-validation";
class MyModel implements Model {
_id!: string;
}
let myRepo!: NanoRepository<MyModel>;
Description: Read the module’s version string if you need it for diagnostics.
import { VERSION } from "@decaf-ts/for-nano";
console.log("for-nano version:", VERSION);
Advanced (optional): Administration helpers
Description: If you must manage CouchDB resources, @decaf-ts/for-nano exports static helpers on NanoAdapter (no direct instantiation required). These are not part of the Repository API.
import { NanoAdapter } from "@decaf-ts/for-nano";
// Build a Nano (CouchDB) connection
const url = NanoAdapter.connect("admin", "secret", "localhost:5984", "http");
// Ensure a database exists / manage users
await NanoAdapter.createDatabase(url, "mydb");
// ... createUser/deleteUser, deleteDatabase, etc.
If you have bug reports, questions or suggestions please create a new issue.
I am grateful for any contributions made to this project. Please read this to get started.
The first and easiest way you can support it is by Contributing. Even just finding a typo in the documentation is important.
Financial support is always welcome and helps keep both me and the project alive and healthy.
So if you can, if this project in any way. either by learning something or simply by helping you save precious time, please consider donating.
This project is released under the Mozilla Public License 2.0.
By developers, for developers...
FAQs
decaf-ts persistence adapter for CouchDB via nano
We found that @decaf-ts/for-nano demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?

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.

Product
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.

Security News
ENISA has become a CVE Program Root, giving the EU a central authority for coordinating vulnerability reporting, disclosure, and cross-border response.

Product
Socket now scans OpenVSX extensions, giving teams early detection of risky behaviors, hidden capabilities, and supply chain threats in developer tools.