### Install and use vdb CLI Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/ecosystem/cli.md Install the CLI globally with bun, then run a find query and start the dev server. ```bash bun add -g @wxn0brp/db-cli vdb -d ./my-db find users '{ "name": "Jane" }' vdb server 3000 ``` -------------------------------- ### Install with Bun Source: https://github.com/wxn0brp/valtheradb/blob/master/README.md Install the ValtheraDB package using Bun. ```bash bun add @wxn0brp/db ``` -------------------------------- ### Install with Yarn Source: https://github.com/wxn0brp/valtheradb/blob/master/README.md Install the ValtheraDB package using Yarn. ```bash yarn add @wxn0brp/db ``` -------------------------------- ### Install with npm Source: https://github.com/wxn0brp/valtheradb/blob/master/README.md Install the ValtheraDB package using npm. ```bash npm install @wxn0brp/db ``` -------------------------------- ### Install and use the Python bridge (wxn0brp-db-conduit) Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/ecosystem/conduit.md Install the Python bridge package and use the ValtheraConduit context manager to initialize a database, create a collection, add a record, and query it. ```bash pip install wxn0brp-db-conduit ``` ```python from wxn0brp.db import conduit with conduit.ValtheraConduit("./vendor/vdb", auto_download=True) as c: db = c.data.init("./data") users = db.c("users") users.add({"name": "Ada"}) print(users.find({"name": "Ada"})) ``` -------------------------------- ### Install ValtheraDB with npm, bun, or yarn Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/getting_started.md Install the ValtheraDB package using your preferred package manager. Choose one of the three commands depending on your environment. ```bash npm install @wxn0brp/db ``` ```bash bun add @wxn0brp/db ``` ```bash yarn add @wxn0brp/db ``` -------------------------------- ### Install VDB() dependencies Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/ecosystem/adapters.md Install the resolver and core packages required to use the VDB() API. ```bash bun add @wxn0brp/db-resolver @wxn0brp/db-core ``` -------------------------------- ### Full usage example with Relation class Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/relation.md Complete example of using the Relation class to find posts with related author and comments. It creates two databases, defines relations with `select` and `dbFindOpts`, and demonstrates `findOne` and `find` with field selection arrays. ```typescript import { Relation } from "@wxn0brp/db-core"; import { ValtheraCreate } from "@wxn0brp/db"; // Create database instances const db1 = ValtheraCreate("./db1"); const db2 = ValtheraCreate("./db2"); // Define databases const dbs = { db1, db2 }; // Define relations const relations = { author: { path: ["db1", "users"], pk: "authorId", fk: "_id", type: "1", select: ["name", "email"] }, comments: { path: ["db2", "comments"], pk: "_id", fk: "postId", type: "1n", dbFindOpts: { limit: 20, sortBy: "createdAt", sortAsc: false } } }; // Create a Relation instance const relation = new Relation(dbs); // Find a single post with relations const post = await relation.findOne( ["db1", "posts"], { _id: "post123" }, relations, [["title"], ["author.name"], ["comments.content"]] ); console.log(post); // Find multiple posts with relations const posts = await relation.find( ["db1", "posts"], { category: "tech" }, relations, [["title"], ["author.name"], ["comments.content"]], { limit: 10 } ); console.log(posts); ``` -------------------------------- ### Select and exclude interaction example Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/find_opts.md Shows the interaction when both select and exclude are used. Exclude is applied first, then select. The example excludes 'b' and selects 'a' and 'c', resulting in { a: 1, c: 3 }. ```javascript // Original: { a: 1, b: 2, c: 3, d: 4 } { exclude: ["b"], // Step 1: { a: 1, c: 3, d: 4 } select: ["a", "c"] // Step 2: { a: 1, c: 3 } } ``` -------------------------------- ### Logging Plugin Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/plugin.md Example plugin that logs all operations with timing information. ```APIDOC ## Logging Plugin ### Description Logs all operations with timing information. ### Example ```typescript const loggingPlugin: ValtheraPlugin = { name: "logger", async execute(ctx) { const start = Date.now(); console.log(`[START] ${ctx.op}`, ctx.query); const result = await ctx.next(); const duration = Date.now() - start; console.log(`[END] ${ctx.op} (${duration}ms)`); return result; } }; ``` ``` -------------------------------- ### Basic Plugin Structure Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/plugin.md Minimal example of a plugin with execute method that logs before and after the operation. ```APIDOC ## Basic Plugin Structure ### Description Minimal plugin structure showing how to wrap an operation with before/after logic. ### Example ```typescript import { ValtheraPlugin } from "@wxn0brp/db"; const myPlugin: ValtheraPlugin = { name: "my-plugin", async execute(ctx) { // Before the operation console.log(`About to execute: ${ctx.op}`); // Call next() to continue the chain const result = await ctx.next(); // After the operation console.log(`Finished: ${ctx.op}`); return result; } }; ``` ``` -------------------------------- ### $startsWith Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/search_opts.md String operator that matches documents where the string field starts with the specified value. ```APIDOC ## $startsWith ### Description Checks if a string starts with a specified value. ### Syntax ```javascript { $startsWith: { name: "Dr." } } ``` ``` -------------------------------- ### sum option in dbFindOpts Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/db_find_opts.md Shows how to use the sum option in dbFindOpts to compute the total of a numeric field. The first example maps the output key totalRevenue to the source field amount. The second example groups by category and sums the price field into totalSales. ```javascript // Total revenue across all entries { dbFindOpts: { sum: { totalRevenue: "amount" } } } ``` ```javascript // Sum with grouping { dbFindOpts: { groupBy: "category", sum: { totalSales: "price" } } } ``` -------------------------------- ### Logging plugin with timing Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/plugin.md Logs each operation with timing. Records the start time, logs the operation and query, awaits ctx.next(), then logs the duration in milliseconds. ```typescript const loggingPlugin: ValtheraPlugin = { name: "logger", async execute(ctx) { const start = Date.now(); console.log(`[START] ${ctx.op}`, ctx.query); const result = await ctx.next(); const duration = Date.now() - start; console.log(`[END] ${ctx.op} (${duration}ms)`); return result; } }; ``` -------------------------------- ### db.version Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/valthera.md Gets the version of the ValtheraDB core engine. ```APIDOC ## Property: db.version ### Description Gets the version of the ValtheraDB core engine. ### Returns - **string** - The version string, e.g., "0.11.6". ### Example ```typescript db.version; // e.g., "0.11.6" ``` ``` -------------------------------- ### Run ValtheraDB server with Docker Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/ecosystem/server.md Starts the ValtheraDB HTTP server on port 14785 using Docker. The server is built on FalconFrame with JWT auth, GateWarden permissions, Web GUI, and SQL/CSV import/export. ```bash docker run -p 14785:14785 ghcr.io/wxn0brp/valthera-server ``` -------------------------------- ### Custom TTL for SmartExecutor Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/valthera.md Custom TTL example: 10 minutes and per-collection queues. ```typescript const db = new ValtheraClass({ adapter: myAdapter, executor: new SmartExecutor(10 * 60 * 1000, true) // 10 min, per-collection }); ``` -------------------------------- ### async db.getCollections() Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/valthera.md Gets the names of all available collections in the database. ```APIDOC ## Method: async db.getCollections() ### Description Gets the names of all available collections in the database. ### Returns - **Promise** - A promise that resolves with an array of collection names. ### Example ```typescript const collections = await db.getCollections(); ``` ``` -------------------------------- ### Result Transformation Plugin Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/plugin.md Example plugin that transforms results after the adapter returns them. ```APIDOC ## Modifying Results ### Description Transform results after the adapter returns them. ### Example ```typescript const transformPlugin: ValtheraPlugin = { name: "transformer", async execute(ctx) { const result = await ctx.next(); if (ctx.op === "find" && Array.isArray(result)) { return result.map(item => ({ ...item, fullName: `${item.firstName} ${item.lastName}` })); } return result; } }; ``` ``` -------------------------------- ### $startsWith string operator Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/search_opts.md Checks if a string starts with a specified value. Use this operator to match documents where the field value begins with the given string. ```javascript { $startsWith: { name: "Dr." } } ``` -------------------------------- ### dbFindOpts Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/db_find_opts.md Documentation for the dbFindOpts options object used in database find operations, including all supported fields and usage examples. ```APIDOC ## dbFindOpts ### Description Options object for database find operations, supporting pagination, sorting, aggregation, and distinct queries. ### Fields - **offset** (number) - Optional - Number of records to skip for pagination. - **limit** (number) - Optional - Maximum number of records to return. - **sortBy** (string | array) - Optional - Field name to sort by, or an array of sort objects for multi-field sorting. Use `"random()"` for random order. - **sortAsc** (boolean) - Optional - Sort ascending if true, descending if false. Default is ascending. - **reverse** (boolean) - Optional - Reverse the natural file order. - **groupBy** (string) - Optional - Field name to group records by for aggregation. - **count** (object) - Optional - Aggregation: count records, mapping alias to field name. - **min** (object) - Optional - Aggregation: minimum value, mapping alias to field name. - **max** (object) - Optional - Aggregation: maximum value, mapping alias to field name. - **avg** (object) - Optional - Aggregation: average value, mapping alias to field name. - **sum** (object) - Optional - Aggregation: sum of values, mapping alias to field name. - **distinct** (string) - Optional - Field name to get distinct values for. ### Examples #### Basic Pagination ```javascript { dbFindOpts: { offset: 10, limit: 10 } } ``` #### Sort by Field Descending ```javascript { dbFindOpts: { sortBy: "age", sortAsc: false, limit: 50 } } ``` #### Random Sample ```javascript { dbFindOpts: { sortBy: "random()", limit: 10 } } ``` #### Reverse Order ```javascript { dbFindOpts: { reverse: true, offset: 0, limit: 100 } } ``` #### Combined Options ```javascript { dbFindOpts: { sortBy: "createdAt", sortAsc: false, offset: 0, limit: 20 } } ``` #### Aggregate per Group ```javascript { dbFindOpts: { groupBy: "category", count: { itemCount: "id" }, min: { minPrice: "price" }, max: { maxPrice: "price" }, avg: { avgPrice: "price" } } } ``` #### Global Aggregation (no grouping) ```javascript { dbFindOpts: { count: { total: "id" }, min: { youngest: "age" }, max: { oldest: "age" }, avg: { averageAge: "age" }, sum: { totalAge: "age" } } } ``` #### Multi-Field Sort ```javascript { dbFindOpts: { sortBy: [ { field: "lastName", asc: true }, { field: "age", asc: false } ] } } ``` #### Distinct Values ```javascript { dbFindOpts: { distinct: "category", count: { total: "id" } } } ``` ``` -------------------------------- ### Manual commit and rollback with tx.commit() and tx.rollback() Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/transaction.md Shows manual commit and rollback using tx.commit() and tx.rollback(). The example checks inventory and explicitly rolls back if insufficient, otherwise commits. ```typescript await db.transaction(["orders"], async (tx) => { try { await tx.c("orders").add({ item: "Widget", quantity: 5 }); // Check some condition const inventory = await tx.c("inventory").findOne({ search: { item: "Widget" } }); if (inventory.quantity < 5) { await tx.rollback(); // Explicit rollback throw new Error("Insufficient inventory"); } await tx.commit(); // Explicit commit } catch (err) { // Error handling throw err; } }); ``` -------------------------------- ### select operator example Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/find_opts.md Shows how to use the select option to include only specific fields in the final object. The original object has fields name, email, age, and status; selecting name and email returns an object with only those fields. ```javascript // Original Object { name: "John Doe", email: "john@example.com", age: 30, status: "active" } // Find Options { select: ["name", "email"] } // Result { name: "John Doe", email: "john@example.com" } ``` -------------------------------- ### RoutedStorage: Route collections to specific backends Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/multi_storage.md Creates a RoutedStorage instance with an array of rules and a default adapter. Rules can be a string (exact collection name or "*"), a RegExp, or a function that takes a query and returns a boolean. The ValtheraClass is then instantiated with this routed adapter. Use for hot/cold storage, per-collection backends, or multi-tenant setups. ```typescript import { RoutedStorage, ValtheraClass } from "@wxn0brp/db-core"; const routed = new RoutedStorage([ { match: "logs", backends: logAdapter }, { match: /^temp_/, backends: memoryAdapter }, { match: (q) => q.collection.includes("archive"), backends: archiveAdapter } ], defaultAdapter); const db = new ValtheraClass({ adapter: routed }); ``` -------------------------------- ### Reverse Order with dbFindOpts Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/db_find_opts.md Reverses the natural file order of results, starting from the first entry and returning up to 100 items. ```javascript // Get results in reverse file order { dbFindOpts: { reverse: true, offset: 0, limit: 100 } } ``` -------------------------------- ### Register a logging plugin with db.plugin() Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/valthera.md Example of registering a plugin that logs operations. The plugin's execute method logs before and after calling ctx.next(). The returned unregister function removes the plugin when called. ```typescript const loggingPlugin: ValtheraPlugin = { name: "logger", async execute(ctx) { console.log(`Executing ${ctx.op}`); const result = await ctx.next(); console.log(`Completed ${ctx.op}`); return result; } }; const unregister = db.plugin(loggingPlugin); // Later: unregister() to remove the plugin ``` -------------------------------- ### Audit logging with wildcard event Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/valthera.md Audit logging example that records delete operations using the wildcard event. ```typescript db.emitter.on("*", (op, query, result) => { if (op === "remove" || op === "removeOne") { auditLog.record({ action: "delete", collection: query.collection, timestamp: new Date() }); } }); ``` -------------------------------- ### Nested relations example Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/relation.md Shows how to nest relations to resolve deeply linked data. The relations option on a relation entry resolves relations on the related documents themselves. ```javascript const relations = { author: { path: ["main", "users"], pk: "_id", fk: "_id", type: "1", relations: { // Resolve relations on the author document itself recentPosts: { path: ["main", "posts"], pk: "_id", fk: "authorId", type: "1n" } } }, comments: { path: ["main", "comments"], pk: "_id", fk: "postId", type: "1n", relations: { // Resolve relations on each comment author: { path: ["main", "users"], pk: "authorId", fk: "_id", type: "1" } } } }; ``` -------------------------------- ### Implement custom ExecutorInterface with MyCustomExecutor Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/executor.md Implements a custom executor by implementing the ExecutorInterface from @wxn0brp/db-core. The addOp method must return a promise that resolves with the operation result; the example queues the operation and calls func(query) when ready. ```typescript import { ExecutorInterface } from "@wxn0brp/db-core"; class MyCustomExecutor implements ExecutorInterface { async addOp(func: Function, query?: any, collection?: string): Promise { // Your custom logic here // Must return a promise that resolves with the operation result return await new Promise((resolve, reject) => { // Queue the operation // Call func(query) when ready func(query).then(resolve).catch(reject); }); } } const db = new ValtheraClass({ adapter: myAdapter, executor: new MyCustomExecutor() }); ``` -------------------------------- ### Create a database with VDB for adapter switching Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/getting_started.md Create a database instance using VDB() to allow switching storage adapters via environment variables. The .dir() method sets the directory adapter. Later you can switch to SQLite by setting VALTHERA_MASTER and VALTHERA_MASTER_OPTS without code changes. ```typescript import { VDB } from "@wxn0brp/db"; // Create a new database instance - same API, but adapter can be changed via env const db = VDB<{ users: { name: string; email: string; _id: string; }; posts: { title: string; content: string; authorId: string; _id: string; }; }>().dir("./my-blog-db"); // Later, switch to SQLite without code changes: // VALTHERA_MASTER=sqlite VALTHERA_MASTER_OPTS=["./db.sqlite"] bun run app.ts ``` -------------------------------- ### async db.init(...args) Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/valthera.md Initializes the adapter. Must be called before performing any operations. If the adapter was provided as a factory function, it is called during this step. Calling init() on an already-initialized instance is a no-op. ```APIDOC ## Method: async db.init(...args) ### Description Initializes the adapter. Must be called before performing any operations. If the adapter was provided as a factory function, it is called during this step. Calling init() on an already-initialized instance is a no-op. ### Parameters - **...args** - Optional - Arguments passed to the adapter's init method. ### Returns - **Promise** - Resolves when initialization is complete. ### Example ```typescript await db.init(); ``` ``` -------------------------------- ### distinct option in dbFindOpts Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/db_find_opts.md Shows how to use the distinct option in dbFindOpts to remove duplicate entries based on a field. The first example deduplicates by category. The second example combines distinct with a limit of 100. ```javascript // Get unique categories { dbFindOpts: { distinct: "category" } } ``` ```javascript // Distinct with other options { dbFindOpts: { distinct: "email", limit: 100 } } ``` -------------------------------- ### Use VDB() with dir, sqlite, mongodb, and typed collections Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/ecosystem/adapters.md Shows how to instantiate the VDB() API with different adapters (dir, sqlite.bun, mongodb) and typed collections. The dir adapter is the default. Resolution order is force option, VALTHERA_ env var, def fallback, then ./vdb-data/. ```typescript import { VDB } from "@wxn0brp/db-resolver"; // Dir adapter (default) const db = VDB().dir("./data"); // SQLite with Bun const db = VDB().sqlite.bun("db.sqlite"); // MongoDB const db = VDB().mongodb("mongodb://localhost:27017", "mydb"); // Typed collections const db = VDB<{ users: { id: number; name: string } }>().dir("./data"); await db.users.add({ id: 1, name: "Ala" }); ``` -------------------------------- ### ValtheraRemote Constructor Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/remote.md Creates a new ValtheraRemote instance. The constructor accepts either a remote object with name, url, and auth properties, or a connection string in the format 'https://dbName:token@example.com/db'. ```APIDOC ## ValtheraRemote(remote) ### Description Creates a new ValtheraRemote instance. The constructor accepts either a remote object with name, url, and auth properties, or a connection string in the format 'https://dbName:token@example.com/db'. ### Parameters #### remote (Object or String) - Required - **name** (string) - Required - The name of the Valthera. - **url** (string) - Required - The URL of the remote Valthera. - **auth** (string) - Required - The authentication token for accessing the Valthera. Alternatively, a connection string can be provided in the format: `https://dbName:token@example.com/db`. ### Example Usage javascript const remoteDB = new ValtheraRemote({ name: 'myRemoteDB', url: 'https://example.com/db', auth: 'your-auth-token' }); or javascript const remoteDB = new ValtheraRemote('https://dbName:token@example.com/db'); ``` -------------------------------- ### Instantiate ValtheraRemote with object or connection string Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/remote.md Two ways to instantiate ValtheraRemote: with an object specifying name, url, and auth, or with a connection string containing dbName and token. Both create a remote client for HTTP requests. ```javascript const remoteDB = new ValtheraRemote({ name: 'myRemoteDB', url: 'https://example.com/db', auth: 'your-auth-token' }); ``` ```javascript const remoteDB = new ValtheraRemote('https://dbName:token@example.com/db'); ``` -------------------------------- ### Import utility functions from @wxn0brp/db-core Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/adapter.md Shows how to import ID generation, query helpers, find utility, and types from @wxn0brp/db-core. Use these imports when building custom adapters. ```typescript // ID generation import { genId } from "@wxn0brp/db-core"; import { addId } from "@wxn0brp/db-core/helpers/addId"; // Query helpers import { hasFieldsAdvanced } from "@wxn0brp/db-core/utils/hasFieldsAdvanced"; import { updateFindObject } from "@wxn0brp/db-core/utils/updateFindObject"; import { updateObjectAdvanced } from "@wxn0brp/db-core/utils/updateObject"; // Find utility for multi-file searches import { findUtil } from "@wxn0brp/db-core/utils/action"; // Types import type { FileCpu } from "@wxn0brp/db-core/types/fileCpu"; import type { Data, DataInternal } from "@wxn0brp/db-core/types/data"; import type { VQueryT } from "@wxn0brp/db-core/types/query"; import type { AdapterOpts } from "@wxn0brp/db-core/types/options"; ``` -------------------------------- ### Create a database with ValtheraCreate Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/getting_started.md Create a database instance using the ValtheraCreate function with the dir adapter. The generic type parameter defines the collections for type checking. This creates a folder named 'my-blog-db' in your project. ```typescript import { ValtheraCreate } from "@wxn0brp/db"; // Create a new database instance inside the "./my-blog-db" directory const db = ValtheraCreate<{ // Define your collections here (for type checking) users: { name: string; email: string; _id: string; }; posts: { title: string; content: string; authorId: string; _id: string; }; }>("./my-blog-db"); ``` -------------------------------- ### Query Modification Plugin Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/plugin.md Example plugin that modifies queries before they reach the adapter. ```APIDOC ## Modifying Queries ### Description Plugins can modify queries before they reach the adapter. ### Example ```typescript const softDeletePlugin: ValtheraPlugin = { name: "soft-delete", async execute(ctx) { // Add deleted filter to all find operations if (ctx.op === "find" || ctx.op === "findOne") { ctx.query.search ||= {}; ctx.query.search.deleted = { $ne: true }; } return ctx.next(); } }; ``` ``` -------------------------------- ### Operation Blocker Plugin Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/plugin.md Example plugin that prevents write operations in read-only mode. ```APIDOC ## Operation Blocker Plugin ### Description Prevents certain operations by throwing an error. ### Example ```typescript const readOnlyPlugin: ValtheraPlugin = { name: "read-only", async execute(ctx) { const writeOps = ["add", "update", "updateOne", "remove", "removeOne"]; if (writeOps.includes(ctx.op)) { throw new Error(`Operation ${ctx.op} is not allowed in read-only mode`); } return ctx.next(); } }; ``` ``` -------------------------------- ### Create memory database with pre-populated data Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/memory.md Creates an in-memory database pre-populated with users and posts, then queries the users collection to confirm the data is immediately available. ```typescript import { createMemoryValthera } from "@wxn0brp/db-core"; const db = createMemoryValthera({ users: [ { _id: "user1", name: "Alice", email: "alice@example.com" }, { _id: "user2", name: "Bob", email: "bob@example.com" } ], posts: [ { _id: "post1", title: "Hello", authorId: "user1" } ] }); // Data is immediately available const users = await db.users.find({}); console.log(users.length); // 2 ``` -------------------------------- ### $iStartsWith Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/search_opts.md String operator that matches documents where the string field starts with the specified value, ignoring case. ```APIDOC ## $iStartsWith ### Description Checks if a string starts with a specified value (case-insensitive). ### Syntax ```javascript { $iStartsWith: { name: "dr" } } // matches "Dr.", "DR.", "dr." ``` ``` -------------------------------- ### Clone PHP server for MariaDB/MySQL Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/ecosystem/server.md Clones the alternative PHP implementation of the ValtheraDB server for SQL databases (MariaDB/MySQL). Configure via config.php; the API is compatible with the main server. ```bash git clone https://github.com/wxn0brP/ValtheraDB-server-php.git ``` -------------------------------- ### Basic plugin structure Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/plugin.md Minimal plugin structure. Import the ValtheraPlugin type, define a plugin with a name and an async execute that logs before and after calling ctx.next() and returns the result. ```typescript import { ValtheraPlugin } from "@wxn0brp/db"; const myPlugin: ValtheraPlugin = { name: "my-plugin", async execute(ctx) { // Before the operation console.log(`About to execute: ${ctx.op}`); // Call next() to continue the chain const result = await ctx.next(); // After the operation console.log(`Finished: ${ctx.op}`); return result; } }; ``` -------------------------------- ### SmartExecutor with aware = true Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/executor.md When aware = true, queues are isolated per collection. Each collection gets its own separate queue. ```typescript const executor = new SmartExecutor(300000, true); // "users" -> separate queue // "posts" -> separate queue // "comments" -> separate queue ``` -------------------------------- ### MultiBackend Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/multi_storage.md Creates a MultiBackend instance that queries across multiple adapters simultaneously. The primaryIndex parameter (default 0) determines which backend receives writes. ```APIDOC ## MultiBackend ### Description Creates a MultiBackend instance that queries across multiple adapters simultaneously. The primaryIndex parameter (default 0) determines which backend receives writes. ### Constructor `new MultiBackend(adapters: Adapter[], primaryIndex?: number)` ### Parameters - **adapters** (Adapter[]) - Required - Array of storage adapters to query across. - **primaryIndex** (number) - Optional - Index of the primary backend for write operations. Defaults to 0. ### Usage Example ```typescript import { MultiBackend, ValtheraClass } from "@wxn0brp/db-core"; const multi = new MultiBackend([ adapter1, adapter2, adapter3, ], 0); // primaryIndex (default: 0) const db = new ValtheraClass({ adapter: multi }); ``` ### Operation Behavior | Operation | Behavior | |-----------|----------| | `add` | Primary backend only | | `find` | All backends, results merged (flattened) | | `findOne` | Iterates backends, returns first non-null match | | `update` | All backends, results merged | | `updateOne` | Iterates backends, returns first non-null result | | `remove` | All backends, results merged | | `removeOne` | Iterates backends, returns first non-null result | | `ensureCollection` | All backends | | `issetCollection` | Returns `true` if any backend has the collection | | `removeCollection` | All backends | | `getCollections` | Unique union from all backends | ### Use Cases Replication, migration, read replicas ``` -------------------------------- ### Create and use a collection with db.c() Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/valthera.md Creates or retrieves a Collection instance for the given collection name. The collection is cached for reuse. When using forgeTypedValthera() or ValtheraCreate(), you can access collections directly as properties (e.g., db.users). ```typescript const users = db.c("users"); await users.add({ name: "Alice" }); ``` -------------------------------- ### RoutedStorage Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/multi_storage.md Creates a RoutedStorage instance that routes collections to specific backends based on rules. When no rules match, the defaultBackend is used. ```APIDOC ## RoutedStorage ### Description Creates a RoutedStorage instance that routes collections to specific backends based on rules. When no rules match, the defaultBackend is used. ### Constructor `new RoutedStorage(rules: Rule[], defaultBackend: Adapter)` ### Parameters - **rules** (Rule[]) - Required - Array of routing rules. Each rule has a `match` property (string, RegExp, or function) and a `backends` property (adapter or array of adapters). - **defaultBackend** (Adapter) - Required - Backend used when no rules match. ### Match Types - **String**: exact collection name or `"*"` for all - **RegExp**: pattern match on collection name - **Function**: `(query) => boolean` ### Usage Example ```typescript import { RoutedStorage, ValtheraClass } from "@wxn0brp/db-core"; const routed = new RoutedStorage([ { match: "logs", backends: logAdapter }, { match: /^temp_/, backends: memoryAdapter }, { match: (q) => q.collection.includes("archive"), backends: archiveAdapter } ], defaultAdapter); const db = new ValtheraClass({ adapter: routed }); ``` ### Operation Behavior | Operation | Behavior | |-----------|----------| | `add` | Writes to first matched backend, then replicates to all matched backends | | `find` | First matched backend only | | `findOne` | First matched backend only | | `update` | All matched backends | | `updateOne` | All matched backends | | `remove` | All matched backends | | `removeOne` | All matched backends | | `getCollections` | Unique union from all rule backends | When no rules match, the `defaultBackend` is used. ### Use Cases Hot/cold storage, per-collection backends, multi-tenant ``` -------------------------------- ### Nested Conditions with hasFieldsAdvanced Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/search_opts.md Demonstrates nested $and and $or conditions to validate an address object. The example returns true for a user with an address containing city and country but no zipCode. ```javascript const criteria = { $and: [ { $exists: { address: true }, $type: { address: "object" } }, { $or: [ { $exists: { "address.zipCode": true } }, { $and: [ { $exists: { "address.city": true } }, { $exists: { "address.country": true } } ] } ] } ] }; const user = { address: { city: "New York", country: "USA" } }; const isValid = hasFieldsAdvanced(user, criteria); // true ``` -------------------------------- ### Initialize adapter with db.init() Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/valthera.md Initializes the adapter. Must be called before any operations. If the adapter was provided as a factory function, it is called during this step. Calling init() on an already-initialized instance is a no-op. ```typescript await db.init(); ``` -------------------------------- ### convertIdToUnix: Extract Unix timestamp from ID Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/id.md Extracts the Unix timestamp (milliseconds) from an ID. The example shows converting an ID to a timestamp and then creating a Date object from it. ```typescript import { convertIdToUnix } from "@wxn0brp/db-core"; const id = "m1abc23-x-y"; const timestamp = convertIdToUnix(id); // 1700000000000 const date = new Date(timestamp); ``` -------------------------------- ### Basic transaction with ValtheraCreate Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/dev/transaction.md Shows the basic transaction pattern: declare collections upfront, use the tx object for all operations, and rely on automatic rollback if any operation throws. ```typescript import { ValtheraCreate } from "@wxn0brp/db"; const db = ValtheraCreate("mydb"); await db.transaction(["users", "accounts"], async (tx) => { // All operations use the tx object, not db const user = await tx.c("users").add({ name: "Alice", email: "alice@example.com" }); await tx.c("accounts").add({ userId: user._id, balance: 1000, createdAt: new Date() }); // If we reach here, both operations succeed // If any operation throws, both are rolled back }); ``` -------------------------------- ### exclude operator example Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/find_opts.md Shows how to use the exclude option to remove specific fields from the object. Excluding the name field returns an object with email, age, and status. ```javascript // Original Object { name: "John Doe", email: "john@example.com", age: 30, status: "active" } // Find Options { exclude: ["name"] } // Result { email: "john@example.com", age: 30, status: "active" } ``` -------------------------------- ### ValtheraClass with adapterOpts Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/valthera.md Example of constructing a ValtheraClass with adapterOpts to use numeric IDs and a custom ID field name. The legacy top-level numberId and idKey options are deprecated. ```typescript const db = new ValtheraClass({ adapter: myAdapter, adapterOpts: { numberId: true, // Use numeric IDs (1, 2, 3...) idKey: "id", // Use "id" instead of "_id" } }); ``` -------------------------------- ### Basic Pagination with dbFindOpts Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/db_find_opts.md Retrieves the second page of results by skipping the first 10 entries and limiting the result set to 10 items. ```javascript // Get page 2 with 10 items per page { dbFindOpts: { offset: 10, limit: 10 } } ``` -------------------------------- ### transform operator example Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/find_opts.md Shows how to use the transform option to apply a custom updater function to modify the object. The function uppercases the name field and returns the modified document. ```javascript // Original Object { name: "John Doe", email: "john@example.com", age: 30, status: "active" } // Find Options { transform: (doc) => { doc.name = doc.name.toUpperCase(); return doc; } } // Result { name: "JOHN DOE", email: "john@example.com", age: 30, status: "active" } ``` -------------------------------- ### MultiBackend: Query across multiple adapters Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/multi_storage.md Creates a MultiBackend instance with an array of adapters and an optional primary index (default 0). The ValtheraClass is then instantiated with this multi-backend adapter. Use for replication, migration, or read replicas. ```typescript import { MultiBackend, ValtheraClass } from "@wxn0brp/db-core"; const multi = new MultiBackend([ adapter1, adapter2, adapter3, ], 0); // primaryIndex (default: 0) const db = new ValtheraClass({ adapter: multi }); ``` -------------------------------- ### $iStartsWith case-insensitive string operator Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/search_opts.md Checks if a string starts with a specified value (case-insensitive). Use this operator to match documents where the field value begins with the given string regardless of case. ```javascript { $iStartsWith: { name: "dr" } } // matches "Dr.", "DR.", "dr." ``` -------------------------------- ### Custom ID Key Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/id.md Shows how to configure a custom ID key for the database. ```APIDOC ## Custom ID Key ### Description Configure a custom ID key via `adapterOpts`. ### Method Function ### Request Example ```typescript import { ValtheraCreate } from "@wxn0brp/db"; const db = ValtheraCreate("./my-db", { adapterOpts: { idKey: "id", // Use "id" instead of "_id" } }); // Now all documents will use "id" as the ID field const user = await db.users.add({ name: "Alice" }); // { name: "Alice", id: "m1abc23-x-y" } ``` ### Notes The custom `idKey` applies to all collections in the database. When using `numberId: true`, the numeric auto-incrementing ID will also use the custom key. ``` -------------------------------- ### Complex Validation with hasFieldsAdvanced Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/search_opts.md Shows a complex criteria object using $and, $or, $gt, $exists, $type, $regex, $arrincall, and $not operators to validate a user object. The example returns true for the given user. ```javascript const criteria = { $and: [ { $or: [ { $gt: { age: 18 } }, { $exists: { guardianConsent: true } } ] }, { $type: { email: "string" }, $regex: { email: /^[^@]+@[^@]+\.[^@]+$/ } }, { $arrincall: { roles: ["user"] }, $not: { $in: { status: ["banned", "suspended"] } } } ] }; const user = { age: 16, guardianConsent: true, email: "john@example.com", roles: ["user", "premium"], status: "active" }; const isValid = hasFieldsAdvanced(user, criteria); // true ``` -------------------------------- ### new ValtheraClass(options) Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/valthera.md Creates a new ValtheraDB instance. The adapter can be an ActionsBase instance or a factory function. Configuration options include adapterOpts for numeric IDs and custom ID field names. ```APIDOC ## Constructor: new ValtheraClass(options) ### Description Creates a new ValtheraDB instance. The adapter can be an ActionsBase instance or a factory function that returns one. Configuration options include adapterOpts for numeric IDs and custom ID field names. ### Parameters - **adapter** (ActionsBase | () => Promise) - Required - The storage adapter instance or a factory function that returns one. - **executor** (Executor) - Optional - Executor for database operations. - **executorAware** (boolean) - Optional - Whether the adapter is executor-aware. Default: true. - **adapterOpts** (AdapterOpts) - Optional - Configuration options for the adapter. - **numberId** (boolean) - Optional - Deprecated. Use adapterOpts.numberId. - **idKey** (string) - Optional - Deprecated. Use adapterOpts.idKey. ### Example ```typescript const db = new ValtheraClass({ adapter: myAdapter, adapterOpts: { numberId: true, idKey: "id" } }); ``` ``` -------------------------------- ### Array paths with specific indices Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/find_opts.md Shows how to use array paths with specific indices to work with array elements. The select option uses ["users", "0", "name"] to select the name of the first user. ```javascript { select: [["users", "0", "name"]] } ``` -------------------------------- ### forgeTypedValthera(target) usage Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/forge.md Creates a typed proxy with TypeScript support. Accessing a property that doesn't exist on the target creates a Collection instance for that collection name. The example shows typed access to db.users and a findOne call. ```typescript import { forgeTypedValthera } from "@wxn0brp/db-core"; import { ValtheraClass } from "@wxn0brp/db-core"; interface User { _id: string; name: string; email: string; } const db = forgeTypedValthera<{ users: User[] }>( new ValtheraClass({ adapter }) ); // db.users is typed as Collection const user = await db.users.findOne({ email: "alice@example.com" }); // user is typed as User | null ``` -------------------------------- ### Nested paths with arrays - select example Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/find_opts.md Shows that dotted paths in select do not traverse through arrays. When a path segment points to an array, it is replaced with an empty object. The result for select: ["users.name"] is { users: { name: undefined } }. ```javascript // Original Object { users: [ { name: "Alice", age: 30 }, { name: "Bob", age: 25 } ] } // Find Options { select: ["users.name"] } // Result - array is replaced with object! { users: { name: undefined // array was replaced } } ``` -------------------------------- ### genId: Generate a unique ID Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/id.md Generates a unique ID using the default format. Optionally accepts an array of part lengths to customize the random segments. The example shows default usage and a custom part length of [2, 3]. ```typescript import { genId } from "@wxn0brp/db-core"; const id = genId(); // "m1abc23-x-y" const customId = genId([2, 3]); // "m1abc23-xy-zab" ``` -------------------------------- ### async db.close(...args) Source: https://github.com/wxn0brp/valtheradb/blob/master/docs/api/valthera.md Closes the adapter connection. Subsequent operations will not work until init() is called again. ```APIDOC ## Method: async db.close(...args) ### Description Closes the adapter connection. Subsequent operations will not work until init() is called again. ### Parameters - **...args** - Optional - Arguments passed to the adapter's close method. ### Returns - **Promise** - Resolves when the connection is closed. ### Example ```typescript await db.close(); ``` ```