@riffdb/client 0.2.1 → 0.2.3
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 +2 -2
- package/dist/driver.d.ts +6 -5
- package/dist/driver.js +132 -30
- package/dist/index.d.ts +40 -1
- package/dist/index.js +37 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,8 +7,8 @@ compiler IDs, storage keys, or an authorization bypass.
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install --save-dev @riffdb/cli@0.2.
|
|
11
|
-
npm install @riffdb/client@0.2.
|
|
10
|
+
npm install --save-dev @riffdb/cli@0.2.3
|
|
11
|
+
npm install @riffdb/client@0.2.3
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
## Four-step application story
|
package/dist/driver.d.ts
CHANGED
|
@@ -61,11 +61,11 @@ export declare function exactMoney<const Currency extends string>(currency: Curr
|
|
|
61
61
|
export interface DriverApplicationIdentity {
|
|
62
62
|
readonly applicationManifestHash?: string;
|
|
63
63
|
readonly operationCatalogHash?: string;
|
|
64
|
-
readonly contractLineage
|
|
65
|
-
readonly contractVersion
|
|
66
|
-
readonly contractBundleHash
|
|
64
|
+
readonly contractLineage?: string;
|
|
65
|
+
readonly contractVersion?: bigint;
|
|
66
|
+
readonly contractBundleHash?: string;
|
|
67
67
|
readonly database?: string;
|
|
68
|
-
readonly role
|
|
68
|
+
readonly role?: string;
|
|
69
69
|
readonly roleDefinitionHash?: string;
|
|
70
70
|
readonly remoteIdentityHash?: string;
|
|
71
71
|
readonly tenant?: string;
|
|
@@ -84,7 +84,7 @@ export interface ResolvedDriverApplicationIdentity {
|
|
|
84
84
|
}
|
|
85
85
|
export interface DriverApplicationTransportOptions {
|
|
86
86
|
readonly socketPath: string;
|
|
87
|
-
readonly identity
|
|
87
|
+
readonly identity?: DriverApplicationIdentity;
|
|
88
88
|
readonly tenant?: string;
|
|
89
89
|
}
|
|
90
90
|
export interface DriverConnectFromEnvOptions {
|
|
@@ -95,6 +95,7 @@ export interface DriverConnectFromEnvOptions {
|
|
|
95
95
|
readonly tenant?: string;
|
|
96
96
|
readonly prefix?: string;
|
|
97
97
|
readonly envPrefix?: string;
|
|
98
|
+
readonly env?: Readonly<Record<string, string | undefined>>;
|
|
98
99
|
}
|
|
99
100
|
export interface DriverOperation {
|
|
100
101
|
readonly name: string;
|
package/dist/driver.js
CHANGED
|
@@ -61,6 +61,7 @@ export class DriverApplicationError extends Error {
|
|
|
61
61
|
* surface. Those semantics remain owned by the Rust host.
|
|
62
62
|
*/
|
|
63
63
|
export class DriverApplicationTransport {
|
|
64
|
+
#socketPath;
|
|
64
65
|
#socket;
|
|
65
66
|
#identity;
|
|
66
67
|
#resolvedIdentity;
|
|
@@ -71,15 +72,39 @@ export class DriverApplicationTransport {
|
|
|
71
72
|
#inputLength = 0;
|
|
72
73
|
#nextRequest = 1;
|
|
73
74
|
#closed = false;
|
|
74
|
-
|
|
75
|
+
#disconnected = false;
|
|
76
|
+
#reconnecting;
|
|
77
|
+
constructor(socketPath, socket, identity, tenant) {
|
|
78
|
+
this.#socketPath = socketPath;
|
|
75
79
|
this.#socket = socket;
|
|
76
80
|
this.#identity = identity;
|
|
77
81
|
this.#tenant = tenant;
|
|
78
82
|
nextSession = nextSession === Number.MAX_SAFE_INTEGER ? 1 : nextSession + 1;
|
|
79
83
|
this.#requestPrefix = `ts.${process.pid}.${nextSession}`;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
this.#attachSocket(socket);
|
|
85
|
+
}
|
|
86
|
+
#attachSocket(socket) {
|
|
87
|
+
socket.on("data", (chunk) => {
|
|
88
|
+
if (this.#socket !== socket)
|
|
89
|
+
return;
|
|
90
|
+
this.#receive(chunk);
|
|
91
|
+
});
|
|
92
|
+
socket.on("error", () => {
|
|
93
|
+
if (this.#socket !== socket)
|
|
94
|
+
return;
|
|
95
|
+
this.#disconnected = true;
|
|
96
|
+
this.#inputChunks.length = 0;
|
|
97
|
+
this.#inputLength = 0;
|
|
98
|
+
this.#fail(new Error("RiffDB driver session failed"));
|
|
99
|
+
});
|
|
100
|
+
socket.on("close", () => {
|
|
101
|
+
if (this.#socket !== socket)
|
|
102
|
+
return;
|
|
103
|
+
this.#disconnected = true;
|
|
104
|
+
this.#inputChunks.length = 0;
|
|
105
|
+
this.#inputLength = 0;
|
|
106
|
+
this.#fail(new Error("RiffDB driver session closed"));
|
|
107
|
+
});
|
|
83
108
|
}
|
|
84
109
|
/** Returns the bound tenant identifier when this session is tenant-scoped. */
|
|
85
110
|
get tenant() {
|
|
@@ -101,7 +126,7 @@ export class DriverApplicationTransport {
|
|
|
101
126
|
socket.once("connect", () => { socket.off("error", onError); resolve(); });
|
|
102
127
|
socket.once("error", onError);
|
|
103
128
|
});
|
|
104
|
-
const transport = new DriverApplicationTransport(socket, options.identity, tenant);
|
|
129
|
+
const transport = new DriverApplicationTransport(options.socketPath, socket, options.identity ?? {}, tenant);
|
|
105
130
|
try {
|
|
106
131
|
await transport.#handshake();
|
|
107
132
|
return transport;
|
|
@@ -117,6 +142,12 @@ export class DriverApplicationTransport {
|
|
|
117
142
|
async invoke(operation, input, options = {}) {
|
|
118
143
|
validateOperation(operation);
|
|
119
144
|
validateDriverRecord(input);
|
|
145
|
+
const lowered = lowerOptions(options);
|
|
146
|
+
if (options.signal?.aborted)
|
|
147
|
+
throw new Error("RiffDB driver request aborted");
|
|
148
|
+
if (this.#disconnected || this.#socket.destroyed) {
|
|
149
|
+
await this.#ensureConnected();
|
|
150
|
+
}
|
|
120
151
|
const requestId = this.#requestId("invoke");
|
|
121
152
|
const response = await this.#request({
|
|
122
153
|
type: "invoke",
|
|
@@ -124,7 +155,7 @@ export class DriverApplicationTransport {
|
|
|
124
155
|
operation: operation.name,
|
|
125
156
|
input_schema_hash: operation.inputSchemaHash,
|
|
126
157
|
input,
|
|
127
|
-
options:
|
|
158
|
+
options: lowered,
|
|
128
159
|
}, requestId, options.signal);
|
|
129
160
|
return decodeResult(response);
|
|
130
161
|
}
|
|
@@ -139,6 +170,12 @@ export class DriverApplicationTransport {
|
|
|
139
170
|
}
|
|
140
171
|
for (const input of items)
|
|
141
172
|
validateDriverRecord(input);
|
|
173
|
+
const lowered = lowerOptions(options);
|
|
174
|
+
if (options.signal?.aborted)
|
|
175
|
+
throw new Error("RiffDB driver request aborted");
|
|
176
|
+
if (this.#disconnected || this.#socket.destroyed) {
|
|
177
|
+
await this.#ensureConnected();
|
|
178
|
+
}
|
|
142
179
|
const requestId = this.#requestId("batch");
|
|
143
180
|
const response = await this.#request({
|
|
144
181
|
type: "batch",
|
|
@@ -148,7 +185,7 @@ export class DriverApplicationTransport {
|
|
|
148
185
|
items,
|
|
149
186
|
concurrency,
|
|
150
187
|
checkpoint,
|
|
151
|
-
options:
|
|
188
|
+
options: lowered,
|
|
152
189
|
}, requestId, options.signal);
|
|
153
190
|
return decodeBatchResult(response, items.length, checkpoint);
|
|
154
191
|
}
|
|
@@ -157,6 +194,7 @@ export class DriverApplicationTransport {
|
|
|
157
194
|
if (this.#closed)
|
|
158
195
|
return;
|
|
159
196
|
this.#closed = true;
|
|
197
|
+
this.#disconnected = true;
|
|
160
198
|
this.#fail(new Error("RiffDB driver session closed"));
|
|
161
199
|
await new Promise((resolve) => {
|
|
162
200
|
if (this.#socket.destroyed) {
|
|
@@ -166,12 +204,60 @@ export class DriverApplicationTransport {
|
|
|
166
204
|
this.#socket.end(resolve);
|
|
167
205
|
});
|
|
168
206
|
}
|
|
207
|
+
async #ensureConnected() {
|
|
208
|
+
if (this.#closed)
|
|
209
|
+
throw new Error("RiffDB driver session closed");
|
|
210
|
+
if (!this.#disconnected && !this.#socket.destroyed)
|
|
211
|
+
return;
|
|
212
|
+
if (this.#reconnecting !== undefined) {
|
|
213
|
+
await this.#reconnecting;
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const task = (async () => {
|
|
217
|
+
const socket = createConnection({ path: this.#socketPath });
|
|
218
|
+
await new Promise((resolve, reject) => {
|
|
219
|
+
const onError = () => reject(new Error("RiffDB driver session failed"));
|
|
220
|
+
socket.once("connect", () => { socket.off("error", onError); resolve(); });
|
|
221
|
+
socket.once("error", onError);
|
|
222
|
+
});
|
|
223
|
+
if (this.#closed) {
|
|
224
|
+
socket.destroy();
|
|
225
|
+
throw new Error("RiffDB driver session closed");
|
|
226
|
+
}
|
|
227
|
+
this.#socket = socket;
|
|
228
|
+
this.#inputChunks.length = 0;
|
|
229
|
+
this.#inputLength = 0;
|
|
230
|
+
this.#disconnected = false;
|
|
231
|
+
this.#attachSocket(socket);
|
|
232
|
+
try {
|
|
233
|
+
await this.#handshake();
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
this.#disconnected = true;
|
|
237
|
+
socket.destroy();
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
})();
|
|
241
|
+
this.#reconnecting = task;
|
|
242
|
+
try {
|
|
243
|
+
await task;
|
|
244
|
+
}
|
|
245
|
+
finally {
|
|
246
|
+
if (this.#reconnecting === task) {
|
|
247
|
+
this.#reconnecting = undefined;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
169
251
|
async #handshake() {
|
|
170
252
|
const requestId = this.#requestId("handshake");
|
|
171
253
|
const identity = this.#identity;
|
|
172
254
|
const manifestHash = identity.applicationManifestHash ?? "";
|
|
173
255
|
const catalogHash = identity.operationCatalogHash ?? "";
|
|
256
|
+
const contractLineage = identity.contractLineage ?? "";
|
|
257
|
+
const contractVersion = identity.contractVersion ?? 0n;
|
|
258
|
+
const contractBundleHash = identity.contractBundleHash ?? "";
|
|
174
259
|
const database = identity.database ?? "";
|
|
260
|
+
const role = identity.role ?? "";
|
|
175
261
|
const roleDefinitionHash = identity.roleDefinitionHash ?? "";
|
|
176
262
|
const remoteIdentityHash = identity.remoteIdentityHash ?? "";
|
|
177
263
|
const response = await this.#request({
|
|
@@ -180,16 +266,17 @@ export class DriverApplicationTransport {
|
|
|
180
266
|
protocol_version: DRIVER_PROTOCOL_VERSION,
|
|
181
267
|
application_manifest_hash: manifestHash,
|
|
182
268
|
operation_catalog_hash: catalogHash,
|
|
183
|
-
contract_lineage:
|
|
184
|
-
contract_version:
|
|
185
|
-
contract_bundle_hash:
|
|
269
|
+
contract_lineage: contractLineage,
|
|
270
|
+
contract_version: contractVersion,
|
|
271
|
+
contract_bundle_hash: contractBundleHash,
|
|
186
272
|
value_registry_hash: DRIVER_VALUE_REGISTRY_HASH,
|
|
187
273
|
error_registry_hash: DRIVER_ERROR_REGISTRY_HASH,
|
|
188
274
|
database,
|
|
189
|
-
role
|
|
275
|
+
role,
|
|
190
276
|
role_definition_hash: roleDefinitionHash,
|
|
191
277
|
remote_identity_hash: remoteIdentityHash,
|
|
192
278
|
}, requestId);
|
|
279
|
+
const resolvedContractVersion = requiredPositiveBigInt(response.contract_version);
|
|
193
280
|
if (response.type !== "handshake"
|
|
194
281
|
|| response.protocol_version !== DRIVER_PROTOCOL_VERSION
|
|
195
282
|
|| typeof response.application_manifest_hash !== "string"
|
|
@@ -198,13 +285,19 @@ export class DriverApplicationTransport {
|
|
|
198
285
|
|| typeof response.operation_catalog_hash !== "string"
|
|
199
286
|
|| !HASH.test(response.operation_catalog_hash)
|
|
200
287
|
|| (catalogHash !== "" && response.operation_catalog_hash !== catalogHash)
|
|
201
|
-
|| response.contract_lineage !==
|
|
202
|
-
||
|
|
203
|
-
|| response.
|
|
288
|
+
|| typeof response.contract_lineage !== "string"
|
|
289
|
+
|| !SYMBOL.test(response.contract_lineage)
|
|
290
|
+
|| (contractLineage !== "" && response.contract_lineage !== contractLineage)
|
|
291
|
+
|| (contractVersion !== 0n && resolvedContractVersion !== contractVersion)
|
|
292
|
+
|| typeof response.contract_bundle_hash !== "string"
|
|
293
|
+
|| !HASH.test(response.contract_bundle_hash)
|
|
294
|
+
|| (contractBundleHash !== "" && response.contract_bundle_hash !== contractBundleHash)
|
|
204
295
|
|| typeof response.database !== "string"
|
|
205
296
|
|| !SYMBOL.test(response.database)
|
|
206
297
|
|| (database !== "" && response.database !== database)
|
|
207
|
-
|| response.role !==
|
|
298
|
+
|| typeof response.role !== "string"
|
|
299
|
+
|| !SYMBOL.test(response.role)
|
|
300
|
+
|| (role !== "" && response.role !== role)
|
|
208
301
|
|| typeof response.role_definition_hash !== "string"
|
|
209
302
|
|| !HASH.test(response.role_definition_hash)
|
|
210
303
|
|| (roleDefinitionHash !== "" && response.role_definition_hash !== roleDefinitionHash)
|
|
@@ -216,11 +309,11 @@ export class DriverApplicationTransport {
|
|
|
216
309
|
this.#resolvedIdentity = {
|
|
217
310
|
applicationManifestHash: response.application_manifest_hash,
|
|
218
311
|
operationCatalogHash: response.operation_catalog_hash,
|
|
219
|
-
contractLineage:
|
|
220
|
-
contractVersion:
|
|
221
|
-
contractBundleHash:
|
|
312
|
+
contractLineage: response.contract_lineage,
|
|
313
|
+
contractVersion: resolvedContractVersion,
|
|
314
|
+
contractBundleHash: response.contract_bundle_hash,
|
|
222
315
|
database: response.database,
|
|
223
|
-
role:
|
|
316
|
+
role: response.role,
|
|
224
317
|
roleDefinitionHash: response.role_definition_hash,
|
|
225
318
|
remoteIdentityHash: response.remote_identity_hash,
|
|
226
319
|
...(this.#tenant === undefined ? {} : { tenant: this.#tenant }),
|
|
@@ -277,6 +370,7 @@ export class DriverApplicationTransport {
|
|
|
277
370
|
while (this.#inputLength >= 4) {
|
|
278
371
|
const length = this.#peekFrameLength();
|
|
279
372
|
if (length < 2 || length > MAX_FRAME_BYTES) {
|
|
373
|
+
this.#closed = true;
|
|
280
374
|
this.#inputChunks.length = 0;
|
|
281
375
|
this.#inputLength = 0;
|
|
282
376
|
this.#fail(new Error("RiffDB driver returned an invalid frame"));
|
|
@@ -291,6 +385,7 @@ export class DriverApplicationTransport {
|
|
|
291
385
|
response = exactObject(decodeJson(UTF8_DECODER.decode(body)));
|
|
292
386
|
}
|
|
293
387
|
catch {
|
|
388
|
+
this.#closed = true;
|
|
294
389
|
this.#inputChunks.length = 0;
|
|
295
390
|
this.#inputLength = 0;
|
|
296
391
|
this.#fail(new Error("RiffDB driver returned an invalid message"));
|
|
@@ -299,6 +394,7 @@ export class DriverApplicationTransport {
|
|
|
299
394
|
}
|
|
300
395
|
const requestId = response.request_id;
|
|
301
396
|
if (typeof requestId !== "string" || !REQUEST_ID.test(requestId)) {
|
|
397
|
+
this.#closed = true;
|
|
302
398
|
this.#inputChunks.length = 0;
|
|
303
399
|
this.#inputLength = 0;
|
|
304
400
|
this.#fail(new Error("RiffDB driver returned an invalid request identity"));
|
|
@@ -878,7 +974,7 @@ const ENV_RESOLVED = Symbol("riffdb.envResolved");
|
|
|
878
974
|
function resolveTransportTenant(options) {
|
|
879
975
|
const allowEnvFallback = !(ENV_RESOLVED in options);
|
|
880
976
|
const envTenant = allowEnvFallback ? process.env.RIFFDB_TENANT : undefined;
|
|
881
|
-
const candidate = options.tenant ?? options.identity
|
|
977
|
+
const candidate = options.tenant ?? options.identity?.tenant ?? (envTenant && envTenant.length > 0 ? envTenant : undefined);
|
|
882
978
|
if (candidate === undefined)
|
|
883
979
|
return undefined;
|
|
884
980
|
if (typeof candidate !== "string" || candidate.length < 1 || candidate.length > 128 || !/^[\x21-\x7e]+$/.test(candidate)) {
|
|
@@ -907,9 +1003,10 @@ export function resolveTransportOptionsFromEnv(options = {}) {
|
|
|
907
1003
|
const candidatePrefixes = normalizedPrefix === "RIFFDB_" || normalizedPrefix.endsWith("RIFFDB_")
|
|
908
1004
|
? [normalizedPrefix]
|
|
909
1005
|
: [`${normalizedPrefix}RIFFDB_`, normalizedPrefix];
|
|
1006
|
+
const envSource = options.env ?? process.env;
|
|
910
1007
|
const readEnv = (suffix) => {
|
|
911
1008
|
for (const candidatePrefix of candidatePrefixes) {
|
|
912
|
-
const raw =
|
|
1009
|
+
const raw = envSource[`${candidatePrefix}${suffix}`];
|
|
913
1010
|
if (raw !== undefined && raw.trim().length > 0) {
|
|
914
1011
|
return raw.trim();
|
|
915
1012
|
}
|
|
@@ -924,7 +1021,10 @@ export function resolveTransportOptionsFromEnv(options = {}) {
|
|
|
924
1021
|
if (typeof rawVersion === "bigint") {
|
|
925
1022
|
contractVersion = rawVersion;
|
|
926
1023
|
}
|
|
927
|
-
else if (typeof rawVersion === "string"
|
|
1024
|
+
else if (typeof rawVersion === "string") {
|
|
1025
|
+
if (!/^[1-9][0-9]*$/.test(rawVersion)) {
|
|
1026
|
+
throw new Error("invalid RiffDB driver identity");
|
|
1027
|
+
}
|
|
928
1028
|
contractVersion = BigInt(rawVersion);
|
|
929
1029
|
}
|
|
930
1030
|
const contractBundleHash = base.contractBundleHash ?? readEnv("BUNDLE_HASH") ?? "";
|
|
@@ -960,10 +1060,10 @@ function validateTransportOptions(options) {
|
|
|
960
1060
|
throw new Error("invalid RiffDB driver socket path");
|
|
961
1061
|
}
|
|
962
1062
|
const identity = options.identity;
|
|
963
|
-
if (
|
|
964
|
-
|
|
965
|
-
}
|
|
1063
|
+
if (identity === undefined)
|
|
1064
|
+
return;
|
|
966
1065
|
for (const value of [
|
|
1066
|
+
identity.contractBundleHash,
|
|
967
1067
|
identity.applicationManifestHash, identity.operationCatalogHash,
|
|
968
1068
|
identity.roleDefinitionHash, identity.remoteIdentityHash,
|
|
969
1069
|
]) {
|
|
@@ -971,12 +1071,14 @@ function validateTransportOptions(options) {
|
|
|
971
1071
|
throw new Error("invalid RiffDB driver identity");
|
|
972
1072
|
}
|
|
973
1073
|
}
|
|
974
|
-
|
|
975
|
-
|
|
1074
|
+
for (const value of [identity.database, identity.contractLineage, identity.role]) {
|
|
1075
|
+
if (value !== undefined && value !== "" && !SYMBOL.test(value)) {
|
|
1076
|
+
throw new Error("invalid RiffDB driver identity");
|
|
1077
|
+
}
|
|
976
1078
|
}
|
|
977
|
-
if (
|
|
978
|
-
|
|
979
|
-
|| identity.contractVersion > 18446744073709551615n) {
|
|
1079
|
+
if (identity.contractVersion !== undefined
|
|
1080
|
+
&& identity.contractVersion !== 0n
|
|
1081
|
+
&& (identity.contractVersion < 1n || identity.contractVersion > 18446744073709551615n)) {
|
|
980
1082
|
throw new Error("invalid RiffDB driver identity");
|
|
981
1083
|
}
|
|
982
1084
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DriverApplicationTransport, type DriverApplicationError, type DriverApplicationTransportOptions, type DriverConnectFromEnvOptions, type DriverCompactQueryResult, type DriverPackedQueryResult, type DriverOperation } from "./driver.js";
|
|
1
|
+
import { DriverApplicationTransport, type DriverApplicationError, type DriverApplicationTransportOptions, type DriverBatchResult, type DriverConnectFromEnvOptions, type DriverCompactQueryResult, type DriverInvokeOptions, type DriverPackedQueryResult, type DriverOperation, type DriverResult, type DriverValue, type ResolvedDriverApplicationIdentity } from "./driver.js";
|
|
2
2
|
export type ApplicationValueSchema = {
|
|
3
3
|
readonly kind: "bool" | "i64" | "u64" | "string" | "uuid" | "bytes" | "date" | "timestamp" | "cursor" | "limit";
|
|
4
4
|
readonly maximumBytes?: number;
|
|
@@ -26,6 +26,7 @@ export type ApplicationValueSchema = {
|
|
|
26
26
|
readonly value: ApplicationValueSchema;
|
|
27
27
|
readonly minimum?: number;
|
|
28
28
|
readonly maximum?: number;
|
|
29
|
+
readonly unique?: boolean;
|
|
29
30
|
readonly aggregateCanonicalElementBytes?: number;
|
|
30
31
|
} | {
|
|
31
32
|
readonly kind: "record";
|
|
@@ -340,6 +341,10 @@ export declare class DriverGeneratedApplicationTransport {
|
|
|
340
341
|
static connectFromEnv(options?: DriverConnectFromEnvOptions): Promise<DriverGeneratedApplicationTransport>;
|
|
341
342
|
/** Returns the bound tenant identifier when this session is tenant-scoped. */
|
|
342
343
|
get tenant(): string | undefined;
|
|
344
|
+
/** Returns the resolved application identity verified during driver handshake. */
|
|
345
|
+
get identity(): ResolvedDriverApplicationIdentity;
|
|
346
|
+
invoke(operation: DriverOperation, input: Readonly<Record<string, DriverValue>>, options?: DriverInvokeOptions): Promise<DriverResult>;
|
|
347
|
+
batch(operation: DriverOperation, items: ReadonlyArray<Readonly<Record<string, DriverValue>>>, concurrency: number, checkpoint: number, options?: DriverInvokeOptions): Promise<DriverBatchResult>;
|
|
343
348
|
shutdown(): Promise<void>;
|
|
344
349
|
executeNamedQuery<P, R>(request: NamedQueryRequest<P, R>, options?: QueryOptions): Promise<TypedQueryResult<R>>;
|
|
345
350
|
executeCommand<I, R>(request: CommandRequest<I, R>, attemptBudget: number): Promise<TypedCommandResult<R>>;
|
|
@@ -373,5 +378,39 @@ export declare class DriverGeneratedApplicationTransport {
|
|
|
373
378
|
}): AsyncIterable<LiveQueryUpdate<T>>;
|
|
374
379
|
private mutateDriverLease;
|
|
375
380
|
}
|
|
381
|
+
declare module "./driver.js" {
|
|
382
|
+
interface DriverApplicationTransport {
|
|
383
|
+
executeNamedQuery<P, R>(request: NamedQueryRequest<P, R>, options?: QueryOptions): Promise<TypedQueryResult<R>>;
|
|
384
|
+
executeCommand<I, R>(request: CommandRequest<I, R>, attemptBudget: number): Promise<TypedCommandResult<R>>;
|
|
385
|
+
executeVectorInspection<P, R>(request: VectorInspectionRequest<P, R>, options?: VectorInspectionOptions): Promise<TypedVectorInspectionResult<R>>;
|
|
386
|
+
executeCommandBatch<I, R>(request: CommandRequest<I, R>, inputs: ReadonlyArray<I>, concurrency: number, checkpoint: number, attemptBudget: number): Promise<{
|
|
387
|
+
readonly items: ReadonlyArray<{
|
|
388
|
+
readonly index: number;
|
|
389
|
+
readonly result?: TypedCommandResult<R>;
|
|
390
|
+
readonly error?: DriverApplicationError;
|
|
391
|
+
}>;
|
|
392
|
+
readonly checkpoint: number;
|
|
393
|
+
}>;
|
|
394
|
+
consumeEventStream<P, E>(request: ReactiveConsumerRequest<P>, options?: ReactiveConsumerOptions): AsyncIterable<ReactiveConsumerBatch<E>>;
|
|
395
|
+
acknowledgeEvent<P>(request: ReactiveConsumerRequest<P>, delivery: ReactiveEventDelivery<unknown>): Promise<ReactiveEventMutationResult>;
|
|
396
|
+
negativeAcknowledgeEvent<P>(request: ReactiveConsumerRequest<P>, delivery: ReactiveEventDelivery<unknown>, retryDelayMs?: number): Promise<ReactiveEventMutationResult>;
|
|
397
|
+
seekEventConsumer<P>(request: ReactiveConsumerRequest<P>, checkpoint: string): Promise<ReactiveEventMutationResult>;
|
|
398
|
+
eventConsumerStatus<P>(request: ReactiveConsumerRequest<P>): Promise<ReactiveConsumerStatus | undefined>;
|
|
399
|
+
consumeContextualSubscription<P, E>(request: ReactiveConsumerRequest<P>, maximumWaitMs?: number, signal?: AbortSignal): Promise<ContextualBatch<E>>;
|
|
400
|
+
acknowledgeContextualItem<P>(request: ReactiveConsumerRequest<P>, item: ContextualWorkItem<unknown>): Promise<ReactiveEventMutationResult>;
|
|
401
|
+
negativeAcknowledgeContextualItem<P>(request: ReactiveConsumerRequest<P>, item: ContextualWorkItem<unknown>, retryDelayMs?: number): Promise<ReactiveEventMutationResult>;
|
|
402
|
+
contextualSubscriptionStatus<P>(request: ReactiveConsumerRequest<P>): Promise<ReactiveConsumerStatus | undefined>;
|
|
403
|
+
executeContextualReaction<P, I, R>(request: ReactiveConsumerRequest<P>, reaction: ContextualReaction, command: CommandRequest<I, R>): Promise<TypedCommandResult<R>>;
|
|
404
|
+
watchNamedQuery<P, T>(request: {
|
|
405
|
+
readonly driverOperations?: Readonly<Record<string, DriverOperation>>;
|
|
406
|
+
readonly reactiveModuleHash: string;
|
|
407
|
+
readonly operationName: string;
|
|
408
|
+
readonly parameters: P;
|
|
409
|
+
readonly parameterSchema: ApplicationValueSchema;
|
|
410
|
+
readonly cursor?: string;
|
|
411
|
+
readonly signal?: AbortSignal;
|
|
412
|
+
}): AsyncIterable<LiveQueryUpdate<T>>;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
376
415
|
export { DRIVER_ERROR_REGISTRY_HASH, DRIVER_PROTOCOL_VERSION, DRIVER_VALUE_REGISTRY_HASH, DriverApplicationError, DriverApplicationTransport, resolveTransportOptionsFromEnv, } from "./driver.js";
|
|
377
416
|
export type { DriverApplicationIdentity, DriverApplicationTransportOptions, DriverConnectFromEnvOptions, DriverBatchItem, DriverBatchResult, DriverBatchSuccess, DriverDecimal, DriverErrorDetails, DriverInvokeOptions, DriverMoney, DriverOperation, DriverPackedColumn, DriverPackedQueryResult, DriverResult, DriverTimestamp, DriverValue, ResolvedDriverApplicationIdentity, } from "./driver.js";
|
package/dist/index.js
CHANGED
|
@@ -647,6 +647,16 @@ export class DriverGeneratedApplicationTransport {
|
|
|
647
647
|
get tenant() {
|
|
648
648
|
return this.driver.tenant;
|
|
649
649
|
}
|
|
650
|
+
/** Returns the resolved application identity verified during driver handshake. */
|
|
651
|
+
get identity() {
|
|
652
|
+
return this.driver.identity;
|
|
653
|
+
}
|
|
654
|
+
async invoke(operation, input, options = {}) {
|
|
655
|
+
return this.driver.invoke(operation, input, options);
|
|
656
|
+
}
|
|
657
|
+
async batch(operation, items, concurrency, checkpoint, options = {}) {
|
|
658
|
+
return this.driver.batch(operation, items, concurrency, checkpoint, options);
|
|
659
|
+
}
|
|
650
660
|
async shutdown() {
|
|
651
661
|
await this.driver.shutdown();
|
|
652
662
|
}
|
|
@@ -821,6 +831,33 @@ export class DriverGeneratedApplicationTransport {
|
|
|
821
831
|
return decodeDriverMutationResult(requireDriverValue(result));
|
|
822
832
|
}
|
|
823
833
|
}
|
|
834
|
+
for (const methodName of [
|
|
835
|
+
"executeNamedQuery",
|
|
836
|
+
"executeCommand",
|
|
837
|
+
"executeVectorInspection",
|
|
838
|
+
"executeCommandBatch",
|
|
839
|
+
"consumeEventStream",
|
|
840
|
+
"acknowledgeEvent",
|
|
841
|
+
"negativeAcknowledgeEvent",
|
|
842
|
+
"seekEventConsumer",
|
|
843
|
+
"eventConsumerStatus",
|
|
844
|
+
"consumeContextualSubscription",
|
|
845
|
+
"acknowledgeContextualItem",
|
|
846
|
+
"negativeAcknowledgeContextualItem",
|
|
847
|
+
"contextualSubscriptionStatus",
|
|
848
|
+
"executeContextualReaction",
|
|
849
|
+
"watchNamedQuery",
|
|
850
|
+
]) {
|
|
851
|
+
Object.defineProperty(DriverApplicationTransport.prototype, methodName, {
|
|
852
|
+
configurable: true,
|
|
853
|
+
writable: true,
|
|
854
|
+
value(...args) {
|
|
855
|
+
const adapter = new DriverGeneratedApplicationTransport(this);
|
|
856
|
+
const fn = adapter[methodName];
|
|
857
|
+
return fn.apply(adapter, args);
|
|
858
|
+
},
|
|
859
|
+
});
|
|
860
|
+
}
|
|
824
861
|
function validateDriverReactiveRequest(value) {
|
|
825
862
|
if (!HASH.test(value.reactiveModuleHash) || !SYMBOL.test(value.operationName)) {
|
|
826
863
|
throw new Error("invalid generated reactive operation identity");
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"description":"First-party application runtime for the Rust-owned RiffDB driver host","engines":{"node":">=22"},"exports":{".":"./dist/index.js","./operator":"./dist/operator.js"},"files":["dist","README.md","conformance-manifest-v1.json"],"license":"MIT OR Apache-2.0","name":"@riffdb/client","repository":{"type":"git","url":"git+https://github.com/riffdb/riffdb.git"},"type":"module","types":"./dist/index.d.ts","version":"0.2.
|
|
1
|
+
{"description":"First-party application runtime for the Rust-owned RiffDB driver host","engines":{"node":">=22"},"exports":{".":"./dist/index.js","./operator":"./dist/operator.js"},"files":["dist","README.md","conformance-manifest-v1.json"],"license":"MIT OR Apache-2.0","name":"@riffdb/client","repository":{"type":"git","url":"git+https://github.com/riffdb/riffdb.git"},"type":"module","types":"./dist/index.d.ts","version":"0.2.3"}
|