/** * nedb-client — TypeScript/JavaScript client for the nedbd HTTP API. * * Works in Node.js (18+) and modern browsers. * * @example * ```ts * import { NedbClient } from "nedb-engine-client"; * * const db = new NedbClient({ url: "http://127.0.0.1:7070", db: "mydb" }); * * await db.put("blocks", "618000", { height: 618000, hash: "000abc" }); * const rows = await db.query("FROM blocks ORDER BY height DESC LIMIT 10"); * const head = await db.head(); * ``` */ export interface NedbClientOptions { /** Base URL of the nedbd server. Default: "http://127.0.0.1:7070" */ url?: string; /** Database name. All operations target this database. */ db: string; /** Bearer token (matches NEDBD_TOKEN on the server). */ token?: string; /** * Auto-create the database on first write if it doesn't exist. * Default: true */ autoCreate?: boolean; /** * Read timeout in milliseconds (for queries). * Default: 3000 */ readTimeoutMs?: number; /** * Write timeout in milliseconds (for puts, deletes, batch). * Default: 30000 */ writeTimeoutMs?: number; } export interface PutOptions { /** Object hashes that causally led to this write (DAG provenance). */ causedBy?: string[]; /** Bi-temporal valid-from date (ISO 8601). */ validFrom?: string; /** Bi-temporal valid-to date (ISO 8601). */ validTo?: string; /** Human-readable provenance note. */ evidence?: string; /** Confidence score 0–1. */ confidence?: number; /** Idempotency key — duplicate puts with the same key are no-ops. */ idem?: string; /** Replay-protection nonce (monotonically increasing per clientId). */ nonce?: number; /** Client identifier for replay protection. */ clientId?: string; } export interface PutResult { ok: boolean; doc: Record; seq: number; head: string; } export interface QueryResult { rows: Record[]; count: number; seq: number; head: string; } /** * Result of a natural-language cast. The interesting part is the PLAN, not the * rows — `rows`/`count` appear only when `execute: true` was requested. */ export interface CastResult { prompt: string; /** The generated NQL. Present even on a 422, so you can see what it got wrong. */ nql: string; /** Whether the generated NQL parses — checked by the same parser that executes it. */ valid: boolean; /** The collection named after FROM, if one could be read off the output. */ collection: string | null; /** Whether that collection exists in this database. */ collection_known: boolean; /** Every collection this database actually has — what the plan was checked against. */ collections: string[]; executed: boolean; seq: number; head: string; rows?: Record[]; count?: number; error?: string; /** * Present when the plan contains a quoted literal that is NOT in the prompt — * the model substituted a memorised value instead of copying yours. * * ``` * "memories about pricing" -> FROM memories SEARCH "handoff" * ``` * * The query is valid, the collection exists, rows come back — and it answers * a different question. `valid` and `collection_known` cannot catch this, so * **check `drift` before acting on results unattended.** Advisory only: the * plan may still be what you wanted. */ drift?: string; } export interface VerifyResult { ok: boolean; seq: number; head: string; tamper_evident: boolean; objects_checked: number; tampered: string[]; } export interface HealthResult { ok: boolean; service: string; version: string; databases: string[]; encrypted: boolean; } export interface BatchOp { op: "put" | "del"; coll: string; id: string; doc?: Record; caused_by?: string[]; } export interface BatchResult { results: Array<{ op: string; id: string; seq?: number; error?: string; }>; count: number; seq: number; head: string; } /** Thrown when nedbd returns a non-2xx response (except auto-handled cases). */ export declare class NedbError extends Error { readonly status: number; readonly message: string; constructor(status: number, message: string); } export declare class NedbClient { private readonly base; private readonly db; private readonly headers; private readonly autoCreate; private readonly readMs; private readonly writeMs; constructor(opts: NedbClientOptions); private fetch; private raise; private ensureDb; /** * Write a document. * * @example * ```ts * await db.put("blocks", "618000", { height: 618000 }); * await db.put("claims", "c1", { fact: "..." }, { causedBy: ["abc123"] }); * ``` */ put(coll: string, id: string, doc: Record, opts?: PutOptions): Promise; /** * Fetch the current version of a document. Returns null if not found. */ get(coll: string, id: string): Promise | null>; /** * Tombstone-delete a document. * History is preserved in the DAG; returns true if the document existed. */ delete(coll: string, id: string): Promise; /** * Run a NQL query. Returns an array of document objects. * * ``` * NQL: FROM * [AS OF ] * [VALID AS OF ""] * [WHERE field = value [AND ...]] * [ORDER BY field [DESC]] * [LIMIT n] * [GROUP BY field COUNT|SUM|AVG|MIN|MAX] * [TRACE caused_by [REVERSE]] * [SEARCH "text"] * ``` */ query(nql: string): Promise[]>; /** * Like {@link query} but returns the full response including `seq` and `head`. */ queryFull(nql: string): Promise; /** * Turn a short English prompt into NQL, server-side. * * Requires a daemon built with `--features cast` and started with `--cast`. * Returns the full {@link CastResult} rather than rows, because the plan is * the point. * * `execute` defaults to `false` deliberately: the endpoint hands back a plan * for review. A planner that silently runs a wrong guess is worse than one * that admits uncertainty. Pass `{ execute: true }` to get `rows` and `count` * as well. * * Throws {@link NedbError} when the daemon lacks the feature (501), when the * model emits unparseable NQL (422), or when it names a collection this * database does not have (422). That last case is the model's known failure * mode on an unfamiliar schema, and it is reported explicitly rather than as * an empty result set — which would read as "no matching rows" and be a lie. * * @example * ```ts * const plan = await db.cast("orders over 100"); * // { nql: 'FROM orders WHERE total > 100', valid: true, * // collection_known: true, executed: false, ... } * * if (plan.valid && plan.collection_known) { * const rows = await db.query(plan.nql); // run it yourself, after looking * } * ``` */ cast(prompt: string, opts?: { execute?: boolean; }): Promise; /** Just the NQL string. Convenience wrapper over {@link cast}. */ castNql(prompt: string): Promise; /** * Run a batch of put/del operations in a single HTTP round-trip. * * @example * ```ts * await db.batch([ * { op: "put", coll: "blocks", id: "1", doc: { height: 1 } }, * { op: "del", coll: "blocks", id: "0" }, * ]); * ``` */ batch(ops: BatchOp[]): Promise; /** Create a sorted index on (coll, field) for fast ORDER BY queries. */ createIndex(coll: string, field: string, kind?: "sorted" | "eq"): Promise<{ ok: boolean; }>; /** Run a full BLAKE2b tamper-evidence check over all objects. */ verify(): Promise; /** Return the current BLAKE2b Merkle head of the database. */ head(): Promise; /** Return the current global sequence number. */ seq(): Promise; /** Trigger an explicit checkpoint (no-op on v2 DAG — always snapshotted). */ checkpoint(): Promise<{ ok: boolean; head: string; seq: number; }>; /** Return the last `limit` write operations. */ log(limit?: number): Promise[]>; /** Ping the server. Returns full health object. */ health(): Promise; /** Returns true if the server is reachable and healthy. */ ping(): Promise; /** List all database names on this server. */ listDatabases(): Promise; /** Explicitly create this database. Idempotent. */ createDatabase(): Promise; /** Drop this database and all its data. Irreversible. */ dropDatabase(): Promise; } export default NedbClient; //# sourceMappingURL=index.d.ts.map