zydecodb 0.9.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # ZydecoDB TypeScript / Node driver
2
+
3
+ Official TypeScript/Node client for [ZydecoDB](../../README.md) — a MongoDB-style
4
+ document store without the fluff. Built on Node's standard library (`node:net`),
5
+ no runtime dependencies.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install zydecodb
11
+ ```
12
+
13
+ Requires Node.js 20+. (Working from a checkout of this repo:
14
+ `npm install file:clients/typescript`.)
15
+
16
+ ## Quick start
17
+
18
+ ```ts
19
+ import { Client } from "zydecodb";
20
+
21
+ // Plain TCP (localhost). For TLS: { apiKey: "YOUR_KEY", tls: true }
22
+ const db = new Client("127.0.0.1:9470", { apiKey: "YOUR_KEY" });
23
+ try {
24
+ const users = db.collection("users");
25
+ await users.createIndex(["email"], true);
26
+
27
+ const id = await users.insertOne({ email: "ada@example.com", name: "Ada", age: 30 });
28
+
29
+ const adults = await users.find({ age: { $gte: 18 } }, { sort: [{ field: "age", ascending: true }] });
30
+ for (const u of adults) console.log(u.name, u.age);
31
+
32
+ await users.updateOne({ _id: id }, { $inc: { age: 1 } });
33
+ console.log(await users.countDocuments());
34
+ } finally {
35
+ db.close();
36
+ }
37
+ ```
38
+
39
+ ## What you get
40
+
41
+ - **Connection pooling.** `Client` owns a bounded pool (`poolSize`, default 8)
42
+ and is safe to share across the whole process.
43
+ - **Automatic retries with backoff.** Transient transport failures and server
44
+ `EngineBusy` responses are retried (full-jitter exponential backoff) for
45
+ operations that are safe to repeat. Operator updates and deletes are never
46
+ retried automatically.
47
+ - **Keepalive.** Idle pooled connections are validated with a `ping` on
48
+ checkout and transparently replaced if dead.
49
+ - **Typed error taxonomy.** Non-OK responses throw a specific subclass:
50
+ `ConflictError` (unique-index violation), `AuthError`, `ServerBusyError`,
51
+ `InvalidRequestError`, or the base `ServerError` — each carrying the wire
52
+ `status` byte. Transport problems throw `ConnectionError`.
53
+ - **MongoDB-style `Collection` API.** `insertOne/Many`, `find`/`findOne`,
54
+ `updateOne/Many`, `deleteOne/Many`, `countDocuments`, `distinct`, and
55
+ `createIndex`, with `$`-operators, sort, projection, and skip/limit.
56
+ Pagination is repeatable-read across pages.
57
+ - **Raw KV with TTL.** Side-channel `put` (with `expiresAt`), `get`, and `delete` methods on `Client` for session data that needs a time-to-live.
58
+ - **TLS.** Pass `tls: true` for system CA defaults, or a `tls.ConnectionOptions`
59
+ object for custom roots / SNI / `rejectUnauthorized`.
60
+
61
+ ## Durability
62
+
63
+ Writes are durable (fsync-on-commit) by default. For latency-sensitive,
64
+ loss-tolerant writes, pass `relaxed = true` on any write to acknowledge before
65
+ the fsync.
66
+
67
+ ```ts
68
+ await users.insertOne(doc, true);
69
+ await users.updateOne({ _id: "ada" }, { $inc: { hits: 1 } }, true);
70
+ ```
71
+
72
+ ## Examples
73
+
74
+ - [`examples/quickstart.ts`](examples/quickstart.ts) — end-to-end collection demo.
75
+ - [`examples/user_backend.ts`](examples/user_backend.ts) — a small `node:http`
76
+ users API sharing one pooled client across concurrent requests.
77
+
78
+ With Node 22.18+ you can run the TypeScript directly:
79
+
80
+ ```bash
81
+ node examples/quickstart.ts
82
+ node examples/user_backend.ts
83
+ ```
84
+
85
+ Both read `ZYDECODB_ADDR` (default `127.0.0.1:9470`) and `ZYDECODB_API_KEY`.
86
+
87
+ ## Development
88
+
89
+ ```bash
90
+ npm install # dev deps: typescript, @types/node
91
+ npm run typecheck # tsc --noEmit
92
+ npm run build # emit dist/ (ESM + .d.ts)
93
+ npm test # node --test (native type stripping; no transpiler)
94
+ ```
95
+
96
+ The codec is verified byte-for-byte against the shared
97
+ [conformance vectors](../conformance) — no server required. The live
98
+ integration tests run against a server selected by `ZYDECODB_TEST_HOST` /
99
+ `ZYDECODB_TEST_PORT` (and optional `ZYDECODB_TEST_API_KEY`) and are skipped when
100
+ it is unreachable.
@@ -0,0 +1,62 @@
1
+ import { Collection } from "./collection.ts";
2
+ import { type Projection, type SortKey } from "./protocol.ts";
3
+ export interface ClientOptions {
4
+ apiKey?: string;
5
+ /** Per-request I/O timeout in ms (default 5000). */
6
+ timeoutMs?: number;
7
+ /** Maximum pooled connections (default 8). */
8
+ poolSize?: number;
9
+ /** Retries for idempotent operations on transient failures (default 2). */
10
+ maxRetries?: number;
11
+ backoffBaseMs?: number;
12
+ backoffCapMs?: number;
13
+ }
14
+ export interface FindOptions {
15
+ sort?: SortKey[];
16
+ projection?: Projection;
17
+ skip?: number;
18
+ limit?: number;
19
+ pageSize?: number;
20
+ }
21
+ export interface UpdateResult {
22
+ matched: number;
23
+ modified: number;
24
+ }
25
+ /**
26
+ * A pooled, retrying ZydecoDB client. Safe to share across the whole process.
27
+ * Transient transport failures and server EngineBusy responses are retried with
28
+ * full-jitter exponential backoff for operations that are safe to repeat;
29
+ * operator updates and deletes are never retried automatically.
30
+ */
31
+ export declare class Client {
32
+ private readonly pool;
33
+ private readonly maxRetries;
34
+ private readonly backoffBaseMs;
35
+ private readonly backoffCapMs;
36
+ constructor(address?: string, options?: ClientOptions);
37
+ close(): void;
38
+ private backoff;
39
+ private execute;
40
+ ping(): Promise<void>;
41
+ stats(): Promise<Record<string, unknown>>;
42
+ get(key: Buffer): Promise<Buffer | null>;
43
+ put(key: Buffer, value: Buffer, expiresAt?: number | bigint): Promise<bigint>;
44
+ delete(key: Buffer): Promise<boolean>;
45
+ defineIndex(collection: string, index: string, fields: string[], unique: boolean, ifNotExists?: boolean): Promise<boolean>;
46
+ putDocument(collection: string, docId: string, body: Buffer, relaxed: boolean): Promise<bigint>;
47
+ deleteDocument(collection: string, docId: string): Promise<boolean>;
48
+ getDocument(collection: string, docId: string): Promise<Buffer | null>;
49
+ /** Returns the raw JSON bodies of matching documents, auto-paginating. */
50
+ find(collection: string, filter: Buffer, opts?: FindOptions): Promise<Buffer[]>;
51
+ update(collection: string, filter: Buffer, update: Buffer, multi: boolean, relaxed: boolean): Promise<UpdateResult>;
52
+ deleteByFilter(collection: string, filter: Buffer, multi: boolean, relaxed: boolean): Promise<number>;
53
+ count(collection: string, filter: Buffer): Promise<number>;
54
+ distinct(collection: string, field: string, filter: Buffer): Promise<unknown[]>;
55
+ collection(name: string): Collection;
56
+ }
57
+ /**
58
+ * A time-ordered id (UUIDv7-style): a 48-bit millisecond timestamp followed by
59
+ * 80 random bits, hex-encoded. Sorts lexicographically by creation time.
60
+ */
61
+ export declare function generateId(): string;
62
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js ADDED
@@ -0,0 +1,202 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { Collection } from "./collection.js";
3
+ import { ConnectionError, fromStatus, ServerBusyError, ZydecoError } from "./errors.js";
4
+ import { ConnectionPool } from "./pool.js";
5
+ import { Cmd, decodePage, encodeCount, encodeDelete, encodeDistinct, encodeDocDel, encodeDocPut, encodeFind, encodeIndexDef, encodeQueryById, encodeUpdate, encodePut, encodeKey, Proj, Status, } from "./protocol.js";
6
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
7
+ /**
8
+ * A pooled, retrying ZydecoDB client. Safe to share across the whole process.
9
+ * Transient transport failures and server EngineBusy responses are retried with
10
+ * full-jitter exponential backoff for operations that are safe to repeat;
11
+ * operator updates and deletes are never retried automatically.
12
+ */
13
+ export class Client {
14
+ pool;
15
+ maxRetries;
16
+ backoffBaseMs;
17
+ backoffCapMs;
18
+ constructor(address = "127.0.0.1:9470", options = {}) {
19
+ const { host, port } = parseAddress(address);
20
+ this.pool = new ConnectionPool({
21
+ host,
22
+ port,
23
+ apiKey: options.apiKey ?? null,
24
+ timeoutMs: options.timeoutMs ?? 5000,
25
+ maxSize: options.poolSize ?? 8,
26
+ });
27
+ this.maxRetries = Math.max(0, options.maxRetries ?? 2);
28
+ this.backoffBaseMs = options.backoffBaseMs ?? 50;
29
+ this.backoffCapMs = options.backoffCapMs ?? 2000;
30
+ }
31
+ close() {
32
+ this.pool.close();
33
+ }
34
+ backoff(attempt) {
35
+ const ceiling = Math.min(this.backoffCapMs, this.backoffBaseMs * 2 ** attempt);
36
+ return Math.random() * ceiling;
37
+ }
38
+ async execute(command, payload, op, eo) {
39
+ let lastErr = null;
40
+ for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
41
+ const conn = await this.pool.acquire();
42
+ let res;
43
+ try {
44
+ res = await conn.request(command, payload);
45
+ }
46
+ catch (err) {
47
+ this.pool.discard(conn);
48
+ lastErr = err;
49
+ if (eo.retryable && attempt < this.maxRetries) {
50
+ await sleep(this.backoff(attempt));
51
+ continue;
52
+ }
53
+ throw err;
54
+ }
55
+ this.pool.release(conn);
56
+ if (res.status === Status.Ok)
57
+ return res.body;
58
+ if (eo.notFoundNull && res.status === Status.NotFound)
59
+ return null;
60
+ if (res.status === Status.EngineBusy && eo.retryable && attempt < this.maxRetries) {
61
+ console.warn(`[Client] EngineBusy on ${op}, attempt ${attempt}`);
62
+ lastErr = new ServerBusyError(op, res.status, "");
63
+ await sleep(this.backoff(attempt));
64
+ continue;
65
+ }
66
+ throw fromStatus(res.status, op, res.body);
67
+ }
68
+ throw lastErr ?? new ZydecoError(`${op}: retries exhausted`);
69
+ }
70
+ // --- health / introspection ---
71
+ async ping() {
72
+ await this.execute(Cmd.Ping, Buffer.alloc(0), "Ping", { retryable: true });
73
+ }
74
+ async stats() {
75
+ const body = await this.execute(Cmd.Stats, Buffer.alloc(0), "Stats", { retryable: true });
76
+ return JSON.parse(body.toString("utf8"));
77
+ }
78
+ // --- document layer (raw bytes; Collection adds JSON ergonomics) ---
79
+ async get(key) {
80
+ return this.execute(Cmd.Get, encodeKey(key), "Get", { retryable: true, notFoundNull: true });
81
+ }
82
+ async put(key, value, expiresAt = 0) {
83
+ const out = await this.execute(Cmd.Put, encodePut(key, value, expiresAt), "Put", { retryable: true });
84
+ return decodeU64(out, "Put");
85
+ }
86
+ async delete(key) {
87
+ const out = await this.execute(Cmd.Del, encodeKey(key), "Delete", { retryable: false });
88
+ return out !== null && out.length > 0 && out[0] !== 0;
89
+ }
90
+ async defineIndex(collection, index, fields, unique, ifNotExists = true) {
91
+ const payload = encodeIndexDef(collection, index, fields, unique);
92
+ const conn = await this.pool.acquire();
93
+ let res;
94
+ try {
95
+ res = await conn.request(Cmd.IndexDef, payload);
96
+ }
97
+ catch (err) {
98
+ this.pool.discard(conn);
99
+ throw err;
100
+ }
101
+ this.pool.release(conn);
102
+ if (ifNotExists && res.status === Status.Conflict)
103
+ return false;
104
+ if (res.status !== Status.Ok)
105
+ throw fromStatus(res.status, "IndexDef", res.body);
106
+ return true;
107
+ }
108
+ async putDocument(collection, docId, body, relaxed) {
109
+ const out = await this.execute(Cmd.DocPut, encodeDocPut(collection, Buffer.from(docId, "utf8"), body, relaxed), "DocPut", { retryable: true });
110
+ return decodeU64(out, "DocPut");
111
+ }
112
+ async deleteDocument(collection, docId) {
113
+ const out = await this.execute(Cmd.DocDel, encodeDocDel(collection, Buffer.from(docId, "utf8")), "DocDel", { retryable: false });
114
+ return out !== null && out.length > 0 && out[0] !== 0;
115
+ }
116
+ async getDocument(collection, docId) {
117
+ return this.execute(Cmd.Query, encodeQueryById(collection, Buffer.from(docId, "utf8")), "Query", { retryable: true, notFoundNull: true });
118
+ }
119
+ /** Returns the raw JSON bodies of matching documents, auto-paginating. */
120
+ async find(collection, filter, opts = {}) {
121
+ const pageSize = opts.pageSize && opts.pageSize > 0 ? opts.pageSize : 100;
122
+ const limit = opts.limit ?? 0;
123
+ const projection = opts.projection ?? { mode: Proj.None, fields: [] };
124
+ const sort = opts.sort ?? [];
125
+ let skip = opts.skip ?? 0;
126
+ let cursor = Buffer.alloc(0);
127
+ let yielded = 0;
128
+ const results = [];
129
+ for (;;) {
130
+ let want = pageSize;
131
+ if (limit !== 0) {
132
+ const remaining = limit - yielded;
133
+ if (remaining <= 0)
134
+ return results;
135
+ want = Math.min(want, remaining);
136
+ }
137
+ const payload = encodeFind(collection, filter, sort, projection, skip, want, cursor);
138
+ const body = await this.execute(Cmd.Find, payload, "Find", { retryable: true });
139
+ const page = decodePage(body);
140
+ skip = 0; // applied on the first page; the cursor carries it onward
141
+ for (const row of page.rows) {
142
+ results.push(row.body);
143
+ yielded++;
144
+ if (limit !== 0 && yielded >= limit)
145
+ return results;
146
+ }
147
+ if (page.cursor === null)
148
+ return results;
149
+ cursor = page.cursor;
150
+ }
151
+ }
152
+ async update(collection, filter, update, multi, relaxed) {
153
+ const body = await this.execute(Cmd.Update, encodeUpdate(collection, filter, update, multi, relaxed), "Update", { retryable: false });
154
+ return JSON.parse(body.toString("utf8"));
155
+ }
156
+ async deleteByFilter(collection, filter, multi, relaxed) {
157
+ const body = await this.execute(Cmd.Delete, encodeDelete(collection, filter, multi, relaxed), "Delete", { retryable: false });
158
+ return JSON.parse(body.toString("utf8")).deleted;
159
+ }
160
+ async count(collection, filter) {
161
+ const body = await this.execute(Cmd.Count, encodeCount(collection, filter), "Count", {
162
+ retryable: true,
163
+ });
164
+ return JSON.parse(body.toString("utf8"));
165
+ }
166
+ async distinct(collection, field, filter) {
167
+ const body = await this.execute(Cmd.Count, encodeDistinct(collection, filter, field), "Distinct", { retryable: true });
168
+ return JSON.parse(body.toString("utf8"));
169
+ }
170
+ collection(name) {
171
+ return new Collection(this, name);
172
+ }
173
+ }
174
+ /**
175
+ * A time-ordered id (UUIDv7-style): a 48-bit millisecond timestamp followed by
176
+ * 80 random bits, hex-encoded. Sorts lexicographically by creation time.
177
+ */
178
+ export function generateId() {
179
+ const buf = Buffer.alloc(16);
180
+ const ms = BigInt(Date.now()) & ((1n << 48n) - 1n);
181
+ buf.writeUIntBE(Number(ms), 0, 6);
182
+ randomBytes(10).copy(buf, 6);
183
+ return buf.toString("hex");
184
+ }
185
+ function parseAddress(address) {
186
+ const idx = address.lastIndexOf(":");
187
+ if (idx < 0)
188
+ throw new ZydecoError(`invalid address ${address}: expected host:port`);
189
+ const host = address.slice(0, idx) || "127.0.0.1";
190
+ const port = Number(address.slice(idx + 1));
191
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) {
192
+ throw new ZydecoError(`invalid port in address ${address}`);
193
+ }
194
+ return { host, port };
195
+ }
196
+ function decodeU64(body, op) {
197
+ if (!body || body.length !== 8) {
198
+ throw new ZydecoError(`${op}: expected 8-byte sequence, got ${body?.length ?? 0}`);
199
+ }
200
+ return body.readBigUInt64BE(0);
201
+ }
202
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { Client, UpdateResult } from "./client.ts";
2
+ import { type SortKey } from "./protocol.ts";
3
+ /** A JSON document. The "_id" field is the document's string primary key. */
4
+ export type Document = Record<string, unknown>;
5
+ export interface QueryOptions {
6
+ sort?: SortKey[];
7
+ /** Include only these fields (mutually exclusive with `exclude`). */
8
+ include?: string[];
9
+ /** Exclude these fields. */
10
+ exclude?: string[];
11
+ skip?: number;
12
+ limit?: number;
13
+ pageSize?: number;
14
+ }
15
+ /**
16
+ * The product surface: a MongoDB-inspired collection of JSON documents over the
17
+ * binary client. Filters and updates use the familiar $-operators; the server
18
+ * plans the access path and re-checks the full filter.
19
+ */
20
+ export declare class Collection {
21
+ private readonly client;
22
+ readonly name: string;
23
+ constructor(client: Client, name: string);
24
+ /**
25
+ * Create a secondary index over one or more dotted field paths. Returns false
26
+ * if the index already existed.
27
+ */
28
+ createIndex(fields: string[], unique?: boolean): Promise<boolean>;
29
+ /** Insert a document, generating "_id" if absent. Returns the id. */
30
+ insertOne(document: Document, relaxed?: boolean): Promise<string>;
31
+ insertMany(documents: Document[]): Promise<string[]>;
32
+ /** Insert or fully replace the document at docId. */
33
+ replaceOne(docId: string, document: Document, relaxed?: boolean): Promise<bigint>;
34
+ updateOne(filter: Document, update: Document, relaxed?: boolean): Promise<UpdateResult>;
35
+ updateMany(filter: Document, update: Document, relaxed?: boolean): Promise<UpdateResult>;
36
+ deleteOne(filter: Document, relaxed?: boolean): Promise<number>;
37
+ deleteMany(filter: Document, relaxed?: boolean): Promise<number>;
38
+ /** Return all matching documents, decoded as objects. */
39
+ find(filter: Document | null, opts?: QueryOptions): Promise<Document[]>;
40
+ /** Return the first matching document, or null if none match. */
41
+ findOne(filter: Document | null, opts?: QueryOptions): Promise<Document | null>;
42
+ /** Fetch one document directly by id (fast path), or null if absent. */
43
+ get(docId: string): Promise<Document | null>;
44
+ countDocuments(filter?: Document | null): Promise<number>;
45
+ distinct(field: string, filter?: Document | null): Promise<unknown[]>;
46
+ }
47
+ //# sourceMappingURL=collection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGxD,OAAO,EAAyB,KAAK,OAAO,EAAE,MAAM,eAAe,CAAC;AAEpE,6EAA6E;AAC7E,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID;;;;GAIG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAKxC;;;OAGG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/D,qEAAqE;IAC/D,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAO/D,UAAU,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAM1D,qDAAqD;IACrD,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAK/E,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,YAAY,CAAC;IAIrF,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,YAAY,CAAC;IAItF,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7D,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAI9D,yDAAyD;IACnD,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAWjF,iEAAiE;IAC3D,OAAO,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAKzF,wEAAwE;IAClE,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAKlD,cAAc,CAAC,MAAM,GAAE,QAAQ,GAAG,IAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAI/D,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,QAAQ,GAAG,IAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAG5E"}
@@ -0,0 +1,102 @@
1
+ import { generateId } from "./client.js";
2
+ import { ZydecoError } from "./errors.js";
3
+ import { Proj } from "./protocol.js";
4
+ const EMPTY = Buffer.alloc(0);
5
+ /**
6
+ * The product surface: a MongoDB-inspired collection of JSON documents over the
7
+ * binary client. Filters and updates use the familiar $-operators; the server
8
+ * plans the access path and re-checks the full filter.
9
+ */
10
+ export class Collection {
11
+ client;
12
+ name;
13
+ constructor(client, name) {
14
+ this.client = client;
15
+ this.name = name;
16
+ }
17
+ /**
18
+ * Create a secondary index over one or more dotted field paths. Returns false
19
+ * if the index already existed.
20
+ */
21
+ createIndex(fields, unique = false) {
22
+ const indexName = "by_" + fields.map((f) => f.replaceAll(".", "_")).join("_");
23
+ return this.client.defineIndex(this.name, indexName, fields, unique);
24
+ }
25
+ /** Insert a document, generating "_id" if absent. Returns the id. */
26
+ async insertOne(document, relaxed = false) {
27
+ const id = typeof document._id === "string" && document._id ? document._id : generateId();
28
+ const doc = { ...document, _id: id };
29
+ await this.client.putDocument(this.name, id, jsonBytes(doc), relaxed);
30
+ return id;
31
+ }
32
+ async insertMany(documents) {
33
+ const ids = [];
34
+ for (const d of documents)
35
+ ids.push(await this.insertOne(d));
36
+ return ids;
37
+ }
38
+ /** Insert or fully replace the document at docId. */
39
+ replaceOne(docId, document, relaxed = false) {
40
+ const doc = { ...document, _id: docId };
41
+ return this.client.putDocument(this.name, docId, jsonBytes(doc), relaxed);
42
+ }
43
+ updateOne(filter, update, relaxed = false) {
44
+ return this.client.update(this.name, filterBytes(filter), jsonBytes(update), false, relaxed);
45
+ }
46
+ updateMany(filter, update, relaxed = false) {
47
+ return this.client.update(this.name, filterBytes(filter), jsonBytes(update), true, relaxed);
48
+ }
49
+ deleteOne(filter, relaxed = false) {
50
+ return this.client.deleteByFilter(this.name, filterBytes(filter), false, relaxed);
51
+ }
52
+ deleteMany(filter, relaxed = false) {
53
+ return this.client.deleteByFilter(this.name, filterBytes(filter), true, relaxed);
54
+ }
55
+ /** Return all matching documents, decoded as objects. */
56
+ async find(filter, opts = {}) {
57
+ const bodies = await this.client.find(this.name, filterBytes(filter), {
58
+ sort: opts.sort,
59
+ projection: projection(opts),
60
+ skip: opts.skip,
61
+ limit: opts.limit,
62
+ pageSize: opts.pageSize,
63
+ });
64
+ return bodies.map((b) => (b.length ? JSON.parse(b.toString("utf8")) : {}));
65
+ }
66
+ /** Return the first matching document, or null if none match. */
67
+ async findOne(filter, opts = {}) {
68
+ const docs = await this.find(filter, { ...opts, limit: 1 });
69
+ return docs.length ? docs[0] : null;
70
+ }
71
+ /** Fetch one document directly by id (fast path), or null if absent. */
72
+ async get(docId) {
73
+ const body = await this.client.getDocument(this.name, docId);
74
+ return body === null ? null : JSON.parse(body.toString("utf8"));
75
+ }
76
+ countDocuments(filter = null) {
77
+ return this.client.count(this.name, filterBytes(filter));
78
+ }
79
+ distinct(field, filter = null) {
80
+ return this.client.distinct(this.name, field, filterBytes(filter));
81
+ }
82
+ }
83
+ function projection(opts) {
84
+ if (opts.include?.length && opts.exclude?.length) {
85
+ throw new ZydecoError("projection cannot mix include and exclude fields");
86
+ }
87
+ if (opts.include?.length)
88
+ return { mode: Proj.Include, fields: opts.include };
89
+ if (opts.exclude?.length)
90
+ return { mode: Proj.Exclude, fields: opts.exclude };
91
+ return { mode: Proj.None, fields: [] };
92
+ }
93
+ function jsonBytes(value) {
94
+ return Buffer.from(JSON.stringify(value), "utf8");
95
+ }
96
+ /** A nil/empty filter is "match all" (empty bytes on the wire). */
97
+ function filterBytes(filter) {
98
+ if (!filter || Object.keys(filter).length === 0)
99
+ return EMPTY;
100
+ return jsonBytes(filter);
101
+ }
102
+ //# sourceMappingURL=collection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collection.js","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /** A decoded response: a status byte and (possibly empty) payload. */
2
+ export interface Response {
3
+ status: number;
4
+ body: Buffer;
5
+ }
6
+ /**
7
+ * A single TCP connection to a ZydecoDB server. Safe for concurrent use:
8
+ * requests are pipelined. The writer queue respects OS backpressure (drain),
9
+ * and the reader loop continuously consumes frames to resolve promises in FIFO order.
10
+ */
11
+ export declare class Connection {
12
+ private socket;
13
+ private inFlight;
14
+ private writeQueue;
15
+ private writing;
16
+ private dead;
17
+ lastUsed: number;
18
+ private readonly host;
19
+ private readonly port;
20
+ private readonly timeoutMs;
21
+ private readonly apiKey;
22
+ constructor(host: string, port: number, timeoutMs: number, apiKey: string | null);
23
+ get connected(): boolean;
24
+ connect(): Promise<void>;
25
+ private lastError;
26
+ private sessionInit;
27
+ /** Send one framed request and resolve with the framed response. */
28
+ request(command: number, payload?: Buffer): Promise<Response>;
29
+ private pumpWrites;
30
+ private readLoop;
31
+ /** Tear down the connection and reject any in-flight requests. */
32
+ private fail;
33
+ close(): void;
34
+ /** Send a keepalive; resolves true if the server answered OK. */
35
+ ping(): Promise<boolean>;
36
+ }
37
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAMA,sEAAsE;AACtE,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAaD;;;;GAIG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,IAAI,CAAS;IACrB,QAAQ,SAAK;IAEb,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAE3B,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAOhF,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA+BxB,OAAO,CAAC,SAAS;YAIH,WAAW;IAOzB,oEAAoE;IACpE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAwB,GAAG,OAAO,CAAC,QAAQ,CAAC;YAkBhE,UAAU;YAgCV,QAAQ;IAgCtB,kEAAkE;IAClE,OAAO,CAAC,IAAI;IAeZ,KAAK,IAAI,IAAI;IAQb,iEAAiE;IAC3D,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;CAQ/B"}