camusdb 0.6.0 → 0.7.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.
Files changed (87) hide show
  1. package/README.md +193 -0
  2. package/dist/client.d.ts +42 -37
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +117 -166
  5. package/dist/client.js.map +1 -1
  6. package/dist/config.d.ts +22 -0
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +19 -0
  9. package/dist/config.js.map +1 -1
  10. package/dist/endpoint-pool.d.ts +8 -0
  11. package/dist/endpoint-pool.d.ts.map +1 -1
  12. package/dist/endpoint-pool.js +25 -0
  13. package/dist/endpoint-pool.js.map +1 -1
  14. package/dist/index.d.ts +6 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +4 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/node-stats.d.ts +113 -0
  19. package/dist/node-stats.d.ts.map +1 -0
  20. package/dist/node-stats.js +90 -0
  21. package/dist/node-stats.js.map +1 -0
  22. package/dist/options.d.ts +10 -0
  23. package/dist/options.d.ts.map +1 -1
  24. package/dist/options.js +1 -0
  25. package/dist/options.js.map +1 -1
  26. package/dist/pipeline.d.ts +126 -0
  27. package/dist/pipeline.d.ts.map +1 -0
  28. package/dist/pipeline.js +363 -0
  29. package/dist/pipeline.js.map +1 -0
  30. package/dist/prepared/auto-prepare.d.ts +51 -0
  31. package/dist/prepared/auto-prepare.d.ts.map +1 -0
  32. package/dist/prepared/auto-prepare.js +150 -0
  33. package/dist/prepared/auto-prepare.js.map +1 -0
  34. package/dist/prepared/policy.d.ts +7 -0
  35. package/dist/prepared/policy.d.ts.map +1 -1
  36. package/dist/prepared/policy.js +16 -0
  37. package/dist/prepared/policy.js.map +1 -1
  38. package/dist/query-stream.d.ts +4 -1
  39. package/dist/query-stream.d.ts.map +1 -1
  40. package/dist/query-stream.js +13 -2
  41. package/dist/query-stream.js.map +1 -1
  42. package/dist/retry.d.ts +8 -0
  43. package/dist/retry.d.ts.map +1 -1
  44. package/dist/retry.js +12 -1
  45. package/dist/retry.js.map +1 -1
  46. package/dist/telemetry.d.ts +199 -0
  47. package/dist/telemetry.d.ts.map +1 -0
  48. package/dist/telemetry.js +422 -0
  49. package/dist/telemetry.js.map +1 -0
  50. package/dist/transaction.d.ts +60 -5
  51. package/dist/transaction.d.ts.map +1 -1
  52. package/dist/transaction.js +124 -24
  53. package/dist/transaction.js.map +1 -1
  54. package/dist/transport/authenticating-transport.d.ts +9 -1
  55. package/dist/transport/authenticating-transport.d.ts.map +1 -1
  56. package/dist/transport/authenticating-transport.js +13 -0
  57. package/dist/transport/authenticating-transport.js.map +1 -1
  58. package/dist/transport/grpc/batch-frames.d.ts +23 -5
  59. package/dist/transport/grpc/batch-frames.d.ts.map +1 -1
  60. package/dist/transport/grpc/batch-frames.js +29 -8
  61. package/dist/transport/grpc/batch-frames.js.map +1 -1
  62. package/dist/transport/grpc/batcher.d.ts +69 -5
  63. package/dist/transport/grpc/batcher.d.ts.map +1 -1
  64. package/dist/transport/grpc/batcher.js +217 -10
  65. package/dist/transport/grpc/batcher.js.map +1 -1
  66. package/dist/transport/grpc/grpc-transport.d.ts +35 -1
  67. package/dist/transport/grpc/grpc-transport.d.ts.map +1 -1
  68. package/dist/transport/grpc/grpc-transport.js +193 -7
  69. package/dist/transport/grpc/grpc-transport.js.map +1 -1
  70. package/dist/transport/grpc/messages.d.ts +15 -0
  71. package/dist/transport/grpc/messages.d.ts.map +1 -1
  72. package/dist/transport/grpc/messages.js +9 -0
  73. package/dist/transport/grpc/messages.js.map +1 -1
  74. package/dist/transport/rest-transport.d.ts +9 -1
  75. package/dist/transport/rest-transport.d.ts.map +1 -1
  76. package/dist/transport/rest-transport.js +24 -0
  77. package/dist/transport/rest-transport.js.map +1 -1
  78. package/dist/transport/sequential-pipeline.d.ts +21 -0
  79. package/dist/transport/sequential-pipeline.d.ts.map +1 -0
  80. package/dist/transport/sequential-pipeline.js +119 -0
  81. package/dist/transport/sequential-pipeline.js.map +1 -0
  82. package/dist/transport/transport.d.ts +94 -0
  83. package/dist/transport/transport.d.ts.map +1 -1
  84. package/dist/transport/transport.js +10 -0
  85. package/dist/transport/transport.js.map +1 -1
  86. package/package.json +10 -4
  87. package/proto/camus_sql.proto +114 -0
