@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 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.1
11
- npm install @riffdb/client@0.2.1
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: string;
65
- readonly contractVersion: bigint;
66
- readonly contractBundleHash: string;
64
+ readonly contractLineage?: string;
65
+ readonly contractVersion?: bigint;
66
+ readonly contractBundleHash?: string;
67
67
  readonly database?: string;
68
- readonly role: string;
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: DriverApplicationIdentity;
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
- constructor(socket, identity, tenant) {
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
- socket.on("data", (chunk) => this.#receive(chunk));
81
- socket.on("error", () => this.#fail(new Error("RiffDB driver session failed")));
82
- socket.on("close", () => this.#fail(new Error("RiffDB driver session closed")));
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: lowerOptions(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: lowerOptions(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: identity.contractLineage,
184
- contract_version: identity.contractVersion,
185
- contract_bundle_hash: identity.contractBundleHash,
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: identity.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 !== identity.contractLineage
202
- || requiredPositiveBigInt(response.contract_version) !== identity.contractVersion
203
- || response.contract_bundle_hash !== identity.contractBundleHash
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 !== identity.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: identity.contractLineage,
220
- contractVersion: identity.contractVersion,
221
- contractBundleHash: identity.contractBundleHash,
312
+ contractLineage: response.contract_lineage,
313
+ contractVersion: resolvedContractVersion,
314
+ contractBundleHash: response.contract_bundle_hash,
222
315
  database: response.database,
223
- role: identity.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.tenant ?? (envTenant && envTenant.length > 0 ? envTenant : undefined);
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 = process.env[`${candidatePrefix}${suffix}`];
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" && /^[0-9]+$/.test(rawVersion)) {
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 (!HASH.test(identity.contractBundleHash)) {
964
- throw new Error("invalid RiffDB driver identity");
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
- if (identity.database !== undefined && identity.database !== "" && !SYMBOL.test(identity.database)) {
975
- throw new Error("invalid RiffDB driver identity");
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 (!SYMBOL.test(identity.contractLineage)
978
- || !SYMBOL.test(identity.role) || identity.contractVersion < 1n
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"}
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"}