new SencilloDB(config)- Database methods
- Transaction methods
- The instructions object
quickTxcreateResourceManager- Errors
- Events
Every field is optional.
| Option | Type | Default | Meaning |
|---|---|---|---|
file |
string | "./sencillo.json" |
Single file mode. Parent folders are created if needed. |
folder |
string | — | Folder mode: one file per collection, loaded on demand. |
sharding |
boolean | false |
Folder mode only: one file per index bucket. |
compression |
boolean | false |
gzip the persisted files. |
aof |
boolean | false |
Append writes to a log instead of rewriting the store. |
appendfsync |
"always" | "everysec" | "no" |
"everysec" |
How aggressively the log is flushed to disk. |
maxCacheSize |
number | 0 |
Collections/shards kept in memory. 0 means no limit. |
clone |
boolean | true |
Return deep copies instead of live references. |
lock |
boolean | { staleMs, timeoutMs, retryMs } |
false |
Advisory cross process lock file. |
loadHook |
() => Promise<string> |
— | Single file mode: load the store from somewhere else. |
saveHook |
(json: string) => Promise<void> |
— | Single file mode: save the store somewhere else. |
debug |
boolean | false |
Also print internal warnings to stderr. |
Rejected combinations throw a ValidationError: sharding without folder, file together with folder, and hooks together with folder.
Runs callback(tx) and commits when it returns. Resolves to the callback's return value. If the callback throws, every change is discarded and the error is re-thrown.
Folds the append only log back into the store and deletes the log. Also purges expired documents. Safe to call in any mode.
Writes anything still pending and drops the in-memory cache. The instance stays usable — the next transaction reloads from disk.
Loads every collection (and every shard) and resolves to a plain object copy of the whole store.
Replaces the store with data. With { merge: true }, existing collections are kept and merged rather than removed. The result is written straight through and the log is reset.
Writes export() to path. Gzipped when the path ends in .gz.
Runs any migration whose version has not been recorded yet, in ascending version order, each inside its own transaction. Applied versions are stored in the __migrations collection. Resolves to the list of versions applied by this call.
await db.migrate([
{ version: 1, name: "seed", up: async (tx) => { await tx.create({ collection: "users", data: { name: "root" } }); } },
{ version: 2, name: "add-role", up: async (tx) => { await tx.updateMany({ collection: "users", filter: {}, $set: { role: "member" } }); } },
]);A migration that throws is not recorded, so it runs again next time.
SencilloDB extends EventEmitter; see Events.
All are asynchronous and take a single instructions object.
| Method | Returns | Notes |
|---|---|---|
tx.create |
the created document | Needs data. |
tx.createMany |
array of created documents | data must be an array. index may be a function. |
tx.update |
the updated document | Needs _id or filter, and data or an update operator. |
tx.updateMany |
array of updated documents | Applies the same patch to every match. |
tx.destroy |
the removed document | Needs _id or filter. |
tx.destroyMany |
array of removed documents | Removes every match. |
tx.find |
the first match or undefined |
|
tx.findMany |
array of matches | Honours sort, skip, limit, populate. |
tx.count |
number | Same matching rules as findMany. |
tx.dropCollection |
void |
Deletes the collection and its files. |
tx.dropIndex |
void |
Deletes one index bucket, its documents and (in sharded mode) its file. |
tx.rewriteCollection |
void |
Rebuilds the collection: renumbers ids, re-sorts, re-buckets. Secondary indexes and TTL rules are preserved. |
tx.ensureIndex |
void |
{ collection, field, unique? }. Builds the index over existing documents. |
tx.dropSecondaryIndex |
void |
{ collection, field }. |
tx.ensureTTL |
void |
{ collection, field, seconds }. |
// full replacement (fields not present are dropped)
await tx.update({ collection: "users", _id: 1, data: { name: "Alice", age: 31 } });
// partial patch
await tx.update({ collection: "users", _id: 1, $set: { age: 31 } });
await tx.update({ collection: "users", _id: 1, $inc: { visits: 1 } });
await tx.update({ collection: "users", _id: 1, $unset: ["temporary"] });
// by filter, creating the document when nothing matches
await tx.update({
collection: "settings",
filter: { key: "theme" },
$set: { value: "dark" },
upsert: true,
});$set and $unset accept dot paths ("profile.theme"). Update operators are applied on top of data when both are given.
| Field | Used by | Meaning |
|---|---|---|
collection |
all | Collection name. Defaults to "default". |
index |
all | Index bucket. A string, a (document) => string function (create/createMany/update), or { current, new } to move a document. For reads it restricts the search to one bucket. |
data |
create, createMany, update | The document (or array of documents). |
_id |
update, destroy | Target document id. |
filter |
reads, update, destroy, *Many | Query object — see Querying. |
callback |
reads | (document) => boolean, combined with filter via AND. |
sort |
findMany, rewriteCollection | Array.sort comparator. Defaults to ascending _id. |
limit / skip |
findMany | Pagination, applied after sorting. |
populate |
find, findMany | [{ field, collection, targetField? }]. targetField defaults to _id. |
$set / $inc / $unset |
update, updateMany | Partial update operators. |
upsert |
update | Create the document when nothing matches. |
Wraps a single operation in its own transaction:
import { quickTx } from "sencillodb";
const qtx = quickTx(db);
const user = await qtx("create", { collection: "users", data: { name: "Alice" } });A schema-validating, hook-aware wrapper around one collection. See Schemas and Resource Managers.
const User = createResourceManager({
db,
collection: "users",
index: (user) => user.country,
schema: { name: String, age: { type: Number, required: false, default: 0 } },
hooks: { beforeCreate: (data) => ({ ...data, createdAt: new Date().toISOString() }) },
});
await User.create({ data: { name: "Alice" } });
await User.findMany({ filter: { age: { $gte: 18 } } });Returned object: schema, validate(document), errors(document), withDefaults(document), execute(operation, instructions) and shorthands create, createMany, update, updateMany, destroy, destroyMany, find, findMany, count.
All extend SencilloDBError, which extends Error.
| Error | Thrown when |
|---|---|
ValidationError |
Bad instructions, bad config, or a schema violation. |
CollectionNotFoundError |
The collection does not exist. |
IndexNotFoundError |
The index bucket does not exist. |
DocumentNotFoundError |
No document matched the _id or filter. |
UniqueConstraintError |
A write would duplicate a value on a unique index. |
CorruptDataError |
A store file exists but could not be read. |
LockError |
The advisory lock could not be acquired before the timeout. |
DatabaseNotLoadedError |
An operation was used outside a transaction before any load. |
db.on("create", ({ collection, index, _id, doc }) => { /* … */ });| Event | Payload | Fires |
|---|---|---|
create, update, destroy |
{ collection, index, _id, doc } |
After the transaction commits |
dropCollection, dropIndex, rewriteCollection |
{ collection, index? } |
After commit |
ensureIndex, dropSecondaryIndex, ensureTTL |
{ collection } |
After commit |
expire |
{ collection, index, _id, doc } |
During compact() |
commit |
array of the events just emitted | After commit |
rollback |
{ error } |
After a failed transaction |
warning |
{ message, detail } |
On a recoverable problem, e.g. an unreadable log line |