@@ -0,0 +1,422 @@
1
+ /**
2
+ * This file is part of CamusDB
3
+ *
4
+ * For the full copyright and license information, please view the LICENSE.txt
5
+ * file that was distributed with this source code.
6
+ */
7
+ import { createRequire } from 'node:module';
8
+ import { CamusEndpointPool } from './endpoint-pool.js';
9
+ import { CamusError } from './errors.js';
10
+ import { CamusPreparedStatementPolicy } from './prepared/policy.js';
11
+ /**
12
+ * Traces and metrics through `@opentelemetry/api`.
13
+ *
14
+ * The package is an optional peer dependency, as the gRPC packages are. When it is installed, the
15
+ * driver reports through the global tracer and meter that it names `camusdb`. When it is not
16
+ * installed, every function here returns at once and the driver reports nothing. Install an
17
+ * OpenTelemetry SDK and register it as usual to collect the data. The driver needs no plugin.
18
+ *
19
+ * The span and metric names and attributes are those of the .NET driver, and they follow the
20
+ * OpenTelemetry database conventions. See the README for the list.
21
+ */
22
+ /** The instrumentation scope that the driver's tracer and meter report under. */
23
+ export const CAMUS_TELEMETRY_NAME = 'camusdb';
24
+ /** The `db.system.name` of every span and measurement. */
25
+ const SYSTEM_NAME = 'camusdb';
26
+ /** The `camusdb.retry.kind` values: what the driver sent again. */
27
+ export const CamusRetryKind = {
28
+ /** A commit or a rollback sent again after `CADB0509`. */
29
+ Finalize: 'finalize',
30
+ /** A unit of work of `withRetry` run again after a serializable conflict. */
31
+ Autocommit: 'autocommit',
32
+ /** A unit of work of `client.transaction` run again, from `BEGIN`, after a serializable conflict. */
33
+ Transaction: 'transaction',
34
+ /** A call sent again with a new token after the server refused the old one. */
35
+ TokenRenewal: 'token_renewal',
36
+ /** A `CREATE DATABASE` or a branch creation sent again after a transient failure. */
37
+ CreateDatabase: 'create_database',
38
+ };
39
+ /** The `camusdb.prepared_statement.result` values. */
40
+ export const PreparedResult = {
41
+ Hit: 'hit',
42
+ Registered: 'registered',
43
+ Miss: 'miss',
44
+ Success: 'success',
45
+ Refused: 'refused',
46
+ Unsupported: 'unsupported',
47
+ };
48
+ // ─── Loading ────────────────────────────────────────────────────────────────
49
+ /** `undefined` until the first try, `null` when the package is not installed. */
50
+ let loadedApi;
51
+ let packageVersion;
52
+ /**
53
+ * The API, or `undefined` when the package is not installed.
54
+ *
55
+ * It is loaded with `require`, so the first operation is instrumented too: a dynamic `import` would
56
+ * leave every operation before it settles without a span. The API keeps its registrations in a
57
+ * process-wide global, so the copy that `require` loads sees the SDK that an ES module registered.
58
+ */
59
+ function api() {
60
+ if (loadedApi === undefined) {
61
+ const require = createRequire(import.meta.url);
62
+ try {
63
+ loadedApi = require('@opentelemetry/api');
64
+ }
65
+ catch {
66
+ loadedApi = null;
67
+ }
68
+ try {
69
+ packageVersion = require('../package.json').version;
70
+ }
71
+ catch {
72
+ packageVersion = undefined;
73
+ }
74
+ }
75
+ return loadedApi ?? undefined;
76
+ }
77
+ /**
78
+ * @internal Test hook: replaces the API, or with `null` plays a process without the package.
79
+ * `undefined` loads it again on the next operation.
80
+ */
81
+ export function setTelemetryApi(replacement) {
82
+ loadedApi = replacement;
83
+ tracer = undefined;
84
+ instruments = undefined;
85
+ }
86
+ let tracer;
87
+ /** The global tracer. The API hands out a proxy, so a provider registered later still gets the spans. */
88
+ function tracerFor(otel) {
89
+ if (tracer?.api !== otel)
90
+ tracer = { api: otel, tracer: otel.trace.getTracer(CAMUS_TELEMETRY_NAME, packageVersion) };
91
+ return tracer.tracer;
92
+ }
93
+ let instruments;
94
+ /**
95
+ * The instruments, made on the meter of the current global provider.
96
+ *
97
+ * The metrics API has no proxy provider, so an instrument made before the SDK registered stays a
98
+ * no-op for good. The instruments are made again whenever the global provider changes.
99
+ */
100
+ function instrumentsFor(otel) {
101
+ const provider = otel.metrics.getMeterProvider();
102
+ if (instruments?.api === otel && instruments.provider === provider)
103
+ return instruments;
104
+ const meter = otel.metrics.getMeter(CAMUS_TELEMETRY_NAME, packageVersion);
105
+ const quarantined = meter.createObservableGauge('camusdb.client.endpoint.quarantined', {
106
+ unit: '{endpoint}',
107
+ description: '1 while the endpoint is set aside after a transport failure, 0 while it takes traffic.',
108
+ });
109
+ quarantined.addCallback((result) => {
110
+ for (const [endpoint, isQuarantined] of CamusEndpointPool.collectQuarantine()) {
111
+ result.observe(isQuarantined ? 1 : 0, endpointAttributes(endpoint));
112
+ }
113
+ });
114
+ const preparedCount = meter.createObservableUpDownCounter('camusdb.client.prepared_statement.count', {
115
+ unit: '{statement}',
116
+ description: 'Statements kept prepared now.',
117
+ });
118
+ preparedCount.addCallback((result) => {
119
+ for (const [database, count] of CamusPreparedStatementPolicy.collectPreparedCounts()) {
120
+ result.observe(count, { 'db.namespace': database });
121
+ }
122
+ });
123
+ instruments = {
124
+ api: otel,
125
+ provider,
126
+ duration: meter.createHistogram('db.client.operation.duration', {
127
+ unit: 's',
128
+ description: 'Duration of database client operations.',
129
+ advice: { explicitBucketBoundaries: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10] },
130
+ }),
131
+ retries: meter.createCounter('camusdb.client.operation.retries', {
132
+ unit: '{retry}',
133
+ description: 'Operations the driver sent again after a failure it knows to be safe to retry.',
134
+ }),
135
+ quarantines: meter.createCounter('camusdb.client.endpoint.quarantines', {
136
+ unit: '{quarantine}',
137
+ description: 'Times an endpoint failed at the transport level and was set aside for 30 seconds.',
138
+ }),
139
+ lookups: meter.createCounter('camusdb.client.prepared_statement.lookups', {
140
+ unit: '{lookup}',
141
+ description: 'Executions of a preparable statement, by whether the statement went as a prepared handle.',
142
+ }),
143
+ registrations: meter.createCounter('camusdb.client.prepared_statement.registrations', {
144
+ unit: '{registration}',
145
+ description: 'Requests to the server to prepare a statement.',
146
+ }),
147
+ evictions: meter.createCounter('camusdb.client.prepared_statement.evictions', {
148
+ unit: '{eviction}',
149
+ description: 'Prepared statements released to make room for a statement used more recently.',
150
+ }),
151
+ };
152
+ return instruments;
153
+ }
154
+ /** The spans this driver started, so a retry adds its event only to one of them. */
155
+ const ownSpans = new WeakSet();
156
+ /**
157
+ * One instrumented operation: its span, and its start time for the duration histogram.
158
+ *
159
+ * It ends once. The first `complete` or `fail` ends it, and later calls do nothing.
160
+ */
161
+ export class CamusOperation {
162
+ otel;
163
+ span;
164
+ startedAt;
165
+ database;
166
+ operationName;
167
+ ended = false;
168
+ serverAddress;
169
+ serverPort = 0;
170
+ /** @internal Use `startOperation`. */
171
+ constructor(otel, span, startedAt, database, operationName) {
172
+ this.otel = otel;
173
+ this.span = span;
174
+ this.startedAt = startedAt;
175
+ this.database = database;
176
+ this.operationName = operationName;
177
+ }
178
+ /** Records the server the operation goes to, as `server.address` and `server.port`. */
179
+ setEndpoint(endpoint) {
180
+ const { host, port } = parseEndpoint(endpoint);
181
+ this.serverAddress = host;
182
+ this.serverPort = port;
183
+ if (this.span.isRecording()) {
184
+ this.span.setAttribute('server.address', host);
185
+ if (port > 0)
186
+ this.span.setAttribute('server.port', port);
187
+ }
188
+ }
189
+ setAttribute(key, value) {
190
+ if (this.span.isRecording())
191
+ this.span.setAttribute(key, value);
192
+ }
193
+ /**
194
+ * Runs `fn` with this operation's span as the active span, so the HTTP or gRPC spans of the
195
+ * transport are its children.
196
+ */
197
+ run(fn) {
198
+ return this.otel.context.with(this.otel.trace.setSpan(this.otel.context.active(), this.span), fn);
199
+ }
200
+ /** Adds a `camusdb.retry` event to this operation's span. */
201
+ addRetryEvent(kind, errorType) {
202
+ this.span.addEvent('camusdb.retry', defined({ 'camusdb.retry.kind': kind, 'error.type': errorType }));
203
+ }
204
+ /** Ends the operation as a success. */
205
+ complete() {
206
+ this.end(undefined, false);
207
+ }
208
+ /** Ends the operation as a failure. */
209
+ fail(error) {
210
+ this.end(error, true);
211
+ }
212
+ end(error, failed) {
213
+ if (this.ended)
214
+ return;
215
+ this.ended = true;
216
+ // The conventions use the database status code as the error type when there is one.
217
+ const statusCode = failed && CamusError.is(error) ? error.code : undefined;
218
+ const errorType = failed ? (statusCode ?? errorTypeName(error)) : undefined;
219
+ if (failed) {
220
+ if (this.span.isRecording()) {
221
+ this.span.setAttribute('error.type', errorType);
222
+ if (statusCode !== undefined)
223
+ this.span.setAttribute('db.response.status_code', statusCode);
224
+ this.span.recordException(error instanceof Error ? error : String(error));
225
+ }
226
+ this.span.setStatus({
227
+ code: this.otel.SpanStatusCode.ERROR,
228
+ message: error instanceof Error ? error.message : String(error),
229
+ });
230
+ }
231
+ this.span.end();
232
+ instrumentsFor(this.otel).duration.record((performance.now() - this.startedAt) / 1000, defined({
233
+ 'db.system.name': SYSTEM_NAME,
234
+ 'db.namespace': this.database,
235
+ 'db.operation.name': this.operationName,
236
+ 'server.address': this.serverAddress,
237
+ 'server.port': this.serverPort > 0 ? this.serverPort : undefined,
238
+ 'error.type': errorType,
239
+ 'db.response.status_code': statusCode,
240
+ }));
241
+ }
242
+ }
243
+ /**
244
+ * Starts an operation, or reports `undefined` when `@opentelemetry/api` is not installed.
245
+ *
246
+ * The span is a child of the active span. Its name is `{operation} {target}`, where the target is
247
+ * the table when it is known, and the database if not.
248
+ */
249
+ export function startOperation(scope, init) {
250
+ const otel = api();
251
+ if (otel === undefined)
252
+ return undefined;
253
+ const database = scope.database;
254
+ const target = init.collection ?? database;
255
+ const name = init.operationName === undefined ? target : `${init.operationName} ${target}`;
256
+ const span = tracerFor(otel).startSpan(name, { kind: otel.SpanKind.CLIENT }, otel.context.active());
257
+ ownSpans.add(span);
258
+ if (span.isRecording()) {
259
+ span.setAttribute('db.system.name', SYSTEM_NAME);
260
+ span.setAttribute('db.namespace', database);
261
+ if (init.operationName !== undefined)
262
+ span.setAttribute('db.operation.name', init.operationName);
263
+ if (init.collection !== undefined)
264
+ span.setAttribute('db.collection.name', init.collection);
265
+ if (init.batchSize !== undefined && init.batchSize > 0) {
266
+ span.setAttribute('db.operation.batch.size', init.batchSize);
267
+ }
268
+ if (init.queryText !== undefined && scope.config.traceQueryText) {
269
+ span.setAttribute('db.query.text', init.queryText);
270
+ }
271
+ span.setAttribute('camusdb.transport', scope.config.protocol);
272
+ }
273
+ return new CamusOperation(otel, span, performance.now(), database, init.operationName);
274
+ }
275
+ /**
276
+ * Runs one operation under a span, and ends the span with the operation's outcome.
277
+ *
278
+ * Without `@opentelemetry/api`, it only calls `run`.
279
+ */
280
+ export async function traced(scope, init, run) {
281
+ const operation = startOperation(scope, init);
282
+ if (operation === undefined)
283
+ return run(undefined);
284
+ try {
285
+ const result = await operation.run(() => run(operation));
286
+ operation.complete();
287
+ return result;
288
+ }
289
+ catch (error) {
290
+ operation.fail(error);
291
+ throw error;
292
+ }
293
+ }
294
+ /**
295
+ * The statement verbs that become `db.operation.name`. A first keyword that is not in this list
296
+ * gives no operation name, so the metric keeps a small set of values.
297
+ */
298
+ const KNOWN_OPERATIONS = new Set([
299
+ 'SELECT',
300
+ 'INSERT',
301
+ 'UPDATE',
302
+ 'DELETE',
303
+ 'CREATE',
304
+ 'ALTER',
305
+ 'DROP',
306
+ 'TRUNCATE',
307
+ 'EXPLAIN',
308
+ 'SHOW',
309
+ 'REFRESH',
310
+ 'COMMENT',
311
+ 'GRANT',
312
+ 'REVOKE',
313
+ 'SET',
314
+ ]);
315
+ /**
316
+ * The operation name of a statement: its first keyword in upper case when that keyword is a known
317
+ * verb, and `undefined` if not. Leading white space and opening parentheses are skipped.
318
+ */
319
+ export function operationName(sql) {
320
+ const match = /^[\s(]*([A-Za-z]+)/.exec(sql);
321
+ const keyword = match?.[1]?.toUpperCase();
322
+ return keyword !== undefined && KNOWN_OPERATIONS.has(keyword) ? keyword : undefined;
323
+ }
324
+ // ─── Driver metrics ─────────────────────────────────────────────────────────
325
+ /**
326
+ * Counts one retry, and adds a `camusdb.retry` event to the driver span of the operation, or to the
327
+ * active span when it is one of the driver's.
328
+ */
329
+ export function recordRetry(kind, error, details = {}) {
330
+ const otel = api();
331
+ if (otel === undefined)
332
+ return;
333
+ const errorType = CamusError.is(error) ? error.code : errorTypeName(error);
334
+ if (details.operation !== undefined) {
335
+ details.operation.addRetryEvent(kind, errorType);
336
+ }
337
+ else {
338
+ const active = otel.trace.getActiveSpan();
339
+ if (active !== undefined && ownSpans.has(active)) {
340
+ active.addEvent('camusdb.retry', defined({ 'camusdb.retry.kind': kind, 'error.type': errorType }));
341
+ }
342
+ }
343
+ instrumentsFor(otel).retries.add(1, defined({
344
+ 'camusdb.retry.kind': kind,
345
+ 'error.type': errorType,
346
+ 'db.namespace': details.database,
347
+ 'db.operation.name': details.operationName,
348
+ }));
349
+ }
350
+ /** Counts one endpoint set aside after a transport failure. */
351
+ export function recordQuarantine(endpoint) {
352
+ const otel = api();
353
+ if (otel === undefined)
354
+ return;
355
+ instrumentsFor(otel).quarantines.add(1, endpointAttributes(endpoint));
356
+ }
357
+ /** Counts one execution of a preparable statement: `hit`, `registered`, or `miss`. */
358
+ export function recordPreparedLookup(database, result) {
359
+ const otel = api();
360
+ if (otel === undefined)
361
+ return;
362
+ instrumentsFor(otel).lookups.add(1, {
363
+ 'db.namespace': database,
364
+ 'camusdb.prepared_statement.result': result,
365
+ });
366
+ }
367
+ /** Counts one request to prepare a statement: `success`, `refused`, or `unsupported`. */
368
+ export function recordPreparedRegistration(database, result, error) {
369
+ const otel = api();
370
+ if (otel === undefined)
371
+ return;
372
+ instrumentsFor(otel).registrations.add(1, defined({
373
+ 'db.namespace': database,
374
+ 'camusdb.prepared_statement.result': result,
375
+ 'error.type': error === undefined ? undefined : CamusError.is(error) ? error.code : errorTypeName(error),
376
+ }));
377
+ }
378
+ /** Counts one prepared statement released to make room for one used more recently. */
379
+ export function recordPreparedEviction(database) {
380
+ const otel = api();
381
+ if (otel === undefined)
382
+ return;
383
+ instrumentsFor(otel).evictions.add(1, { 'db.namespace': database });
384
+ }
385
+ // ─── Helpers ────────────────────────────────────────────────────────────────
386
+ /** The parsed host and port of each endpoint. Endpoints come from configuration, so the map stays small. */
387
+ const parsedEndpoints = new Map();
388
+ function parseEndpoint(endpoint) {
389
+ let parsed = parsedEndpoints.get(endpoint);
390
+ if (parsed === undefined) {
391
+ try {
392
+ const url = new URL(endpoint);
393
+ const port = url.port.length > 0 ? Number(url.port) : url.protocol === 'https:' ? 443 : 80;
394
+ parsed = { host: url.hostname, port };
395
+ }
396
+ catch {
397
+ parsed = { host: endpoint, port: 0 };
398
+ }
399
+ if (parsedEndpoints.size < 1024)
400
+ parsedEndpoints.set(endpoint, parsed);
401
+ }
402
+ return parsed;
403
+ }
404
+ function endpointAttributes(endpoint) {
405
+ const { host, port } = parseEndpoint(endpoint);
406
+ return port > 0 ? { 'server.address': host, 'server.port': port } : { 'server.address': host };
407
+ }
408
+ /** The attributes without the keys whose value is unknown. The SDK warns about an `undefined` value. */
409
+ function defined(attributes) {
410
+ const result = {};
411
+ for (const [key, value] of Object.entries(attributes)) {
412
+ if (value !== undefined)
413
+ result[key] = value;
414
+ }
415
+ return result;
416
+ }
417
+ function errorTypeName(error) {
418
+ if (error instanceof Error)
419
+ return error.name.length > 0 ? error.name : 'Error';
420
+ return '_OTHER';
421
+ }
422
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,19 @@
5
5
  * file that was distributed with this source code.
6
6
  */
7
7
  import type { CamusTransactionOptions } from './options.js';
8
+ import { CamusPipeline } from './pipeline.js';
8
9
  import type { ClientRuntime } from './runtime.js';
10
+ import type { StartTransactionResult } from './transport/transport.js';
11
+ /**
12
+ * A pipeline's claim on a transaction's `BEGIN`. It is settled once the server answered the
13
+ * `BEGIN` that rode the pipeline's exchange.
14
+ *
15
+ * @internal
16
+ */
17
+ export interface StartClaim {
18
+ resolve(result: StartTransactionResult, target: string): void;
19
+ reject(error: Error): void;
20
+ }
9
21
  /**
10
22
  * A set of reads and writes that take effect atomically, at one logical instant, across columns,
11
23
  * rows, and tables.
@@ -18,9 +30,13 @@ import type { ClientRuntime } from './runtime.js';
18
30
  * a later transaction, but never relocates this one. A caller that knows the transaction's hot
19
31
  * statement can choose the endpoint at `BEGIN` with `options.affinity` instead.
20
32
  *
21
- * Two consequences of the deferral are visible, and only in routed mode: the server-minted identity
22
- * reads as zero until the first statement, and a failure to begin surfaces from that first
23
- * statement rather than from the call that created the transaction.
33
+ * `options.deferBegin` defers `BEGIN` with learned routing off too. The first statement then starts
34
+ * the transaction on the pool's rotation. When that first statement is a `CamusPipeline` send, the
35
+ * `BEGIN` travels inside the same exchange.
36
+ *
37
+ * Two consequences of the deferral are visible, and only for a deferred transaction: the
38
+ * server-minted identity reads as zero until the first statement, and a failure to begin surfaces
39
+ * from that first statement rather than from the call that created the transaction.
24
40
  */
25
41
  export declare class CamusTransaction {
26
42
  private readonly runtime;
@@ -37,6 +53,11 @@ export declare class CamusTransaction {
37
53
  private startPromise;
38
54
  private startFailed;
39
55
  private finalized;
56
+ /**
57
+ * True once a pipeline committed this transaction, so that a later finalize does not ask the
58
+ * server about a transaction it no longer knows.
59
+ */
60
+ private committedByPipeline;
40
61
  /** The concurrency knobs this transaction was begun with, after every default was applied. */
41
62
  readonly options: CamusTransactionOptions;
42
63
  /**
@@ -54,8 +75,8 @@ export declare class CamusTransaction {
54
75
  /**
55
76
  * True once the server minted this transaction.
56
77
  *
57
- * It is always true with learned routing off. With routing on it is false until the first
58
- * statement, or until an explicit `affinity`, starts it.
78
+ * It is always true with learned routing off and no `deferBegin`. For a deferred transaction it
79
+ * is false until the first statement, or until an explicit `affinity`, starts it.
59
80
  */
60
81
  get isStarted(): boolean;
61
82
  /** True once this transaction was committed or rolled back. */
@@ -80,6 +101,40 @@ export declare class CamusTransaction {
80
101
  */
81
102
  ensureStarted(preferredEndpoint: string | undefined, signal?: AbortSignal): Promise<string>;
82
103
  private startOn;
104
+ private seat;
105
+ /**
106
+ * Several statements of this transaction, sent as one exchange and answered together. See
107
+ * `CamusPipeline`. A transaction begun with `deferBegin`, or with learned routing on, sends its
108
+ * `BEGIN` inside the first pipeline send too.
109
+ */
110
+ pipeline(): CamusPipeline;
111
+ /**
112
+ * Lets a pipeline begin this transaction inside its first exchange.
113
+ *
114
+ * When nothing has begun the transaction yet, it reports a claim. The pipeline settles the claim
115
+ * after the server answered the `BEGIN`. When a `BEGIN` is already under way, it reports that
116
+ * `BEGIN` for the pipeline to await instead. When the transaction has started, it reports
117
+ * neither. The memoized `startPromise` is what makes a pipeline and a statement that race to be
118
+ * the first one agree on one `BEGIN`.
119
+ *
120
+ * @internal
121
+ */
122
+ claimStart(): {
123
+ claim?: StartClaim;
124
+ pending?: Promise<void>;
125
+ };
126
+ /**
127
+ * Records that a pipeline's conditional commit committed this transaction.
128
+ *
129
+ * @internal
130
+ */
131
+ markCommittedByPipeline(): void;
132
+ /**
133
+ * True when a pipeline committed this transaction.
134
+ *
135
+ * @internal
136
+ */
137
+ get isCommittedByPipeline(): boolean;
83
138
  /** Makes this transaction's writes durable. */
84
139
  commit(signal?: AbortSignal): Promise<void>;
85
140
  /** Discards this transaction's writes. */
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAE5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IAExC,OAAO,CAAC,YAAY,CAAM;IAE1B,OAAO,CAAC,iBAAiB,CAAK;IAE9B,OAAO,CAAC,aAAa,CAAqB;IAE1C,OAAO,CAAC,YAAY,CAAS;IAE7B;;;;;OAKG;IACH,OAAO,CAAC,YAAY,CAA4B;IAEhD,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,SAAS,CAAS;IAE1B,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAE1C;;;OAGG;IACH,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAE/B,oDAAoD;gBAElD,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,uBAAuB,EAChC,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;IAcxG;;;;;OAKG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,+DAA+D;IAC/D,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,+FAA+F;IAC/F,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,yFAAyF;IACzF,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,4DAA4D;IAC5D,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,2FAA2F;IAC3F,IAAI,QAAQ,IAAI,MAAM,GAAG,SAAS,CAEjC;IAED;;;;;;;;;OASG;IACG,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;YAUnF,OAAO;IAqBrB,+CAA+C;IAC/C,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C;;;;;;;;;;OAUG;YACW,QAAQ;IA4CtB;;;;OAIG;IACG,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5C;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,CAAC,SAAS;;;MAAoB;CAC9C"}
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAGlD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,MAAM,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9D,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IAExC,OAAO,CAAC,YAAY,CAAM;IAE1B,OAAO,CAAC,iBAAiB,CAAK;IAE9B,OAAO,CAAC,aAAa,CAAqB;IAE1C,OAAO,CAAC,YAAY,CAAS;IAE7B;;;;;OAKG;IACH,OAAO,CAAC,YAAY,CAA4B;IAEhD,OAAO,CAAC,WAAW,CAAS;IAE5B,OAAO,CAAC,SAAS,CAAS;IAE1B;;;OAGG;IACH,OAAO,CAAC,mBAAmB,CAAS;IAEpC,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;IAE1C;;;OAGG;IACH,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAE/B,oDAAoD;gBAElD,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,uBAAuB,EAChC,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;IAcxG;;;;;OAKG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,+DAA+D;IAC/D,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,+FAA+F;IAC/F,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,yFAAyF;IACzF,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,4DAA4D;IAC5D,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,2FAA2F;IAC3F,IAAI,QAAQ,IAAI,MAAM,GAAG,SAAS,CAEjC;IAED;;;;;;;;;OASG;IACG,aAAa,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;YAUnF,OAAO;IAqBrB,OAAO,CAAC,IAAI;IAQZ;;;;OAIG;IACH,QAAQ,IAAI,aAAa;IAIzB;;;;;;;;;;OAUG;IACH,UAAU,IAAI;QAAE,KAAK,CAAC,EAAE,UAAU,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE;IAiC7D;;;;OAIG;IACH,uBAAuB,IAAI,IAAI;IAK/B;;;;OAIG;IACH,IAAI,qBAAqB,IAAI,OAAO,CAEnC;IAED,+CAA+C;IAC/C,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C;;;;;;;;;;OAUG;YACW,QAAQ;IAmEtB;;;;OAIG;IACG,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5C;;;;;;OAMG;IACH,MAAM,CAAC,QAAQ,CAAC,SAAS;;;MAAoB;CAC9C"}