@xcitedbs/client 0.2.11 → 0.2.12
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 +22 -0
- package/dist/client.d.ts +17 -2
- package/dist/client.js +64 -3
- package/dist/index.d.ts +1 -1
- package/dist/types.d.ts +37 -2
- package/llms-full.txt +25 -11
- package/llms.txt +12 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,6 +34,19 @@ const docs = await client.queryByIdentifier('/test1', 'FirstMatch');
|
|
|
34
34
|
await client.put('app.settings', { theme: 'dark' });
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
### Full-text search (temporal)
|
|
38
|
+
|
|
39
|
+
`client.search()` accepts `TextSearchQuery` with optional **`at_date`** (point-in-time), **`date_from`** / **`date_to`** (range overlap), and **`mode`: `'fts'`** for pure keyword search. Omit temporal fields for the default “current” posting view. Hits may include **`valid_from`** / **`valid_to`** (7-character internal date keys returned by the server).
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
await client.search({
|
|
43
|
+
query: 'installation guide',
|
|
44
|
+
mode: 'fts',
|
|
45
|
+
at_date: '2024-06-01',
|
|
46
|
+
limit: 20,
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
37
50
|
### WebSocket
|
|
38
51
|
|
|
39
52
|
```typescript
|
|
@@ -45,6 +58,15 @@ client.subscribe(
|
|
|
45
58
|
|
|
46
59
|
With JWT in browsers, tokens are passed as `access_token` query parameter on the WebSocket URL. API keys can use `api_key` query parameter.
|
|
47
60
|
|
|
61
|
+
## Test sessions (ephemeral and overlay)
|
|
62
|
+
|
|
63
|
+
Call **`POST /api/v1/test/sessions`** with your normal API key or Bearer (same project context as usual). Use **`XCiteDBClient.createTestSession({ baseUrl, apiKey, … })`** to get a client that sends **`X-Test-Session`** on requests.
|
|
64
|
+
|
|
65
|
+
- **Default:** isolated empty LMDB under the server’s `_test/<uuid>/` (writes never touch production).
|
|
66
|
+
- **Overlay:** pass **`overlay: true`** in **`createTestSession`** options (or **`POST`** body **`{"overlay":true}`**). The server layers a writable LMDB on top of the **current project’s on-disk data opened read-only** so you can debug against real data; changes still live only under `_test/<uuid>/`. Use project-scoped credentials or platform Bearer + **`X-Project-Id`** as when calling production APIs.
|
|
67
|
+
|
|
68
|
+
Tear down with **`destroyTestSession()`** (or **`DELETE /api/v1/test/sessions/current`** with the session header). See **`llms.txt`** / **`llms-full.txt`** in this package for full behavior, limits, and auth notes.
|
|
69
|
+
|
|
48
70
|
## Build
|
|
49
71
|
|
|
50
72
|
```bash
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AccessCheckResult, AppAuthConfig, AppEmailConfig, AppEmailTemplates, AppUser, AppUserTokenPair, EmailTestResponse, ForgotPasswordResponse, SendVerificationResponse, BranchInfo, BookmarkRecord, CheckpointRecord, CommitRecord, CompareRef, CompareResult, DatabaseContext, DiffRef, DiffResult, Flags, ListIdentifierChildrenResult, ListIdentifiersResult, LockInfo, LogEntry, MergeResult, PublishResult, WorkspaceInfo, MetaValue, PlatformRegisterResult, PolicySubjectInput, UnqueryResult, UnqueryTemplate, PolicyUpdateResponse, RealtimeEvent, SecurityConfig, SecurityPolicy, StoredTriggerResponse, TriggerDefinition, StoredPolicyResponse, SubscriptionOptions, TagRecord, TextSearchQuery, TextSearchResult, ProjectSearchSettings, ProjectSearchSettingsUpdate, VectorIndexEstimate, RagQueryOptions, RagQueryResult, RagStreamEvent, OAuthProvidersResponse, ProjectInfo, PlatformRegistrationConfig, PlatformWorkspacesResponse, TokenPair, UserInfo, ApiKeyInfo, WriteDocumentOptions, CreateTestSessionOptions, XCiteDBClientOptions, XCiteDBJwtClaims, XCiteQuery, UserIsolationConfig } from './types';
|
|
1
|
+
import { AccessCheckResult, AppAuthConfig, AppEmailConfig, AppEmailTemplates, AppUser, AppUserTokenPair, EmailTestResponse, ForgotPasswordResponse, SendVerificationResponse, BranchInfo, BookmarkRecord, CheckpointRecord, CommitRecord, CompareRef, CompareResult, DatabaseContext, DiffRef, DiffResult, Flags, ListIdentifierChildrenResult, ListIdentifiersResult, LockInfo, LogEntry, MergeResult, PublishResult, WorkspaceInfo, MetaValue, PlatformRegisterResult, PolicySubjectInput, UnqueryResult, UnqueryTemplate, PolicyUpdateResponse, RealtimeEvent, SecurityConfig, SecurityPolicy, StoredTriggerResponse, TriggerDefinition, StoredPolicyResponse, SubscriptionOptions, TagRecord, TextSearchQuery, TextSearchResult, ProjectSearchSettings, ProjectSearchSettingsUpdate, ProjectDocConfResponse, PlatformDefaultDocConfResponse, VectorIndexEstimate, RagQueryOptions, RagQueryResult, RagStreamEvent, OAuthProvidersResponse, ProjectInfo, PlatformRegistrationConfig, PlatformWorkspacesResponse, TokenPair, UserInfo, ApiKeyInfo, WriteDocumentOptions, CreateTestSessionOptions, XCiteDBClientOptions, XCiteDBJwtClaims, XCiteQuery, UserIsolationConfig } from './types';
|
|
2
2
|
import { WebSocketSubscription } from './websocket';
|
|
3
3
|
export declare class XCiteDBClient {
|
|
4
4
|
private baseUrl;
|
|
@@ -18,10 +18,13 @@ export declare class XCiteDBClient {
|
|
|
18
18
|
private testRequireAuth?;
|
|
19
19
|
private userIsolation?;
|
|
20
20
|
private cachedAppUserId?;
|
|
21
|
+
private readonly requestTimeoutMs?;
|
|
21
22
|
constructor(options: XCiteDBClientOptions);
|
|
22
23
|
/**
|
|
23
|
-
* Create an ephemeral
|
|
24
|
+
* Create an ephemeral test database: calls `POST /api/v1/test/sessions` with your API key or Bearer,
|
|
24
25
|
* then returns a client that sends `X-Test-Session` (auth-free by default).
|
|
26
|
+
* With `opts.overlay === true`, the server stores overlay mode: reads merge the empty `_test/...` LMDB
|
|
27
|
+
* over the current project's production data (read-only base); writes stay under `_test/...` only.
|
|
25
28
|
*/
|
|
26
29
|
static createTestSession(opts: CreateTestSessionOptions): Promise<XCiteDBClient>;
|
|
27
30
|
/**
|
|
@@ -484,6 +487,18 @@ export declare class XCiteDBClient {
|
|
|
484
487
|
getProjectSearchSettings(): Promise<ProjectSearchSettings>;
|
|
485
488
|
/** Update project search settings (`PUT /api/v1/project/settings/search`). Returns the same shape as GET. */
|
|
486
489
|
updateProjectSearchSettings(patch: ProjectSearchSettingsUpdate): Promise<ProjectSearchSettings>;
|
|
490
|
+
/** Per-project `document.conf` override (`GET /api/v1/project/settings/doc-conf`). */
|
|
491
|
+
getProjectDocConf(): Promise<ProjectDocConfResponse>;
|
|
492
|
+
/** Save or clear project `document.conf` (`PUT /api/v1/project/settings/doc-conf`). */
|
|
493
|
+
updateProjectDocConf(body: {
|
|
494
|
+
doc_conf_text: string;
|
|
495
|
+
} | {
|
|
496
|
+
clear: true;
|
|
497
|
+
}): Promise<ProjectDocConfResponse>;
|
|
498
|
+
/** Remove project override; server uses platform default (`DELETE /api/v1/project/settings/doc-conf`). */
|
|
499
|
+
deleteProjectDocConf(): Promise<ProjectDocConfResponse>;
|
|
500
|
+
/** Embedded platform default `document.conf` text (`GET /api/v1/platform/default-doc-conf`). */
|
|
501
|
+
getPlatformDefaultDocConf(): Promise<PlatformDefaultDocConfResponse>;
|
|
487
502
|
/** Blocking full DB scan (admin; no calls to embedding API). Prefer {@link postVectorIndexEstimateSession} for UI. */
|
|
488
503
|
getVectorIndexEstimate(): Promise<VectorIndexEstimate>;
|
|
489
504
|
/** Start background estimate (202); cancel prior session for this tenant. */
|
package/dist/client.js
CHANGED
|
@@ -18,6 +18,30 @@ function buildQuery(params) {
|
|
|
18
18
|
const s = sp.toString();
|
|
19
19
|
return s ? `?${s}` : '';
|
|
20
20
|
}
|
|
21
|
+
function warnIfHttpOnTlsPort(baseUrl) {
|
|
22
|
+
try {
|
|
23
|
+
const u = new URL(baseUrl);
|
|
24
|
+
if (u.protocol !== 'http:')
|
|
25
|
+
return;
|
|
26
|
+
if (u.port === '443') {
|
|
27
|
+
if (typeof console !== 'undefined' && typeof console.warn === 'function') {
|
|
28
|
+
console.warn('[@xcitedbs/client] baseUrl uses http: on port 443; use https:// to avoid hangs or TLS errors.');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
/* ignore invalid baseUrl */
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Uses `AbortSignal.timeout` when the runtime supports it. */
|
|
37
|
+
function requestTimeoutSignal(ms) {
|
|
38
|
+
if (ms === undefined || ms <= 0)
|
|
39
|
+
return undefined;
|
|
40
|
+
const ctor = AbortSignal;
|
|
41
|
+
if (typeof ctor.timeout === 'function')
|
|
42
|
+
return ctor.timeout(ms);
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
21
45
|
class XCiteDBClient {
|
|
22
46
|
constructor(options) {
|
|
23
47
|
this.baseUrl = options.baseUrl.replace(/\/+$/, '');
|
|
@@ -34,10 +58,14 @@ class XCiteDBClient {
|
|
|
34
58
|
this.testSessionToken = options.testSessionToken;
|
|
35
59
|
this.testRequireAuth = options.testRequireAuth === true;
|
|
36
60
|
this.userIsolation = options.userIsolation;
|
|
61
|
+
this.requestTimeoutMs = options.requestTimeoutMs;
|
|
62
|
+
warnIfHttpOnTlsPort(this.baseUrl);
|
|
37
63
|
}
|
|
38
64
|
/**
|
|
39
|
-
* Create an ephemeral
|
|
65
|
+
* Create an ephemeral test database: calls `POST /api/v1/test/sessions` with your API key or Bearer,
|
|
40
66
|
* then returns a client that sends `X-Test-Session` (auth-free by default).
|
|
67
|
+
* With `opts.overlay === true`, the server stores overlay mode: reads merge the empty `_test/...` LMDB
|
|
68
|
+
* over the current project's production data (read-only base); writes stay under `_test/...` only.
|
|
41
69
|
*/
|
|
42
70
|
static async createTestSession(opts) {
|
|
43
71
|
const temp = new XCiteDBClient({
|
|
@@ -53,8 +81,9 @@ class XCiteDBClient {
|
|
|
53
81
|
onAppUserTokensUpdated: opts.onAppUserTokensUpdated,
|
|
54
82
|
onSessionInvalid: opts.onSessionInvalid,
|
|
55
83
|
userIsolation: opts.userIsolation,
|
|
84
|
+
requestTimeoutMs: opts.requestTimeoutMs,
|
|
56
85
|
});
|
|
57
|
-
const data = await temp.request('POST', '/api/v1/test/sessions', undefined, undefined, { no401Retry: true });
|
|
86
|
+
const data = await temp.request('POST', '/api/v1/test/sessions', opts.overlay === true ? { overlay: true } : undefined, undefined, { no401Retry: true });
|
|
58
87
|
return new XCiteDBClient({
|
|
59
88
|
baseUrl: opts.baseUrl,
|
|
60
89
|
apiKey: opts.testRequireAuth ? opts.apiKey : undefined,
|
|
@@ -70,6 +99,7 @@ class XCiteDBClient {
|
|
|
70
99
|
testSessionToken: data.session_token,
|
|
71
100
|
testRequireAuth: opts.testRequireAuth,
|
|
72
101
|
userIsolation: opts.userIsolation,
|
|
102
|
+
requestTimeoutMs: opts.requestTimeoutMs,
|
|
73
103
|
});
|
|
74
104
|
}
|
|
75
105
|
/**
|
|
@@ -444,6 +474,9 @@ class XCiteDBClient {
|
|
|
444
474
|
init.body = JSON.stringify(body);
|
|
445
475
|
}
|
|
446
476
|
}
|
|
477
|
+
const sig = requestTimeoutSignal(this.requestTimeoutMs);
|
|
478
|
+
if (sig)
|
|
479
|
+
init.signal = sig;
|
|
447
480
|
const res = await fetch(url, init);
|
|
448
481
|
const text = await res.text();
|
|
449
482
|
let data;
|
|
@@ -1410,12 +1443,18 @@ class XCiteDBClient {
|
|
|
1410
1443
|
body.offset = q.offset;
|
|
1411
1444
|
if (q.limit !== undefined)
|
|
1412
1445
|
body.limit = q.limit;
|
|
1413
|
-
if (q.mode)
|
|
1446
|
+
if (q.mode !== undefined)
|
|
1414
1447
|
body.mode = q.mode;
|
|
1415
1448
|
if (q.min_score !== undefined)
|
|
1416
1449
|
body.min_score = q.min_score;
|
|
1417
1450
|
if (q.semantic_weight !== undefined)
|
|
1418
1451
|
body.semantic_weight = q.semantic_weight;
|
|
1452
|
+
if (q.at_date !== undefined && q.at_date !== '')
|
|
1453
|
+
body.at_date = q.at_date;
|
|
1454
|
+
if (q.date_from !== undefined && q.date_from !== '')
|
|
1455
|
+
body.date_from = q.date_from;
|
|
1456
|
+
if (q.date_to !== undefined && q.date_to !== '')
|
|
1457
|
+
body.date_to = q.date_to;
|
|
1419
1458
|
const data = await this.request('POST', '/api/v1/search', body);
|
|
1420
1459
|
const hits = [];
|
|
1421
1460
|
if (Array.isArray(data.hits)) {
|
|
@@ -1436,6 +1475,12 @@ class XCiteDBClient {
|
|
|
1436
1475
|
if (o.source === 'fts' || o.source === 'semantic' || o.source === 'both') {
|
|
1437
1476
|
hit.source = o.source;
|
|
1438
1477
|
}
|
|
1478
|
+
if (typeof o.valid_from === 'string' && o.valid_from.length > 0) {
|
|
1479
|
+
hit.valid_from = o.valid_from;
|
|
1480
|
+
}
|
|
1481
|
+
if (typeof o.valid_to === 'string' && o.valid_to.length > 0) {
|
|
1482
|
+
hit.valid_to = o.valid_to;
|
|
1483
|
+
}
|
|
1439
1484
|
hits.push(hit);
|
|
1440
1485
|
}
|
|
1441
1486
|
}
|
|
@@ -1460,6 +1505,22 @@ class XCiteDBClient {
|
|
|
1460
1505
|
async updateProjectSearchSettings(patch) {
|
|
1461
1506
|
return this.request('PUT', '/api/v1/project/settings/search', patch);
|
|
1462
1507
|
}
|
|
1508
|
+
/** Per-project `document.conf` override (`GET /api/v1/project/settings/doc-conf`). */
|
|
1509
|
+
async getProjectDocConf() {
|
|
1510
|
+
return this.request('GET', '/api/v1/project/settings/doc-conf');
|
|
1511
|
+
}
|
|
1512
|
+
/** Save or clear project `document.conf` (`PUT /api/v1/project/settings/doc-conf`). */
|
|
1513
|
+
async updateProjectDocConf(body) {
|
|
1514
|
+
return this.request('PUT', '/api/v1/project/settings/doc-conf', body);
|
|
1515
|
+
}
|
|
1516
|
+
/** Remove project override; server uses platform default (`DELETE /api/v1/project/settings/doc-conf`). */
|
|
1517
|
+
async deleteProjectDocConf() {
|
|
1518
|
+
return this.request('DELETE', '/api/v1/project/settings/doc-conf');
|
|
1519
|
+
}
|
|
1520
|
+
/** Embedded platform default `document.conf` text (`GET /api/v1/platform/default-doc-conf`). */
|
|
1521
|
+
async getPlatformDefaultDocConf() {
|
|
1522
|
+
return this.request('GET', '/api/v1/platform/default-doc-conf');
|
|
1523
|
+
}
|
|
1463
1524
|
/** Blocking full DB scan (admin; no calls to embedding API). Prefer {@link postVectorIndexEstimateSession} for UI. */
|
|
1464
1525
|
async getVectorIndexEstimate() {
|
|
1465
1526
|
return this.request('GET', '/api/v1/project/settings/search/vector-index-estimate', undefined);
|
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, Flags, JsonDocumentData, IdentifierChildNode, ListIdentifierChildrenResult, ListIdentifiersResult, LockInfo, MergeConflict, MergeResult, OAuthProviderInfo, OAuthProvidersResponse, OwnedTenantInfo, ProjectInfo, PlatformRegistrationConfig, PlatformWorkspaceOrg, PlatformWorkspacesResponse, ProjectSearchSettings, ProjectSearchSettingsUpdate, 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, UserIsolationOptions, WorkspaceInfo, WriteDocumentOptions, 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, Flags, JsonDocumentData, IdentifierChildNode, ListIdentifierChildrenResult, ListIdentifiersResult, LockInfo, 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, UserIsolationOptions, WorkspaceInfo, WriteDocumentOptions, CreateTestSessionOptions, XCiteDBClientOptions, XCiteDBJwtClaims, UnqueryResult, UnqueryTemplate, XCiteQuery, } from './types';
|
|
4
4
|
export { XCiteDBError } from './types';
|
package/dist/types.d.ts
CHANGED
|
@@ -41,12 +41,20 @@ export interface TextSearchQuery {
|
|
|
41
41
|
branch?: string;
|
|
42
42
|
offset?: number;
|
|
43
43
|
limit?: number;
|
|
44
|
-
/**
|
|
45
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Default server behavior when omitted: `auto` (hybrid if FTS+vector enabled, else semantic or FTS).
|
|
46
|
+
* Explicit `fts` / `semantic` / `hybrid` require the matching capabilities to be enabled.
|
|
47
|
+
*/
|
|
48
|
+
mode?: 'auto' | 'fts' | 'semantic' | 'hybrid';
|
|
46
49
|
/** Minimum cosine similarity for semantic / hybrid vector leg (default 0.3). */
|
|
47
50
|
min_score?: number;
|
|
48
51
|
/** Hybrid only: weight of semantic vs FTS in weighted RRF (0–1, default 0.5). */
|
|
49
52
|
semantic_weight?: number;
|
|
53
|
+
/** Point-in-time FTS filter (ISO date string; server maps to internal date key). */
|
|
54
|
+
at_date?: string;
|
|
55
|
+
/** Range FTS filter: interval overlap with [date_from, date_to) (ISO dates). */
|
|
56
|
+
date_from?: string;
|
|
57
|
+
date_to?: string;
|
|
50
58
|
}
|
|
51
59
|
export interface TextSearchHit {
|
|
52
60
|
identifier: string;
|
|
@@ -59,6 +67,9 @@ export interface TextSearchHit {
|
|
|
59
67
|
score: number;
|
|
60
68
|
/** Present for semantic / hybrid search. */
|
|
61
69
|
source?: 'fts' | 'semantic' | 'both';
|
|
70
|
+
/** FTS temporal window for this hit (internal 7-char keys), when returned by the server. */
|
|
71
|
+
valid_from?: string;
|
|
72
|
+
valid_to?: string;
|
|
62
73
|
}
|
|
63
74
|
export interface TextSearchResult {
|
|
64
75
|
hits: TextSearchHit[];
|
|
@@ -153,6 +164,15 @@ export interface ProjectSearchSettingsUpdate {
|
|
|
153
164
|
llm_base_url?: string | null;
|
|
154
165
|
llm_api_key?: string;
|
|
155
166
|
}
|
|
167
|
+
/** `GET /api/v1/project/settings/doc-conf` (and returned after `PUT` / `DELETE`). */
|
|
168
|
+
export interface ProjectDocConfResponse {
|
|
169
|
+
has_project_override: boolean;
|
|
170
|
+
doc_conf_text: string | null;
|
|
171
|
+
}
|
|
172
|
+
/** `GET /api/v1/platform/default-doc-conf` */
|
|
173
|
+
export interface PlatformDefaultDocConfResponse {
|
|
174
|
+
doc_conf_text: string;
|
|
175
|
+
}
|
|
156
176
|
/** `POST /api/v1/rag/query` (non-streaming: set `stream: false` or omit). */
|
|
157
177
|
export interface RagQueryOptions {
|
|
158
178
|
question: string;
|
|
@@ -314,6 +334,11 @@ export interface DatabaseContext {
|
|
|
314
334
|
workspace?: string;
|
|
315
335
|
/** @deprecated Prefer {@link DatabaseContext.workspace}. Sent as `X-Branch` when `workspace` is unset. */
|
|
316
336
|
branch?: string;
|
|
337
|
+
/**
|
|
338
|
+
* As-of revision time, sent as `X-Date`. Accepted forms (whole string must match; trailing spaces ignored):
|
|
339
|
+
* `mm/dd/yyyy`, `mm/dd/yyyy:HH:MM:SS`, ISO `YYYY-MM-DDTHH:MM:SS` with optional numeric timezone,
|
|
340
|
+
* `YYYY-MM-DD HH:MM:SS`, and ISO date-only `YYYY-MM-DD`.
|
|
341
|
+
*/
|
|
317
342
|
date?: string;
|
|
318
343
|
prefix?: string;
|
|
319
344
|
/**
|
|
@@ -392,6 +417,11 @@ export interface XCiteDBClientOptions {
|
|
|
392
417
|
testRequireAuth?: boolean;
|
|
393
418
|
/** Auto-prefix identifiers for app-user sessions (see {@link UserIsolationOptions}). */
|
|
394
419
|
userIsolation?: UserIsolationOptions;
|
|
420
|
+
/**
|
|
421
|
+
* Per-request timeout in milliseconds for normal REST calls (uses `AbortSignal.timeout` when available).
|
|
422
|
+
* Omit for no timeout. Streaming RAG (`ragQueryStream`) does not apply this.
|
|
423
|
+
*/
|
|
424
|
+
requestTimeoutMs?: number;
|
|
395
425
|
}
|
|
396
426
|
/** Options for {@link XCiteDBClient.createTestSession} (provisions via API key or Bearer). */
|
|
397
427
|
export interface CreateTestSessionOptions {
|
|
@@ -403,12 +433,17 @@ export interface CreateTestSessionOptions {
|
|
|
403
433
|
context?: DatabaseContext;
|
|
404
434
|
platformConsole?: boolean;
|
|
405
435
|
projectId?: string;
|
|
436
|
+
/**
|
|
437
|
+
* When true, creates an overlay test session: writable ephemeral LMDB with production project data as read-only base.
|
|
438
|
+
*/
|
|
439
|
+
overlay?: boolean;
|
|
406
440
|
/** Keep `apiKey` / `accessToken` on the client and send `X-Test-Auth: required` on each request. */
|
|
407
441
|
testRequireAuth?: boolean;
|
|
408
442
|
onSessionTokensUpdated?: (pair: TokenPair) => void;
|
|
409
443
|
onAppUserTokensUpdated?: (pair: AppUserTokenPair) => void;
|
|
410
444
|
onSessionInvalid?: () => void;
|
|
411
445
|
userIsolation?: UserIsolationOptions;
|
|
446
|
+
requestTimeoutMs?: number;
|
|
412
447
|
}
|
|
413
448
|
/** Application user (tenant-scoped), distinct from developer users. */
|
|
414
449
|
export interface AppUser {
|
package/llms-full.txt
CHANGED
|
@@ -26,7 +26,9 @@ Before reading the full reference, note these critical differences from typical
|
|
|
26
26
|
|
|
27
27
|
9. **OpenAPI:** See repository `docs/openapi.yaml` for a machine-readable route map.
|
|
28
28
|
|
|
29
|
-
10. **Ephemeral test sessions.** `POST /api/v1/test/sessions` (authenticated) returns a UUID **`session_token`**. Clients send **`X-Test-Session: <token>`** on API calls to use an isolated, TTL- and quota-limited LMDB instead of production project data. Unless **`X-Test-Auth: required`** is set, **developer** JWT/API-key checks are bypassed (synthetic admin for wet tests), but **app-user** identity via **`X-App-User-Token`** or Bearer app-user JWT is still recognized. Management routes under **`/api/v1/test/*`** must not include `X-Test-Session`.
|
|
29
|
+
10. **Ephemeral test sessions.** `POST /api/v1/test/sessions` (authenticated) returns a UUID **`session_token`**. Clients send **`X-Test-Session: <token>`** on API calls to use an isolated, TTL- and quota-limited LMDB instead of production project data. Unless **`X-Test-Auth: required`** is set, **developer** JWT/API-key checks are bypassed (synthetic admin for wet tests), but **app-user** identity via **`X-App-User-Token`** or Bearer app-user JWT is still recognized. Management routes under **`/api/v1/test/*`** must not include `X-Test-Session`. With a default body (omit or `{}`), the test LMDB starts **empty** (no cloned production project config).
|
|
30
|
+
|
|
31
|
+
11. **Overlay test sessions.** Same **`POST`**, with JSON **`{"overlay":true}`**, while authenticated for the **project to debug** (project-scoped API key, or platform Bearer + **`X-Project-Id`**). The session metadata records overlay mode; subsequent requests need only **`X-Test-Session`**. The server opens **`XCiteDB(_test/<uuid>/data, <production data path>)`**: production is used as a **read-only base**; reads merge overlay + base; **writes never modify production**. If the production data directory is missing, opening the session database fails. JS **`createTestSession({ …, overlay: true })`**, C++ **`test_session_overlay`** + **`create_test_session`**, MCP **`create_test_session`** tool **`overlay: true`**.
|
|
30
32
|
|
|
31
33
|
## Choosing the Right Versioning Approach
|
|
32
34
|
|
|
@@ -58,7 +60,7 @@ Legacy REST paths under `/api/v1/branches`, `/commits`, `/tags`, `/diff` remain
|
|
|
58
60
|
|
|
59
61
|
6. **Self-registration uses server-configured default groups.** `registerAppUser()` assigns groups from the server's `auth.app_users.default_groups` config, not from the client request. To assign specific groups, use the admin endpoint `createAppUser()` instead, or update groups after registration via `updateAppUserGroups()`.
|
|
60
62
|
|
|
61
|
-
7. **Do not mock XciteDB in tests — use ephemeral test sessions instead.** Unlike most BaaS platforms, XciteDB has built-in support for isolated, throwaway database sessions specifically designed for wet integration tests. Mocking the client skips the actual storage, versioning, querying, and ABAC behavior, producing tests that don't catch real integration issues. Use `createTestSession()` / `test_session()` / `create_test_session()` (SDK helpers) or `POST /api/v1/test/sessions` directly to get a real
|
|
63
|
+
7. **Do not mock XciteDB in tests — use ephemeral test sessions instead.** Unlike most BaaS platforms, XciteDB has built-in support for isolated, throwaway database sessions specifically designed for wet integration tests. Mocking the client skips the actual storage, versioning, querying, and ABAC behavior, producing tests that don't catch real integration issues. Use `createTestSession()` / `test_session()` / `create_test_session()` (SDK helpers) or `POST /api/v1/test/sessions` directly to get a real LMDB under `_test/<uuid>/` (empty by default, or **overlay** on read-only production with **`{"overlay":true}`** / **`overlay: true`** / **`test_session_overlay`**). See "Ephemeral test sessions" below.
|
|
62
64
|
|
|
63
65
|
---
|
|
64
66
|
|
|
@@ -205,7 +207,7 @@ For **integration and wet tests** against a shared BaaS host without touching pr
|
|
|
205
207
|
|
|
206
208
|
| Step | What to do |
|
|
207
209
|
|------|------------|
|
|
208
|
-
| **Create** | **`POST /api/v1/test/sessions`** with normal **`Authorization: Bearer …`** or **`X-API-Key`**. Response includes a **`session_token`** (UUID). Server enforces per-credential limits (`test.max_sessions_per_key`, `test.session_ttl_seconds`, `test.max_test_db_size_bytes` in server config). |
|
|
210
|
+
| **Create** | **`POST /api/v1/test/sessions`** with normal **`Authorization: Bearer …`** or **`X-API-Key`**. Response includes a **`session_token`** (UUID). Server enforces per-credential limits (`test.max_sessions_per_key`, `test.session_ttl_seconds`, `test.max_test_db_size_bytes` in server config). Optional JSON body **`{"overlay":true}`** provisions a **read-through production** session (writable delta only under `_test/<uuid>/`; production LMDB is read-only base). |
|
|
209
211
|
| **Use** | Send **`X-Test-Session: <session_token>`** on document and other data API requests. The server routes to a dedicated LMDB under its data root (`_test/<id>/`), not the caller’s production tenant. **`tenant_id` / `X-Project-Id` semantics do not select production** while the test header is present—the synthetic test tenant is implied. |
|
|
210
212
|
| **Auth** | **Default:** developer auth (API key / platform JWT) is **bypassed** with a synthetic admin identity. However, **app-user identity is still recognized**: if `X-App-User-Token` or a Bearer app-user JWT is present, the request runs as that app user (for routes like `/app/auth/me`). **`X-Test-Auth: required`:** all auth is validated normally; ABAC applies, but data still comes from the test session DB. |
|
|
211
213
|
| **Manage** | **`GET /api/v1/test/sessions`** — list sessions for the current credential. **`DELETE /api/v1/test/sessions/current`** — destroy the session named by **`X-Test-Session`** (no other auth). **`DELETE /api/v1/test/sessions/all`** — destroy all sessions for the credential. **`DELETE /api/v1/test/sessions/{token}`** — destroy one session if owned by the credential. Do **not** send **`X-Test-Session`** on these `/api/v1/test/*` routes. |
|
|
@@ -213,9 +215,9 @@ For **integration and wet tests** against a shared BaaS host without touching pr
|
|
|
213
215
|
|
|
214
216
|
**SDK usage (summary):**
|
|
215
217
|
|
|
216
|
-
- **JavaScript/TypeScript:** `XCiteDBClient.createTestSession({ baseUrl, apiKey, … })` returns a client configured with `testSessionToken`; optional `testRequireAuth: true` maps to `X-Test-Auth: required`. `destroyTestSession()` calls `DELETE …/test/sessions/current`.
|
|
217
|
-
- **Python:** `async with XCiteDBClient.test_session(base_url, api_key=…, …)` provisions and tears down; or pass `test_session_token` / `test_require_auth` to the constructor.
|
|
218
|
-
- **C++:** `XCiteDBClient::create_test_session(options)` after setting `api_key
|
|
218
|
+
- **JavaScript/TypeScript:** `XCiteDBClient.createTestSession({ baseUrl, apiKey, … })` returns a client configured with `testSessionToken`; optional **`overlay: true`** for overlay mode; optional `testRequireAuth: true` maps to `X-Test-Auth: required`. `destroyTestSession()` calls `DELETE …/test/sessions/current`.
|
|
219
|
+
- **Python:** `async with XCiteDBClient.test_session(base_url, api_key=…, …)` provisions and tears down; or pass `test_session_token` / `test_require_auth` to the constructor. For overlay until the helper accepts a flag, call **`POST /api/v1/test/sessions`** with JSON **`{"overlay":true}`** then construct the client with the returned token.
|
|
220
|
+
- **C++:** `XCiteDBClient::create_test_session(options)` after setting `api_key`, optional **`test_session_overlay = true`**, and optional `test_require_auth`; `destroy_test_session()`.
|
|
219
221
|
|
|
220
222
|
**JavaScript/TypeScript — complete test scaffold (Vitest / Jest):**
|
|
221
223
|
|
|
@@ -529,7 +531,7 @@ Can also use `"query"` instead of `"identifier"` to target multiple documents by
|
|
|
529
531
|
|
|
530
532
|
# Search
|
|
531
533
|
|
|
532
|
-
Full-text search (
|
|
534
|
+
Full-text search uses **embedded XciteFTS** (LMDB index per project). **Semantic** and **hybrid** (FTS + vector) search are available when vector search is enabled in project settings. The JSON field **`mode`** selects behavior (`auto` picks the best option for the project, or set `fts`, `semantic`, or `hybrid` explicitly).
|
|
533
535
|
|
|
534
536
|
**Base path:** `/api/v1/search`
|
|
535
537
|
|
|
@@ -543,15 +545,26 @@ Full-text search (backed by Meilisearch or Elasticsearch).
|
|
|
543
545
|
"doc_types": ["xml", "json"],
|
|
544
546
|
"branch": "",
|
|
545
547
|
"limit": 20,
|
|
546
|
-
"offset": 0
|
|
548
|
+
"offset": 0,
|
|
549
|
+
"mode": "fts"
|
|
547
550
|
}
|
|
548
551
|
```
|
|
549
552
|
|
|
550
|
-
|
|
553
|
+
Optional fields (also on SDK `TextSearchQuery` and the MCP `search` tool): **`min_score`**, **`semantic_weight`** for semantic/hybrid.
|
|
554
|
+
|
|
555
|
+
**Temporal FTS** (posting intervals; applies to the FTS keyword index—use **`mode`: `"fts"`** for pure temporal keyword search, or hybrid where the FTS leg participates):
|
|
556
|
+
|
|
557
|
+
| Field | Meaning |
|
|
558
|
+
|-------|---------|
|
|
559
|
+
| **`at_date`** | Date string (e.g. ISO `YYYY-MM-DD` or `mm/dd/yyyy` as accepted by the server). A posting matches if it is valid at that instant: `start <= at_date < end` (internal 7-char keys after `date2key`). |
|
|
560
|
+
| **`date_from`**, **`date_to`** | Date strings defining a half-open range `[date_from, date_to)`. A posting matches if its `[start, end)` **overlaps** that range. Either bound may be omitted (open-ended). |
|
|
561
|
+
| *(none of the three)* | **Current-time** view: only postings whose interval is still “open” (end at the internal max sentinel) are included. |
|
|
562
|
+
|
|
563
|
+
**Response:** `{ hits: [...], total, query }`. Each hit has **`identifier`**, **`path`**, **`doc_type`**, **`branch`**, **`snippet`**, **`score`**, and optionally **`xcitepath`** (XML). Semantic/hybrid hits may include **`source`**: `fts` \| `semantic` \| `both`. When the server infers a temporal window for the matched term(s), hits may include **`valid_from`** and **`valid_to`** as **7-character internal date keys** (same alphabet as revision keys—not ISO). Omitted for full-range/unversioned postings or when not computed.
|
|
551
564
|
|
|
552
565
|
## Reindex
|
|
553
566
|
|
|
554
|
-
**`POST /api/v1/search/reindex`** — Rebuilds the search index.
|
|
567
|
+
**`POST /api/v1/search/reindex`** — Rebuilds the full-text search index.
|
|
555
568
|
|
|
556
569
|
---
|
|
557
570
|
|
|
@@ -1411,7 +1424,7 @@ interface DatabaseContext {
|
|
|
1411
1424
|
- `findLocks(identifier)` → `LockInfo[]`
|
|
1412
1425
|
|
|
1413
1426
|
### Search
|
|
1414
|
-
- `search(query: TextSearchQuery)` → `TextSearchResult`
|
|
1427
|
+
- `search(query: TextSearchQuery)` → `TextSearchResult`. Query may include **`at_date`**, **`date_from`**, **`date_to`** (ISO-style or `mm/dd/yyyy` strings) for temporal FTS; set **`mode`: `"fts"`** for keyword-only temporal search. Hits may include **`valid_from`** / **`valid_to`** (7-char internal keys) when the server returns an inferred validity window.
|
|
1415
1428
|
- `reindex()` → `{ status, message }`
|
|
1416
1429
|
|
|
1417
1430
|
### Unquery
|
|
@@ -1544,6 +1557,7 @@ async def main():
|
|
|
1544
1557
|
print(await client.read_json_document("app.settings"))
|
|
1545
1558
|
print(await client.list_identifiers(XCiteQuery(match_start="/manual/")))
|
|
1546
1559
|
print(await client.search(TextSearchQuery(query="guide", limit=10)))
|
|
1560
|
+
# Temporal FTS: await client.search(TextSearchQuery(query="guide", mode="fts", at_date="2024-06-01"))
|
|
1547
1561
|
await client.platform_login("admin@localhost", "password")
|
|
1548
1562
|
# await client.login_app_user("user@example.com", "pw") # set context.project_id / tenant_id if needed
|
|
1549
1563
|
async with client.with_workspace("feature-x", message="WIP", auto_merge=True):
|
package/llms.txt
CHANGED
|
@@ -22,7 +22,7 @@ These are the most common sources of confusion for developers and AI assistants:
|
|
|
22
22
|
|
|
23
23
|
8. **Project vs tenant id.** In the SDK, prefer `context.project_id` (and `listMyProjects` / `switchProject`). Many JSON bodies and JWT claims still use the field name `tenant_id` for the same value — the client sends that wire name automatically.
|
|
24
24
|
|
|
25
|
-
9. **Ephemeral test sessions (wet tests).** Call **`POST /api/v1/test/sessions`** with a normal API key or Bearer token to get a `session_token` (UUID). Send **`X-Test-Session: <token>`** on subsequent document/API calls to use an isolated, short-lived LMDB instead of production data. By default **developer** auth (API key / platform JWT) is bypassed, but **app-user** identity (`X-App-User-Token` or Bearer app-user JWT) is still recognized. Send **`X-Test-Auth: required`** to exercise full developer JWT/API-key auth and ABAC against the same test database. Do not send `X-Test-Session` on `/api/v1/test/*` management routes. Server limits apply (`test.session_ttl_seconds`, `test.max_sessions_per_key`, `test.max_test_db_size_bytes` in config).
|
|
25
|
+
9. **Ephemeral test sessions (wet tests).** Call **`POST /api/v1/test/sessions`** with a normal API key or Bearer token to get a `session_token` (UUID). Send **`X-Test-Session: <token>`** on subsequent document/API calls to use an isolated, short-lived LMDB instead of production data. By default **developer** auth (API key / platform JWT) is bypassed, but **app-user** identity (`X-App-User-Token` or Bearer app-user JWT) is still recognized. Send **`X-Test-Auth: required`** to exercise full developer JWT/API-key auth and ABAC against the same test database. Do not send `X-Test-Session` on `/api/v1/test/*` management routes. Server limits apply (`test.session_ttl_seconds`, `test.max_sessions_per_key`, `test.max_test_db_size_bytes` in config). By default the test LMDB starts **empty** (no production data). **Overlay mode:** same **`POST`** with JSON body **`{"overlay":true}`** (while authenticated for the project you want to inspect—project-scoped API key, or platform Bearer + **`X-Project-Id`**). The server opens a **writable** LMDB under `_test/<uuid>/` with that project’s on-disk store as a **read-only base** (dual LMDB): reads see production + overlay deltas; **writes never touch production**. **`XCiteDBClient.createTestSession({ …, overlay: true })`** sends that body. After creation, only **`X-Test-Session`** is required on requests (overlay is stored in session metadata).
|
|
26
26
|
|
|
27
27
|
## Choosing the Right Versioning Approach
|
|
28
28
|
|
|
@@ -58,7 +58,7 @@ Legacy REST paths (`/api/v1/branches`, `/commits`, `/tags`, `/diff`) remain as *
|
|
|
58
58
|
|
|
59
59
|
6. **Self-registration uses server-configured default groups.** `registerAppUser()` assigns groups from the server's `auth.app_users.default_groups` config, not from the client request. To set groups explicitly, use **`createAppUser`** with a `groups` array (e.g. `[XCiteDBClient.buildProjectGroup(projectId, 'editor')]`) or **`updateAppUserGroups`**. The server rejects `project:<x>:*` groups when `<x>` is not a known internal project id (avoids mistaking the display name for the tenant id).
|
|
60
60
|
|
|
61
|
-
7. **Do not mock XciteDB in tests — use ephemeral test sessions instead.** Unlike most BaaS platforms, XciteDB has built-in support for isolated, throwaway database sessions specifically designed for wet integration tests. Mocking the client skips the actual storage, versioning, querying, and ABAC behavior, producing tests that don't catch real integration issues. Use `createTestSession()` / `test_session()` / `create_test_session()` (SDK helpers) or `POST /api/v1/test/sessions` directly to get a real
|
|
61
|
+
7. **Do not mock XciteDB in tests — use ephemeral test sessions instead.** Unlike most BaaS platforms, XciteDB has built-in support for isolated, throwaway database sessions specifically designed for wet integration tests. Mocking the client skips the actual storage, versioning, querying, and ABAC behavior, producing tests that don't catch real integration issues. Use `createTestSession()` / `test_session()` / `create_test_session()` (SDK helpers) or `POST /api/v1/test/sessions` directly to get a real LMDB that is scoped under `_test/<uuid>/` and destroyed after the test (empty by default, or **overlay** on read-only production when you pass **`{"overlay":true}`** / **`overlay: true`**). See "Test mode" below.
|
|
62
62
|
|
|
63
63
|
8. **403 on writes with ABAC is often a JWT/group string mismatch.** Decode the app-user access token early: log **`tenant_id`**, **`groups`**, **`sub`**. The middle segment of every **`project:<x>:role`** group must equal **`tenant_id`** exactly. Document write denials may return JSON fields **`policy_id`** and **`hint`** alongside `"Forbidden"`.
|
|
64
64
|
|
|
@@ -105,11 +105,11 @@ await app.writeJsonDocument('userdata/alice/profile', { ok: true });
|
|
|
105
105
|
|
|
106
106
|
> **AI assistant instruction:** XciteDB has built-in ephemeral test session support — this capability is **not standard** in most BaaS platforms and is specifically designed to enable meaningful wet integration tests. When writing tests for code that uses XciteDB, **do not mock or stub the XciteDB client**. Instead, use the test session pattern below to run tests against a real, isolated, throwaway database. This produces far more reliable tests because real storage, versioning, querying, and access-control behavior is exercised.
|
|
107
107
|
|
|
108
|
-
1. **Provision:** `POST /api/v1/test/sessions` with `Authorization: Bearer …` or `X-API-Key` (same as normal API access). Response JSON includes the session token.
|
|
109
|
-
2. **Run tests:** Every request that should hit the throwaway DB must include **`X-Test-Session: <token>`** (and your usual `X-Workspace` / `context` as needed). Data
|
|
108
|
+
1. **Provision:** `POST /api/v1/test/sessions` with `Authorization: Bearer …` or `X-API-Key` (same as normal API access). Optional JSON body **`{"overlay":true}`** creates an **overlay** session (read-through production, writes only under `_test/<session>/`). Response JSON includes the session token (and **`"overlay": true`** when applicable).
|
|
109
|
+
2. **Run tests:** Every request that should hit the throwaway DB must include **`X-Test-Session: <token>`** (and your usual `X-Workspace` / `context` as needed). Data writes go under the server’s `_test/<session>/` tree; overlay sessions **do not** write to production paths.
|
|
110
110
|
3. **Auth behavior:** Developer auth (API key / platform JWT) is bypassed by default for frictionless tests. **App-user identity** (`X-App-User-Token` or Bearer app-user JWT) **is still recognized** in default mode, so `registerAppUser` → `loginAppUser` → `appUserMe` works inside a test session. To also exercise developer auth and ABAC policies, set **`X-Test-Auth: required`** and send normal credentials; the DB is still the test session’s.
|
|
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
|
-
5. **SDKs:** **JS/TS:** `XCiteDBClient.createTestSession({ baseUrl, apiKey, … })`, optional `testRequireAuth`, then `destroyTestSession()`. **Python:** `async with XCiteDBClient.test_session(...)` or
|
|
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
114
|
## JavaScript/TypeScript SDK (`@xcitedbs/client`)
|
|
115
115
|
|
|
@@ -177,8 +177,10 @@ const lock = await client.acquireLock('/manual/v1/intro');
|
|
|
177
177
|
// ... edit ...
|
|
178
178
|
await client.releaseLock('/manual/v1/intro', lock.lock_id);
|
|
179
179
|
|
|
180
|
-
// Full-text search (
|
|
181
|
-
const results = await client.search({ query: 'installation guide', limit: 20 });
|
|
180
|
+
// Full-text search (embedded XciteFTS; optional temporal filters on the query body)
|
|
181
|
+
const results = await client.search({ query: 'installation guide', limit: 20, mode: 'fts' });
|
|
182
|
+
// Point-in-time keyword search: { query: '...', mode: 'fts', at_date: '2024-06-01' }
|
|
183
|
+
// Range overlap: { query: '...', mode: 'fts', date_from: '2024-01-01', date_to: '2025-01-01' }
|
|
182
184
|
|
|
183
185
|
// Subscribe to real-time changes via WebSocket
|
|
184
186
|
const sub = client.subscribe(
|
|
@@ -263,7 +265,7 @@ interface XCiteDBClientOptions {
|
|
|
263
265
|
- `findLocks(identifier)` — Query active locks
|
|
264
266
|
|
|
265
267
|
**Search & Analytics:**
|
|
266
|
-
- `search(query)` — Full-text search
|
|
268
|
+
- `search(query)` — Full-text search (embedded FTS). Optional **`at_date`**, **`date_from`**, **`date_to`** on the query for temporal keyword search (use **`mode: 'fts'`**). Hits may include **`valid_from`** / **`valid_to`** (7-char internal keys).
|
|
267
269
|
- `reindex()` — Rebuild search index
|
|
268
270
|
- `unquery(query, unqueryDoc)` — Execute Unquery DSL
|
|
269
271
|
|
|
@@ -338,6 +340,7 @@ async def main():
|
|
|
338
340
|
await client.write_json_document("app.settings", {"theme": "dark"})
|
|
339
341
|
print(await client.read_json_document("app.settings"))
|
|
340
342
|
print(await client.search(TextSearchQuery(query="guide", limit=10)))
|
|
343
|
+
# Temporal FTS: TextSearchQuery(query="guide", mode="fts", at_date="2024-06-01")
|
|
341
344
|
pair = await client.platform_login("admin@localhost", "password")
|
|
342
345
|
# await client.login_app_user("user@example.com", "secret", tenant_id="...")
|
|
343
346
|
|
|
@@ -378,7 +381,7 @@ auto ids = client.query_documents(q);
|
|
|
378
381
|
- Documents — XML document CRUD, identifiers, hierarchy
|
|
379
382
|
- JSON documents — JSON document CRUD
|
|
380
383
|
- Metadata — JSON metadata on documents
|
|
381
|
-
- Search — Full-text
|
|
384
|
+
- Search — Full-text (embedded FTS; optional temporal `at_date` / `date_from` / `date_to`; hit `valid_from` / `valid_to`)
|
|
382
385
|
- Unquery — Declarative query DSL
|
|
383
386
|
- Workspaces — Isolated editing environments
|
|
384
387
|
- Checkpoints & bookmarks — Named snapshots and references
|