@xcitedbs/client 0.2.17 → 0.2.18

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
@@ -422,10 +422,13 @@ export declare class XCiteDBClient {
422
422
  /**
423
423
  * Write an **XML** document using a JSON request body (`xml` field). The identifier is taken from `db:identifier` on the root element.
424
424
  * For storing JSON data by key, use `writeJsonDocument`.
425
+ *
426
+ * On cooperative-lock conflict the server returns **423** with a {@link LockConflictBody} shape in {@link XCiteDBError.body}.
425
427
  */
426
428
  writeXmlDocument(xml: string, options?: WriteDocumentOptions): Promise<void>;
427
429
  /**
428
430
  * Best-effort batch XML writes (`POST /api/v1/documents/batch`). Each item is independent; check `results[].ok`.
431
+ * Rows with `error === 'lock_conflict'` include `current_lock` (code **423** per row).
429
432
  */
430
433
  writeXmlDocumentsBatch(items: XmlDocumentBatchItem[]): Promise<DocumentBatchResponse>;
431
434
  /**
@@ -465,14 +468,28 @@ export declare class XCiteDBClient {
465
468
  * {@link LockConflictBody} body (thrown as {@link XCiteDBError} with `.status === 409`).
466
469
  */
467
470
  acquireLock(identifier: string, expiresOrOpts?: number | AcquireLockOptions): Promise<LockInfo>;
471
+ /**
472
+ * Release a lock. **404** with {@link LockUnknownBody} if the lock id is unknown; **410** with
473
+ * {@link LockExpiredBody} if the lock TTL expired and was garbage-collected (same server process hint).
474
+ */
468
475
  releaseLock(identifier: string, lockId: string): Promise<boolean>;
469
476
  /**
470
477
  * Force-release a lock using `force_unlock` ABAC authority. Pass the **raw** stored identifier
471
478
  * from {@link findLocks} (no iso-prefix); often the path as returned by the server for another principal.
472
479
  */
473
480
  forceReleaseLock(identifier: string, lockId: string): Promise<boolean>;
481
+ /**
482
+ * Extend lock TTL (holder must match). **404** {@link LockUnknownBody} / **410** {@link LockExpiredBody}
483
+ * behave like {@link releaseLock}.
484
+ */
474
485
  extendLock(identifier: string, lockId: string, ttlSeconds: number): Promise<LockInfo>;
475
- findLocks(identifier: string): Promise<LockInfo[]>;
486
+ /**
487
+ * List locks visible under the given path. Pass `metaId` style paths (e.g. `/spaces/owner/docs/docId`).
488
+ * With `{ asPrefix: true }`, calls `GET /api/v1/locks?prefix=...` (same truncation rules as `identifier`).
489
+ */
490
+ findLocks(identifier: string, opts?: {
491
+ asPrefix?: boolean;
492
+ }): Promise<LockInfo[]>;
476
493
  /**
477
494
  * Run Unquery (`POST /api/v1/unquery`): declarative analytics over documents matching `query`.
478
495
  * The `unquery` argument is a JSON template; keys are output fields, string values are expressions.
package/dist/client.js CHANGED
@@ -1194,6 +1194,8 @@ class XCiteDBClient {
1194
1194
  /**
1195
1195
  * Write an **XML** document using a JSON request body (`xml` field). The identifier is taken from `db:identifier` on the root element.
1196
1196
  * For storing JSON data by key, use `writeJsonDocument`.
1197
+ *
1198
+ * On cooperative-lock conflict the server returns **423** with a {@link LockConflictBody} shape in {@link XCiteDBError.body}.
1197
1199
  */
1198
1200
  async writeXmlDocument(xml, options) {
1199
1201
  await this.request('POST', '/api/v1/documents', {
@@ -1204,6 +1206,7 @@ class XCiteDBClient {
1204
1206
  }
1205
1207
  /**
1206
1208
  * Best-effort batch XML writes (`POST /api/v1/documents/batch`). Each item is independent; check `results[].ok`.
1209
+ * Rows with `error === 'lock_conflict'` include `current_lock` (code **423** per row).
1207
1210
  */
1208
1211
  async writeXmlDocumentsBatch(items) {
1209
1212
  const body = {
@@ -1443,6 +1446,10 @@ class XCiteDBClient {
1443
1446
  const lock = await this.request('POST', '/api/v1/locks', body);
1444
1447
  return { ...lock, identifier: this.isoUnprefixId(lock.identifier) };
1445
1448
  }
1449
+ /**
1450
+ * Release a lock. **404** with {@link LockUnknownBody} if the lock id is unknown; **410** with
1451
+ * {@link LockExpiredBody} if the lock TTL expired and was garbage-collected (same server process hint).
1452
+ */
1446
1453
  async releaseLock(identifier, lockId) {
1447
1454
  const r = await this.request('DELETE', '/api/v1/locks', {
1448
1455
  identifier: this.isoPrefixId(identifier),
@@ -1462,6 +1469,10 @@ class XCiteDBClient {
1462
1469
  });
1463
1470
  return r?.ok !== false;
1464
1471
  }
1472
+ /**
1473
+ * Extend lock TTL (holder must match). **404** {@link LockUnknownBody} / **410** {@link LockExpiredBody}
1474
+ * behave like {@link releaseLock}.
1475
+ */
1465
1476
  async extendLock(identifier, lockId, ttlSeconds) {
1466
1477
  const lock = await this.request('PATCH', '/api/v1/locks', {
1467
1478
  identifier: this.isoPrefixId(identifier),
@@ -1470,8 +1481,13 @@ class XCiteDBClient {
1470
1481
  });
1471
1482
  return { ...lock, identifier: this.isoUnprefixId(lock.identifier) };
1472
1483
  }
1473
- async findLocks(identifier) {
1474
- const locks = await this.request('GET', `/api/v1/locks${buildQuery({ identifier: this.isoPrefixId(identifier) })}`);
1484
+ /**
1485
+ * List locks visible under the given path. Pass `metaId` style paths (e.g. `/spaces/owner/docs/docId`).
1486
+ * With `{ asPrefix: true }`, calls `GET /api/v1/locks?prefix=...` (same truncation rules as `identifier`).
1487
+ */
1488
+ async findLocks(identifier, opts) {
1489
+ const key = opts?.asPrefix ? 'prefix' : 'identifier';
1490
+ const locks = await this.request('GET', `/api/v1/locks${buildQuery({ [key]: this.isoPrefixId(identifier) })}`);
1475
1491
  return Array.isArray(locks)
1476
1492
  ? locks.map((L) => ({ ...L, identifier: this.isoUnprefixId(L.identifier) }))
1477
1493
  : locks;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { XCiteDBClient } from './client';
2
2
  export { WebSocketSubscription } from './websocket';
3
- export type { AccessCheckResult, ApiKeyInfo, AppAuthConfig, AppEmailConfig, AppEmailSmtpConfig, AppEmailTemplateEntry, AppEmailTemplates, AppEmailWebhookConfig, AppUser, AppUserTokenPair, EmailTestResponse, ForgotPasswordResponse, SendVerificationResponse, BookmarkRecord, BranchInfo, BranchListItem, CheckpointRecord, CommitRecord, CompareEntry, CompareRef, CompareResult, DatabaseContext, DiffEntry, DiffRef, DiffResult, DocumentBatchResponse, DocumentBatchResultRow, Flags, JsonDocumentData, JsonDocumentBatchItem, IdentifierChildNode, ListIdentifierChildrenResult, ListIdentifiersResult, LockInfo, AcquireLockOptions, LockConflictBody, MergeConflict, MergeResult, OAuthProviderInfo, OAuthProvidersResponse, OwnedTenantInfo, ProjectInfo, PlatformRegistrationConfig, PlatformWorkspaceOrg, PlatformWorkspacesResponse, ProjectSearchSettings, ProjectSearchSettingsUpdate, ProjectDocConfResponse, PlatformDefaultDocConfResponse, LogEntry, MetaValue, PlatformRegisterResult, PolicyUpdateResponse, PublishConflict, PublishResult, PolicyConditions, PolicyIdentifierPattern, PolicyResources, PolicySubjectInput, PolicySubjects, RagQueryOptions, RagQueryResult, RagStreamEvent, RealtimeEvent, SearchIndexingProgress, SecurityConfig, SecurityPolicy, StoredPolicyResponse, StoredTriggerResponse, SubscriptionOptions, TagRecord, TextSearchHit, TextSearchQuery, TextSearchResult, TriggerDefinition, TokenPair, UserInfo, UserIsolationConfig, UserIsolationCreateShareParams, UserIsolationOptions, UserIsolationShareMode, UserIsolationShareResult, WorkspaceInfo, WriteDocumentOptions, XmlDocumentBatchItem, CreateTestSessionOptions, XCiteDBClientOptions, XCiteDBJwtClaims, UnqueryResult, UnqueryTemplate, XCiteQuery, } from './types';
3
+ export type { AccessCheckResult, ApiKeyInfo, AppAuthConfig, AppEmailConfig, AppEmailSmtpConfig, AppEmailTemplateEntry, AppEmailTemplates, AppEmailWebhookConfig, AppUser, AppUserTokenPair, EmailTestResponse, ForgotPasswordResponse, SendVerificationResponse, BookmarkRecord, BranchInfo, BranchListItem, CheckpointRecord, CommitRecord, CompareEntry, CompareRef, CompareResult, DatabaseContext, DiffEntry, DiffRef, DiffResult, DocumentBatchResponse, DocumentBatchResultRow, Flags, JsonDocumentData, JsonDocumentBatchItem, IdentifierChildNode, ListIdentifierChildrenResult, ListIdentifiersResult, LockInfo, AcquireLockOptions, LockConflictBody, LockExpiredBody, LockUnknownBody, MergeConflict, MergeResult, OAuthProviderInfo, OAuthProvidersResponse, OwnedTenantInfo, ProjectInfo, PlatformRegistrationConfig, PlatformWorkspaceOrg, PlatformWorkspacesResponse, ProjectSearchSettings, ProjectSearchSettingsUpdate, ProjectDocConfResponse, PlatformDefaultDocConfResponse, LogEntry, MetaValue, PlatformRegisterResult, PolicyUpdateResponse, PublishConflict, PublishResult, PolicyConditions, PolicyIdentifierPattern, PolicyResources, PolicySubjectInput, PolicySubjects, RagQueryOptions, RagQueryResult, RagStreamEvent, RealtimeEvent, SearchIndexingProgress, SecurityConfig, SecurityPolicy, StoredPolicyResponse, StoredTriggerResponse, SubscriptionOptions, TagRecord, TextSearchHit, TextSearchQuery, TextSearchResult, TriggerDefinition, TokenPair, UserInfo, UserIsolationConfig, UserIsolationCreateShareParams, UserIsolationOptions, UserIsolationShareMode, UserIsolationShareResult, WorkspaceInfo, WriteDocumentOptions, XmlDocumentBatchItem, CreateTestSessionOptions, XCiteDBClientOptions, XCiteDBJwtClaims, UnqueryResult, UnqueryTemplate, XCiteQuery, } from './types';
4
4
  export { XCiteDBError } from './types';
@@ -26,7 +26,6 @@ async function openTestSession(e) {
26
26
  'Content-Type': 'application/json',
27
27
  Authorization: `Bearer ${e.accessToken}`,
28
28
  'X-Project-Id': e.tenantId,
29
- 'X-Branch': 'main',
30
29
  },
31
30
  body: '{}',
32
31
  });
@@ -39,7 +38,7 @@ async function openTestSession(e) {
39
38
  accessToken: e.accessToken,
40
39
  platformConsole: true,
41
40
  projectId: e.tenantId,
42
- context: { branch: 'main', project_id: e.tenantId },
41
+ context: { project_id: e.tenantId },
43
42
  testSessionToken: data.session_token,
44
43
  testRequireAuth: true,
45
44
  });
package/dist/types.d.ts CHANGED
@@ -267,11 +267,25 @@ export interface AcquireLockOptions {
267
267
  /** Max milliseconds to wait when another exclusive lock is held. */
268
268
  waitMs?: number;
269
269
  }
270
- /** Body returned with HTTP 409 on exclusive lock conflict. */
270
+ /**
271
+ * Body returned with HTTP **409** on `acquireLock` conflict, or **423** on XML document write blocked by a lock.
272
+ * Inspect via {@link XCiteDBError} (`status` and `body`).
273
+ */
271
274
  export interface LockConflictBody {
272
275
  error: 'lock_conflict';
273
276
  current_lock: LockInfo;
274
277
  }
278
+ /** Body returned with HTTP **410** when `extendLock` / `releaseLock` target a lock id that TTL-expired recently. */
279
+ export interface LockExpiredBody {
280
+ error: 'lock_expired';
281
+ message?: string;
282
+ expired_at?: number;
283
+ }
284
+ /** Body returned with HTTP **404** when the lock id does not exist (or never existed) for the given identifier. */
285
+ export interface LockUnknownBody {
286
+ error: 'lock_unknown';
287
+ message?: string;
288
+ }
275
289
  export interface TokenPair {
276
290
  access_token: string;
277
291
  refresh_token: string;
@@ -392,6 +406,8 @@ export interface DocumentBatchResultRow {
392
406
  ok: boolean;
393
407
  error?: string;
394
408
  code?: number;
409
+ /** Present when `error === 'lock_conflict'` (HTTP-style code 423 in batch row). */
410
+ current_lock?: LockInfo;
395
411
  }
396
412
  export interface DocumentBatchResponse {
397
413
  results: DocumentBatchResultRow[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xcitedbs/client",
3
- "version": "0.2.17",
3
+ "version": "0.2.18",
4
4
  "description": "XCiteDB BaaS client SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",