@xcitedbs/client 0.2.12 → 0.2.13

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/dist/client.d.ts CHANGED
@@ -436,12 +436,18 @@ export declare class XCiteDBClient {
436
436
  queryLog(query: XCiteQuery, fromDate: string, toDate: string): Promise<LogEntry[]>;
437
437
  addMeta(identifier: string, value: unknown, path?: string, opts?: {
438
438
  mode?: 'set' | 'append';
439
+ overwrite?: boolean;
439
440
  }): Promise<boolean>;
440
441
  addMetaByQuery(query: XCiteQuery, value: unknown, path?: string, firstMatch?: boolean, opts?: {
441
442
  mode?: 'set' | 'append';
443
+ overwrite?: boolean;
444
+ }): Promise<boolean>;
445
+ appendMeta(identifier: string, value: unknown, path?: string, opts?: {
446
+ overwrite?: boolean;
447
+ }): Promise<boolean>;
448
+ appendMetaByQuery(query: XCiteQuery, value: unknown, path?: string, firstMatch?: boolean, opts?: {
449
+ overwrite?: boolean;
442
450
  }): Promise<boolean>;
443
- appendMeta(identifier: string, value: unknown, path?: string): Promise<boolean>;
444
- appendMetaByQuery(query: XCiteQuery, value: unknown, path?: string, firstMatch?: boolean): Promise<boolean>;
445
451
  queryMeta<T = MetaValue>(identifier: string, path?: string): Promise<T>;
446
452
  queryMetaByQuery<T = MetaValue>(query: XCiteQuery, path?: string): Promise<T>;
447
453
  clearMeta(query: XCiteQuery): Promise<boolean>;
@@ -517,12 +523,16 @@ export declare class XCiteDBClient {
517
523
  * The final event has `done: true` and may include `sources`.
518
524
  */
519
525
  ragQueryStream(options: Omit<RagQueryOptions, 'stream'>, onEvent: (ev: RagStreamEvent) => void): Promise<void>;
520
- writeJsonDocument(identifier: string, data: unknown): Promise<void>;
526
+ writeJsonDocument(identifier: string, data: unknown, opts?: {
527
+ overwrite?: boolean;
528
+ }): Promise<void>;
521
529
  readJsonDocument<T = unknown>(identifier: string): Promise<T>;
522
530
  deleteJsonDocument(identifier: string): Promise<void>;
523
531
  listJsonDocuments(match?: string, limit?: number, offset?: number): Promise<ListIdentifiersResult>;
524
532
  /** JSON document shorthand — same as {@link writeJsonDocument}. */
525
- put(identifier: string, data: unknown): Promise<void>;
533
+ put(identifier: string, data: unknown, opts?: {
534
+ overwrite?: boolean;
535
+ }): Promise<void>;
526
536
  /** JSON document read — same as {@link readJsonDocument}. */
527
537
  get<T = unknown>(identifier: string): Promise<T>;
528
538
  /** JSON document delete — same as {@link deleteJsonDocument}. */
package/dist/client.js CHANGED
@@ -1352,6 +1352,8 @@ class XCiteDBClient {
1352
1352
  const body = { identifier: this.isoPrefixId(identifier), value, path };
1353
1353
  if (opts?.mode === 'append')
1354
1354
  body.mode = 'append';
1355
+ if (opts?.overwrite)
1356
+ body.overwrite = true;
1355
1357
  const r = await this.request('POST', '/api/v1/meta', body);
1356
1358
  return r?.ok !== false;
1357
1359
  }
@@ -1364,14 +1366,16 @@ class XCiteDBClient {
1364
1366
  };
1365
1367
  if (opts?.mode === 'append')
1366
1368
  body.mode = 'append';
1369
+ if (opts?.overwrite)
1370
+ body.overwrite = true;
1367
1371
  const r = await this.request('POST', '/api/v1/meta', body);
1368
1372
  return r?.ok !== false;
1369
1373
  }
1370
- async appendMeta(identifier, value, path = '') {
1371
- return this.addMeta(identifier, value, path, { mode: 'append' });
1374
+ async appendMeta(identifier, value, path = '', opts) {
1375
+ return this.addMeta(identifier, value, path, { mode: 'append', ...opts });
1372
1376
  }
1373
- async appendMetaByQuery(query, value, path = '', firstMatch = false) {
1374
- return this.addMetaByQuery(query, value, path, firstMatch, { mode: 'append' });
1377
+ async appendMetaByQuery(query, value, path = '', firstMatch = false, opts) {
1378
+ return this.addMetaByQuery(query, value, path, firstMatch, { mode: 'append', ...opts });
1375
1379
  }
1376
1380
  async queryMeta(identifier, path = '') {
1377
1381
  return this.request('GET', `/api/v1/meta${buildQuery({ identifier: this.isoPrefixId(identifier), path })}`);
@@ -1654,8 +1658,11 @@ class XCiteDBClient {
1654
1658
  }
1655
1659
  throw new types_1.XCiteDBError('RAG stream failed after retry', 401, null);
1656
1660
  }
1657
- async writeJsonDocument(identifier, data) {
1658
- await this.request('POST', '/api/v1/json-documents', { identifier: this.isoPrefixId(identifier), data });
1661
+ async writeJsonDocument(identifier, data, opts) {
1662
+ const body = { identifier: this.isoPrefixId(identifier), data };
1663
+ if (opts?.overwrite)
1664
+ body.overwrite = true;
1665
+ await this.request('POST', '/api/v1/json-documents', body);
1659
1666
  }
1660
1667
  async readJsonDocument(identifier) {
1661
1668
  return this.request('GET', `/api/v1/json-documents${buildQuery({ identifier: this.isoPrefixId(identifier) })}`);
@@ -1684,8 +1691,8 @@ class XCiteDBClient {
1684
1691
  return { identifiers: [], total: 0, offset: 0, limit: 0 };
1685
1692
  }
1686
1693
  /** JSON document shorthand — same as {@link writeJsonDocument}. */
1687
- async put(identifier, data) {
1688
- return this.writeJsonDocument(identifier, data);
1694
+ async put(identifier, data, opts) {
1695
+ return this.writeJsonDocument(identifier, data, opts);
1689
1696
  }
1690
1697
  /** JSON document read — same as {@link readJsonDocument}. */
1691
1698
  async get(identifier) {
package/llms-full.txt CHANGED
@@ -452,14 +452,23 @@ Returns `{ parent_path, parent_is_identifier, children: [{ segment, full_path, i
452
452
 
453
453
  **`POST /api/v1/json-documents`**
454
454
 
455
+ JSON body fields:
456
+
457
+ | Field | Required | Meaning |
458
+ |-------|----------|---------|
459
+ | `identifier` | yes | Document path key |
460
+ | `data` | yes | JSON value to merge or store |
461
+ | `overwrite` | no (default `false`) | When `true`, delete all metadata under the document root first, then write `data` only. When `false`, **`data` is merged** into any existing document (nested objects combine fields; nested arrays follow meta merge rules—see Metadata). |
462
+
455
463
  ```json
456
464
  {
457
465
  "identifier": "app.settings",
458
- "data": { "theme": "dark", "maxUploadMb": 25 }
466
+ "data": { "theme": "dark", "maxUploadMb": 25 },
467
+ "overwrite": false
459
468
  }
460
469
  ```
461
470
 
462
- Note: The SDK method uses `identifier` and `data` fields. Some older documentation shows `key` and `value`.
471
+ Note: SDKs use `identifier` and `data` (optional `overwrite`). Some older documentation shows `key` and `value`.
463
472
 
464
473
  ## Read JSON document
465
474
 
@@ -503,15 +512,26 @@ Attach structured **JSON metadata** to documents or nodes.
503
512
 
504
513
  **`POST /api/v1/meta`**
505
514
 
515
+ | Field | Required | Meaning |
516
+ |-------|----------|---------|
517
+ | `identifier` **or** `query` | one required | Target document id or document query |
518
+ | `value` | yes | JSON to write (omit only for string-specific query batch paths handled by the server) |
519
+ | `path` | no (default `""`) | Meta path (dot-separated keys; `[i]` for array indices) |
520
+ | `mode` | no (default `"set"`) | `"set"` — write/replace at `path`. For **arrays** at `path`, indices `0..n-1` are written and any previous tail beyond the new length is cleared. `"append"` — for **arrays** at `path`, new elements are written after existing indices (extend in place). |
521
+ | `overwrite` | no (default `false`) | When `true`, delete existing metadata under `path` before applying `value`. |
522
+ | `first_match` | no | With `query`, only the first matching identifier is updated when `true`. |
523
+
506
524
  ```json
507
525
  {
508
526
  "identifier": "/book/ch1",
509
527
  "value": { "status": "review", "owner": "alice" },
510
- "path": ""
528
+ "path": "",
529
+ "mode": "set",
530
+ "overwrite": false
511
531
  }
512
532
  ```
513
533
 
514
- Optional `"mode": "append"` to append rather than overwrite.
534
+ Use `"mode": "append"` to extend arrays at `path` instead of replacing them.
515
535
 
516
536
  Can also use `"query"` instead of `"identifier"` to target multiple documents by query filter.
517
537
 
@@ -527,6 +547,12 @@ Can also use `"query"` instead of `"identifier"` to target multiple documents by
527
547
 
528
548
  **`DELETE /api/v1/meta`** — `{ "query": {...} }`
529
549
 
550
+ ## JSON metadata storage model (best practices)
551
+
552
+ - **Field-indexed objects.** Metadata and standalone JSON documents share the same shredded-key storage. **JSON objects** map to named paths so fields can be read or updated without loading a monolithic blob.
553
+ - **Dictionary threshold.** When the **set of distinct field names** on an object reaches the server threshold (default **32**, native setting `meta_dict_field_threshold`), XCiteDB switches that object to **dictionary storage** (`{*}` plus per-field keys) for scalable indexed access.
554
+ - **Modeling guidance.** Prefer stable **`{ "key": value, ... }`** / nested-object shapes for records you look up by key. Arrays are appropriate for ordered lists; use **`mode: "append"`** when appending to a stored array.
555
+
530
556
  ---
531
557
 
532
558
  # Search
@@ -1374,17 +1400,17 @@ interface DatabaseContext {
1374
1400
  - `queryLog(query, fromDate, toDate)` → `LogEntry[]`
1375
1401
 
1376
1402
  ### JSON Documents
1377
- - `writeJsonDocument(identifier, data)` → `void`
1403
+ - `writeJsonDocument(identifier, data, opts?)` → `void` — merge by default; `opts?.overwrite` replaces root
1378
1404
  - `readJsonDocument<T>(identifier)` → `T` (default `unknown`)
1379
1405
  - `deleteJsonDocument(identifier)` → `void`
1380
1406
  - `listJsonDocuments(match?, limit?, offset?)` → `ListIdentifiersResult`
1381
- - `put(identifier, data)` / `get<T>(identifier)` / `remove(identifier)` / `list(match?, limit?, offset?)` — JSON CRUD aliases
1407
+ - `put(identifier, data, opts?)` / `get<T>(identifier)` / `remove(identifier)` / `list(match?, limit?, offset?)` — JSON CRUD aliases (`opts` same as `writeJsonDocument`)
1382
1408
 
1383
1409
  ### Metadata
1384
- - `addMeta(identifier, value, path?, opts?)` → `boolean`
1410
+ - `addMeta(identifier, value, path?, opts?)` → `boolean` — `opts`: `mode?: 'set'|'append'`, `overwrite?: boolean`
1385
1411
  - `addMetaByQuery(query, value, path?, firstMatch?, opts?)` → `boolean`
1386
- - `appendMeta(identifier, value, path?)` → `boolean`
1387
- - `appendMetaByQuery(query, value, path?, firstMatch?)` → `boolean`
1412
+ - `appendMeta(identifier, value, path?, opts?)` → `boolean` — same as `addMeta` with `mode: 'append'`
1413
+ - `appendMetaByQuery(query, value, path?, firstMatch?, opts?)` → `boolean`
1388
1414
  - `queryMeta<T>(identifier, path?)` → `T`
1389
1415
  - `queryMetaByQuery<T>(query, path?)` → `T`
1390
1416
  - `clearMeta(query)` → `boolean`
package/llms.txt CHANGED
@@ -111,6 +111,12 @@ await app.writeJsonDocument('userdata/alice/profile', { ok: true });
111
111
  4. **Cleanup:** `DELETE /api/v1/test/sessions/current` with `X-Test-Session` (no other auth), or `DELETE /api/v1/test/sessions/all` / `DELETE /api/v1/test/sessions/{token}` with normal auth for the owning key or JWT.
112
112
  5. **SDKs:** **JS/TS:** `XCiteDBClient.createTestSession({ baseUrl, apiKey, … })`, optional `overlay: true`, optional `testRequireAuth`, then `destroyTestSession()`. **Python:** `async with XCiteDBClient.test_session(...)` or provision with **`POST /api/v1/test/sessions`** and JSON **`{"overlay":true}`** when you need overlay, then pass `test_session_token` / `test_require_auth` to the constructor. **C++:** `XCiteDBClient::create_test_session(options)` with optional `test_session_overlay = true`, `destroy_test_session()`, optional `test_require_auth` in options.
113
113
 
114
+ ## JSON documents and metadata (merge, overwrite, efficiency)
115
+
116
+ - **JSON documents merge by default.** `POST /api/v1/json-documents` merges the posted `data` into the existing document (object fields combined per XCiteDB meta merge rules). Send **`overwrite: true`** to clear all stored JSON under that document root first, then write only the new payload. SDKs accept the same flag (e.g. `writeJsonDocument(id, data, { overwrite: true })` in JavaScript).
117
+ - **Metadata `mode` and arrays.** **`POST /api/v1/meta`** uses **`mode`**: default **`set`** writes or replaces at `path` (arrays are replaced in range; excess old indices cleared); **`append`** appends array elements after existing ones at `path`. Optional **`overwrite: true`** clears metadata under `path` before writing. JavaScript: **`appendMeta`** or **`addMeta(..., { mode: 'append' })`**; Python/C++: **`append_meta`** or **`add_meta`** with **`mode`** / **`overwrite`** (see SDK sections below).
118
+ - **Prefer dictionary-style objects.** Shredded JSON metadata is keyed by field names. **Object maps** get per-field storage; when an object accumulates enough distinct field names (server default threshold **32**), XCiteDB switches automatically to **dictionary storage** (`{*}` plus per-field keys) for efficient indexed access. For lookup-heavy or wide records, use **`{ "key": value, ... }`** shapes (or one document per logical row) rather than opaque arrays when you need keyed reads.
119
+
114
120
  ## JavaScript/TypeScript SDK (`@xcitedbs/client`)
115
121
 
116
122
  Install: `npm install @xcitedbs/client`
@@ -232,15 +238,15 @@ interface XCiteDBClientOptions {
232
238
  - `listIdentifierChildren(parentPath?)` — Navigate identifier hierarchy
233
239
 
234
240
  **JSON Documents:**
235
- - `writeJsonDocument(identifier, data)` — Store a JSON document
241
+ - `writeJsonDocument(identifier, data, opts?)` — Store or merge a JSON document (`opts?.overwrite` replaces entire document root)
236
242
  - `readJsonDocument(identifier)` — Read a JSON document (generic `readJsonDocument<T>()` supported)
237
243
  - `deleteJsonDocument(identifier)` — Delete a JSON document
238
244
  - `listJsonDocuments(match?, limit?, offset?)` — List JSON document keys
239
245
  - **Quick JSON aliases:** `put`, `get`, `remove`, `list` — same as the four methods above
240
246
 
241
247
  **Metadata (JSON on XML):**
242
- - `addMeta(identifier, value, path?)` — Set metadata on a document
243
- - `appendMeta(identifier, value, path?)` — Append to metadata
248
+ - `addMeta(identifier, value, path?, opts?)` — Set or append metadata (`opts?.mode`: `set`|`append`; `opts?.overwrite`)
249
+ - `appendMeta(identifier, value, path?, opts?)` — Append at `path` (same as `addMeta` with `mode: 'append'`)
244
250
  - `queryMeta(identifier, path?)` — Read metadata
245
251
  - `clearMeta(query)` — Remove metadata
246
252
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xcitedbs/client",
3
- "version": "0.2.12",
3
+ "version": "0.2.13",
4
4
  "description": "XCiteDB BaaS client SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",