@anysoftinc/anydb-sdk 0.6.1 → 0.8.0
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 +63 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +115 -34
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -20,6 +20,27 @@ export interface SymbolicQuery {
|
|
|
20
20
|
where: QueryClause[];
|
|
21
21
|
in?: QueryValue[];
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Temporal query options following Datomic REST API.
|
|
25
|
+
* These options control which point-in-time view of the database to query.
|
|
26
|
+
*/
|
|
27
|
+
export interface TemporalOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Query the database as of a specific transaction time (t value).
|
|
30
|
+
* Returns the database as it existed at that point in time.
|
|
31
|
+
*/
|
|
32
|
+
"as-of"?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Query only facts added since a specific transaction time (t value).
|
|
35
|
+
* Returns only datoms that were added after that point in time.
|
|
36
|
+
*/
|
|
37
|
+
since?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Query the entire history of the database.
|
|
40
|
+
* When true, returns all historical facts including retractions.
|
|
41
|
+
*/
|
|
42
|
+
history?: boolean;
|
|
43
|
+
}
|
|
23
44
|
export type EntityId = number | string;
|
|
24
45
|
export type BasisT = number | "-";
|
|
25
46
|
export interface Datom {
|
|
@@ -95,11 +116,52 @@ export declare class AnyDBClient {
|
|
|
95
116
|
getStorageAlias(): string;
|
|
96
117
|
info(): Promise<DatabaseInfo>;
|
|
97
118
|
transact(txData: any[]): Promise<Transaction>;
|
|
98
|
-
|
|
119
|
+
/**
|
|
120
|
+
* Execute a query against the database with optional temporal options.
|
|
121
|
+
*
|
|
122
|
+
* @param q - The symbolic query to execute
|
|
123
|
+
* @param options - Optional temporal options (as-of, since, history) or additional query args
|
|
124
|
+
* @param args - Additional arguments to pass to the query
|
|
125
|
+
* @returns Query results as an array of tuples
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* // Query current state
|
|
129
|
+
* const results = await db.query({ find: [sym('?e')], where: [[sym('?e'), kw('person/name'), sym('?name')]] });
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* // Query as of a specific transaction time
|
|
133
|
+
* const results = await db.query(
|
|
134
|
+
* { find: [sym('?e')], where: [[sym('?e'), kw('person/name'), sym('?name')]] },
|
|
135
|
+
* { "as-of": 1000 }
|
|
136
|
+
* );
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* // Query entire history
|
|
140
|
+
* const results = await db.query(
|
|
141
|
+
* { find: [sym('?e'), sym('?name')], where: [[sym('?e'), kw('person/name'), sym('?name')]] },
|
|
142
|
+
* { history: true }
|
|
143
|
+
* );
|
|
144
|
+
*/
|
|
145
|
+
query(q: SymbolicQuery, options?: TemporalOptions | any, ...args: any[]): Promise<QueryResult>;
|
|
146
|
+
/**
|
|
147
|
+
* Retrieve an entity by ID with all its attributes.
|
|
148
|
+
*
|
|
149
|
+
* @param entityId - The entity ID to retrieve
|
|
150
|
+
* @param basisT - The basis-t value (currently unused, kept for API compatibility)
|
|
151
|
+
* @param options - Optional temporal options (as-of, since)
|
|
152
|
+
* @returns The entity with all its attributes
|
|
153
|
+
*/
|
|
99
154
|
entity(entityId: EntityId, basisT?: BasisT, options?: {
|
|
100
155
|
"as-of"?: number;
|
|
101
156
|
since?: number;
|
|
102
157
|
}): Promise<Entity>;
|
|
158
|
+
/**
|
|
159
|
+
* Retrieve datoms from an index with optional temporal options.
|
|
160
|
+
*
|
|
161
|
+
* @param index - The index to use (eavt, aevt, avet, vaet)
|
|
162
|
+
* @param options - Options including entity/attribute/value filters and temporal options
|
|
163
|
+
* @returns Array of datoms matching the criteria
|
|
164
|
+
*/
|
|
103
165
|
datoms(index: "eavt" | "aevt" | "avet" | "vaet", options?: {
|
|
104
166
|
e?: EntityId;
|
|
105
167
|
a?: string;
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -80,57 +80,67 @@ export function stringifyEdn(obj) {
|
|
|
80
80
|
}
|
|
81
81
|
return String(obj);
|
|
82
82
|
}
|
|
83
|
-
//
|
|
83
|
+
// ===== Type Guards =====
|
|
84
|
+
function isKeyword(v) {
|
|
85
|
+
return typeof v === "object" && v !== null && v._type === "keyword";
|
|
86
|
+
}
|
|
87
|
+
function isSymbol(v) {
|
|
88
|
+
return typeof v === "object" && v !== null && v._type === "symbol";
|
|
89
|
+
}
|
|
90
|
+
// Normalize edn-data parsed value into JS with consistent symbolic types
|
|
91
|
+
// Keywords and symbols are returned as typed objects for round-trip consistency
|
|
84
92
|
function normalizeEdn(value) {
|
|
85
93
|
if (value === null || value === undefined)
|
|
86
94
|
return value;
|
|
87
95
|
// Preserve native Date instances returned by the parser
|
|
88
96
|
if (value instanceof Date)
|
|
89
97
|
return value;
|
|
90
|
-
// edn-data
|
|
98
|
+
// edn-data wraps keywords/symbols as { key: '...' } or { sym: '...' }
|
|
91
99
|
if (typeof value === "object" && value) {
|
|
100
|
+
// Keywords: return as Keyword object for consistency with kw()
|
|
92
101
|
if (typeof value.key === "string") {
|
|
93
102
|
const key = value.key; // e.g., ":db/ident"
|
|
94
|
-
|
|
103
|
+
const bareKey = key.startsWith(":") ? key.slice(1) : key;
|
|
104
|
+
return { _type: "keyword", value: bareKey };
|
|
95
105
|
}
|
|
106
|
+
// Symbols: return as Symbol object for consistency with sym()
|
|
96
107
|
if (typeof value.sym === "string") {
|
|
97
|
-
return value.sym;
|
|
108
|
+
return { _type: "symbol", value: value.sym };
|
|
98
109
|
}
|
|
110
|
+
// Tagged values - check before generic object handling
|
|
111
|
+
if (value.tag === "inst" && typeof value.val === "string") {
|
|
112
|
+
const d = new Date(value.val);
|
|
113
|
+
return isNaN(d.getTime()) ? value.val : d;
|
|
114
|
+
}
|
|
115
|
+
if (value.tag === "uuid" && typeof value.val === "string") {
|
|
116
|
+
return { _type: "uuid", value: value.val };
|
|
117
|
+
}
|
|
118
|
+
// Sets
|
|
99
119
|
if (value instanceof Set) {
|
|
100
120
|
return Array.from(value, (v) => normalizeEdn(v));
|
|
101
121
|
}
|
|
102
122
|
if (Array.isArray(value.set)) {
|
|
103
123
|
return value.set.map((v) => normalizeEdn(v));
|
|
104
124
|
}
|
|
125
|
+
// Maps (EDN maps come as array of [k,v] pairs)
|
|
105
126
|
if (Array.isArray(value.map)) {
|
|
106
127
|
const out = {};
|
|
107
128
|
for (const [k, v] of value.map) {
|
|
108
129
|
const kNorm = normalizeEdn(k);
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
|
|
130
|
+
// Extract string key from symbolic types (Keyword, Symbol, UUID) for JS object keys
|
|
131
|
+
const kStr = (typeof kNorm === "object" && kNorm !== null && "_type" in kNorm && "value" in kNorm)
|
|
132
|
+
? kNorm.value
|
|
133
|
+
: kNorm;
|
|
134
|
+
out[kStr] = normalizeEdn(v);
|
|
112
135
|
}
|
|
113
136
|
return out;
|
|
114
137
|
}
|
|
115
138
|
}
|
|
116
139
|
if (Array.isArray(value))
|
|
117
140
|
return value.map((v) => normalizeEdn(v));
|
|
118
|
-
//
|
|
119
|
-
if (typeof value === "object" &&
|
|
120
|
-
value &&
|
|
121
|
-
value.tag === "inst" &&
|
|
122
|
-
typeof value.val === "string") {
|
|
123
|
-
const d = new Date(value.val);
|
|
124
|
-
return isNaN(d.getTime()) ? value.val : d;
|
|
125
|
-
}
|
|
126
|
-
if (typeof value === "object" &&
|
|
127
|
-
value &&
|
|
128
|
-
value.tag === "uuid" &&
|
|
129
|
-
typeof value.val === "string") {
|
|
130
|
-
return { _type: "uuid", value: value.val };
|
|
131
|
-
}
|
|
141
|
+
// Generic object fallback
|
|
132
142
|
if (typeof value === "object") {
|
|
133
|
-
const out =
|
|
143
|
+
const out = {};
|
|
134
144
|
for (const [k, v] of Object.entries(value)) {
|
|
135
145
|
out[k] = normalizeEdn(v);
|
|
136
146
|
}
|
|
@@ -139,12 +149,6 @@ function normalizeEdn(value) {
|
|
|
139
149
|
return value;
|
|
140
150
|
}
|
|
141
151
|
// ===== Validation =====
|
|
142
|
-
function isKeyword(v) {
|
|
143
|
-
return typeof v === "object" && v !== null && v._type === "keyword";
|
|
144
|
-
}
|
|
145
|
-
function isSymbol(v) {
|
|
146
|
-
return typeof v === "object" && v !== null && v._type === "symbol";
|
|
147
|
-
}
|
|
148
152
|
function validateSymbolicQuery(q) {
|
|
149
153
|
if (!q ||
|
|
150
154
|
typeof q !== "object" ||
|
|
@@ -317,24 +321,93 @@ export class AnyDBClient {
|
|
|
317
321
|
await this.ensureInitialized();
|
|
318
322
|
return this.client.transact(this.storageAlias, this.dbName, txData);
|
|
319
323
|
}
|
|
320
|
-
|
|
324
|
+
/**
|
|
325
|
+
* Execute a query against the database with optional temporal options.
|
|
326
|
+
*
|
|
327
|
+
* @param q - The symbolic query to execute
|
|
328
|
+
* @param options - Optional temporal options (as-of, since, history) or additional query args
|
|
329
|
+
* @param args - Additional arguments to pass to the query
|
|
330
|
+
* @returns Query results as an array of tuples
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* // Query current state
|
|
334
|
+
* const results = await db.query({ find: [sym('?e')], where: [[sym('?e'), kw('person/name'), sym('?name')]] });
|
|
335
|
+
*
|
|
336
|
+
* @example
|
|
337
|
+
* // Query as of a specific transaction time
|
|
338
|
+
* const results = await db.query(
|
|
339
|
+
* { find: [sym('?e')], where: [[sym('?e'), kw('person/name'), sym('?name')]] },
|
|
340
|
+
* { "as-of": 1000 }
|
|
341
|
+
* );
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* // Query entire history
|
|
345
|
+
* const results = await db.query(
|
|
346
|
+
* { find: [sym('?e'), sym('?name')], where: [[sym('?e'), kw('person/name'), sym('?name')]] },
|
|
347
|
+
* { history: true }
|
|
348
|
+
* );
|
|
349
|
+
*/
|
|
350
|
+
async query(q, options, ...args) {
|
|
321
351
|
await this.ensureInitialized();
|
|
322
352
|
// Server path: use /api/query with db descriptor as first arg
|
|
353
|
+
// Following Datomic REST API, temporal options are included in the db descriptor
|
|
323
354
|
const dbDescriptor = {
|
|
324
355
|
"db/alias": `${this.storageAlias}/${this.dbName}`,
|
|
325
356
|
};
|
|
326
|
-
|
|
357
|
+
// Check if options is a TemporalOptions object (has as-of, since, or history keys)
|
|
358
|
+
const isTemporalOptions = options && typeof options === 'object' &&
|
|
359
|
+
('as-of' in options || 'since' in options || 'history' in options);
|
|
360
|
+
if (isTemporalOptions) {
|
|
361
|
+
const temporalOpts = options;
|
|
362
|
+
if (temporalOpts["as-of"] !== undefined) {
|
|
363
|
+
dbDescriptor["as-of"] = temporalOpts["as-of"];
|
|
364
|
+
}
|
|
365
|
+
if (temporalOpts.since !== undefined) {
|
|
366
|
+
dbDescriptor["since"] = temporalOpts.since;
|
|
367
|
+
}
|
|
368
|
+
if (temporalOpts.history !== undefined) {
|
|
369
|
+
dbDescriptor["history"] = temporalOpts.history;
|
|
370
|
+
}
|
|
371
|
+
return this.client.querySymbolic(q, [dbDescriptor, ...args]);
|
|
372
|
+
}
|
|
373
|
+
else if (options !== undefined) {
|
|
374
|
+
// options is actually a query arg, not temporal options
|
|
375
|
+
return this.client.querySymbolic(q, [dbDescriptor, options, ...args]);
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
return this.client.querySymbolic(q, [dbDescriptor, ...args]);
|
|
379
|
+
}
|
|
327
380
|
}
|
|
381
|
+
/**
|
|
382
|
+
* Retrieve an entity by ID with all its attributes.
|
|
383
|
+
*
|
|
384
|
+
* @param entityId - The entity ID to retrieve
|
|
385
|
+
* @param basisT - The basis-t value (currently unused, kept for API compatibility)
|
|
386
|
+
* @param options - Optional temporal options (as-of, since)
|
|
387
|
+
* @returns The entity with all its attributes
|
|
388
|
+
*/
|
|
328
389
|
async entity(entityId, basisT = "-", options) {
|
|
329
|
-
// Use the query API to retrieve entity via pull
|
|
390
|
+
// Use the query API to retrieve entity via pull with wildcard to get all attributes
|
|
330
391
|
const q = {
|
|
331
|
-
find: [[sym("pull"), sym("?e"), [
|
|
392
|
+
find: [[sym("pull"), sym("?e"), [sym("*")]]],
|
|
332
393
|
where: [[sym("?e"), kw("db/id"), entityId]],
|
|
333
394
|
};
|
|
334
|
-
|
|
395
|
+
// Pass temporal options to query if provided
|
|
396
|
+
const temporalOpts = options ? {
|
|
397
|
+
"as-of": options["as-of"],
|
|
398
|
+
since: options.since,
|
|
399
|
+
} : undefined;
|
|
400
|
+
const rows = await this.query(q, temporalOpts);
|
|
335
401
|
const first = Array.isArray(rows) ? rows[0]?.[0] : null;
|
|
336
402
|
return first || { "db/id": entityId };
|
|
337
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* Retrieve datoms from an index with optional temporal options.
|
|
406
|
+
*
|
|
407
|
+
* @param index - The index to use (eavt, aevt, avet, vaet)
|
|
408
|
+
* @param options - Options including entity/attribute/value filters and temporal options
|
|
409
|
+
* @returns Array of datoms matching the criteria
|
|
410
|
+
*/
|
|
338
411
|
async datoms(index, options = {}) {
|
|
339
412
|
// Server exposes datoms via query; implement minimal AVET example
|
|
340
413
|
const clauses = [];
|
|
@@ -343,7 +416,15 @@ export class AnyDBClient {
|
|
|
343
416
|
const v = options.v !== undefined ? options.v : sym("?v");
|
|
344
417
|
clauses.push([e, a, v]);
|
|
345
418
|
const q = { find: [e, a, v], where: clauses };
|
|
346
|
-
|
|
419
|
+
// Build temporal options from the options parameter
|
|
420
|
+
const temporalOpts = (options["as-of"] !== undefined || options.since !== undefined || options.history !== undefined)
|
|
421
|
+
? {
|
|
422
|
+
"as-of": options["as-of"],
|
|
423
|
+
since: options.since,
|
|
424
|
+
history: options.history,
|
|
425
|
+
}
|
|
426
|
+
: undefined;
|
|
427
|
+
const rows = await this.query(q, temporalOpts);
|
|
347
428
|
return rows.map((r) => ({ e: r[0], a: r[1], v: r[2], tx: 0, added: true }));
|
|
348
429
|
}
|
|
349
430
|
subscribeToEvents(onEvent, onError) {
|