# JavaScript client for Node.js Use the dependency-free ES module at `clients/javascript/ratdb.mjs` from a Node backend with access to the database's loopback listener. Copy the file beside your application or import it by its repository path. Web browsers do not expose raw TCP sockets. The client authenticates with the same local administrator as the shell. ```js import { Client } from "./ratdb.mjs"; const db = await Client.connect({password: process.env.RATDB_PASSWORD}); try { await db.selectWarren("garage"); await db.selectDen("cars"); await db.put("car:001", {make: "Ford"}); let after = null; do { const page = await db.page(20, after, {field: "make", value: "Ford"}); for (const car of page.documents) console.log(car.id); after = page.next_after; } while (after !== null); } finally { db.close(); } ``` Provide the password through your process's credential handling. The connection options default to username `admin`, host `127.0.0.1`, port `7337` and timeoutMs `30000`. Use a numeric loopback address. For a remote database, forward its listener through an authenticated SSH tunnel and connect to the local port. | Method | Behavior | |---|---| | `selectWarren(name)`, `selectDen(name)` | Set context on this connection. Select a den after selecting a warren. | | `insert(id, object)`, `put(id, object)` | Insert requires a new ID. Put inserts or replaces the entire object. | | `get(id)`, `update(id, fields)`, `delete(id)` | Get returns the document or null. Update replaces the specified top-level fields. | | `find(field, value)`, `scan()` | Return the bounded protocol result including documents and truncation metadata. | | `page(limit, after, filter)` | Request 1–100 documents ordered by ID. Pass the returned cursor with the same filter and namespace until it is null. Pages see current committed data. | | `getVersioned(id)`, `transaction(generation, changes)` | The development server returns a document and its instance generation together. Send explicit put/delete operations across namespaces against that generation. Another committed write can cause a generation conflict. | | `close()` | Close the socket. Each worker or concurrent operation needs a separate client. | ```js const snapshot = await db.getVersioned("car:001"); await db.transaction(snapshot.generation, [ {op: "put", warren: "garage", den: "notes", id: "service:001", document: {car_id: "car:001", text: "Inspected"}} ]); ``` Await every operation before using the same session again. An overlapping request is rejected locally. The client accepts JSON documents. Use strings for exact large integers or decimal quantities. JavaScript uses binary64 numbers and the client rejects nonfinite numbers and integer values outside the safe range. JSON encoding runs before the outgoing byte-size check, so bound application inputs before constructing large objects. Authentication frames cap at 8 KiB and other frames at 1 MiB. The receiver checks the announced length before allocating the body. The deadline spans the entire exchange even when a peer keeps sending fragments. Authentication failure, incomplete frames, malformed response envelopes, transport errors and timeouts close the socket. If a mutation's reply was lost, reconnect and inspect the relevant records before deciding whether to retry. `RatDBError.code` exposes server errors. An operation failure or generation conflict leaves the session usable. Run the tests against a freshly built development binary: ```sh cargo build --locked --release -p ratdb-cli node scripts/js_client_test.mjs target/release/ratdb ``` On Windows, append `.exe` to the executable path. The tests use temporary files and ephemeral loopback ports. Tests passed on Windows x86-64 using Node 24.13.0 and the GNU Rust release build. The WSL Linux environment did not have a Node executable. The development-only transaction operations require a server that implements them. [Protocol reference](PROTOCOL.md)