@prisma/client-engine-runtime 6.6.0-dev.82 → 6.6.0-dev.84

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.
@@ -98,4 +98,7 @@ export type QueryPlanNode = {
98
98
  field: string;
99
99
  records: QueryPlanNode;
100
100
  };
101
+ } | {
102
+ type: 'transaction';
103
+ args: QueryPlanNode;
101
104
  };
package/dist/index.d.mts CHANGED
@@ -54,17 +54,24 @@ export declare type QueryEvent = {
54
54
 
55
55
  export declare class QueryInterpreter {
56
56
  #private;
57
- constructor({ queryable, placeholderValues, onQuery }: QueryInterpreterOptions);
58
- run(queryPlan: QueryPlanNode): Promise<unknown>;
57
+ constructor({ transactionManager, placeholderValues, onQuery }: QueryInterpreterOptions);
58
+ run(queryPlan: QueryPlanNode, queryable: SqlQueryable): Promise<unknown>;
59
59
  private interpretNode;
60
60
  }
61
61
 
62
62
  export declare type QueryInterpreterOptions = {
63
- queryable: SqlQueryable;
63
+ transactionManager: QueryInterpreterTransactionManager;
64
64
  placeholderValues: Record<string, unknown>;
65
65
  onQuery?: (event: QueryEvent) => void;
66
66
  };
67
67
 
68
+ export declare type QueryInterpreterTransactionManager = {
69
+ enabled: true;
70
+ manager: TransactionManager;
71
+ } | {
72
+ enabled: false;
73
+ };
74
+
68
75
  export declare type QueryPlanBinding = {
69
76
  name: string;
70
77
  expr: QueryPlanNode;
@@ -133,6 +140,9 @@ export declare type QueryPlanNode = {
133
140
  field: string;
134
141
  records: QueryPlanNode;
135
142
  };
143
+ } | {
144
+ type: 'transaction';
145
+ args: QueryPlanNode;
136
146
  };
137
147
 
138
148
  export declare type TransactionInfo = {
@@ -143,10 +153,12 @@ export declare class TransactionManager {
143
153
  private transactions;
144
154
  private closedTransactions;
145
155
  private readonly driverAdapter;
146
- constructor({ driverAdapter }: {
156
+ private readonly transactionOptions;
157
+ constructor({ driverAdapter, transactionOptions }: {
147
158
  driverAdapter: SqlDriverAdapter;
159
+ transactionOptions: TransactionOptions;
148
160
  });
149
- startTransaction(options: TransactionOptions): Promise<TransactionInfo>;
161
+ startTransaction(options?: TransactionOptions): Promise<TransactionInfo>;
150
162
  commitTransaction(transactionId: string): Promise<void>;
151
163
  rollbackTransaction(transactionId: string): Promise<void>;
152
164
  getTransaction(txInfo: TransactionInfo, operation: string): Transaction;
package/dist/index.d.ts CHANGED
@@ -54,17 +54,24 @@ export declare type QueryEvent = {
54
54
 
55
55
  export declare class QueryInterpreter {
56
56
  #private;
57
- constructor({ queryable, placeholderValues, onQuery }: QueryInterpreterOptions);
58
- run(queryPlan: QueryPlanNode): Promise<unknown>;
57
+ constructor({ transactionManager, placeholderValues, onQuery }: QueryInterpreterOptions);
58
+ run(queryPlan: QueryPlanNode, queryable: SqlQueryable): Promise<unknown>;
59
59
  private interpretNode;
60
60
  }
61
61
 
62
62
  export declare type QueryInterpreterOptions = {
63
- queryable: SqlQueryable;
63
+ transactionManager: QueryInterpreterTransactionManager;
64
64
  placeholderValues: Record<string, unknown>;
65
65
  onQuery?: (event: QueryEvent) => void;
66
66
  };
67
67
 
68
+ export declare type QueryInterpreterTransactionManager = {
69
+ enabled: true;
70
+ manager: TransactionManager;
71
+ } | {
72
+ enabled: false;
73
+ };
74
+
68
75
  export declare type QueryPlanBinding = {
69
76
  name: string;
70
77
  expr: QueryPlanNode;
@@ -133,6 +140,9 @@ export declare type QueryPlanNode = {
133
140
  field: string;
134
141
  records: QueryPlanNode;
135
142
  };
143
+ } | {
144
+ type: 'transaction';
145
+ args: QueryPlanNode;
136
146
  };
137
147
 
138
148
  export declare type TransactionInfo = {
@@ -143,10 +153,12 @@ export declare class TransactionManager {
143
153
  private transactions;
144
154
  private closedTransactions;
145
155
  private readonly driverAdapter;
146
- constructor({ driverAdapter }: {
156
+ private readonly transactionOptions;
157
+ constructor({ driverAdapter, transactionOptions }: {
147
158
  driverAdapter: SqlDriverAdapter;
159
+ transactionOptions: TransactionOptions;
148
160
  });
149
- startTransaction(options: TransactionOptions): Promise<TransactionInfo>;
161
+ startTransaction(options?: TransactionOptions): Promise<TransactionInfo>;
150
162
  commitTransaction(transactionId: string): Promise<void>;
151
163
  rollbackTransaction(transactionId: string): Promise<void>;
152
164
  getTransaction(txInfo: TransactionInfo, operation: string): Transaction;
package/dist/index.js CHANGED
@@ -274,22 +274,22 @@ function serialize(resultSet) {
274
274
 
275
275
  // src/interpreter/QueryInterpreter.ts
276
276
  var QueryInterpreter = class {
277
- #queryable;
277
+ #transactionManager;
278
278
  #placeholderValues;
279
279
  #onQuery;
280
280
  #generators = new GeneratorRegistry();
281
- constructor({ queryable, placeholderValues, onQuery }) {
282
- this.#queryable = queryable;
281
+ constructor({ transactionManager, placeholderValues, onQuery }) {
282
+ this.#transactionManager = transactionManager;
283
283
  this.#placeholderValues = placeholderValues;
284
284
  this.#onQuery = onQuery;
285
285
  }
286
- async run(queryPlan) {
287
- return this.interpretNode(queryPlan, this.#placeholderValues, this.#generators.snapshot());
286
+ async run(queryPlan, queryable) {
287
+ return this.interpretNode(queryPlan, queryable, this.#placeholderValues, this.#generators.snapshot());
288
288
  }
289
- async interpretNode(node, scope, generators) {
289
+ async interpretNode(node, queryable, scope, generators) {
290
290
  switch (node.type) {
291
291
  case "seq": {
292
- const results = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope, generators)));
292
+ const results = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
293
293
  return results[results.length - 1];
294
294
  }
295
295
  case "get": {
@@ -299,10 +299,10 @@ var QueryInterpreter = class {
299
299
  const nestedScope = Object.create(scope);
300
300
  await Promise.all(
301
301
  node.args.bindings.map(async (binding) => {
302
- nestedScope[binding.name] = await this.interpretNode(binding.expr, scope, generators);
302
+ nestedScope[binding.name] = await this.interpretNode(binding.expr, queryable, scope, generators);
303
303
  })
304
304
  );
305
- return this.interpretNode(node.args.expr, nestedScope, generators);
305
+ return this.interpretNode(node.args.expr, queryable, nestedScope, generators);
306
306
  }
307
307
  case "getFirstNonEmpty": {
308
308
  for (const name of node.args.names) {
@@ -314,31 +314,31 @@ var QueryInterpreter = class {
314
314
  return [];
315
315
  }
316
316
  case "concat": {
317
- const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope, generators)));
317
+ const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
318
318
  return parts.reduce((acc, part) => acc.concat(asList(part)), []);
319
319
  }
320
320
  case "sum": {
321
- const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope, generators)));
321
+ const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
322
322
  return parts.reduce((acc, part) => asNumber(acc) + asNumber(part));
323
323
  }
324
324
  case "execute": {
325
325
  const query = renderQuery(node.args, scope, generators);
326
326
  return this.#withQueryEvent(query, async () => {
327
- return await this.#queryable.executeRaw(query);
327
+ return await queryable.executeRaw(query);
328
328
  });
329
329
  }
330
330
  case "query": {
331
331
  const query = renderQuery(node.args, scope, generators);
332
332
  return this.#withQueryEvent(query, async () => {
333
- return serialize(await this.#queryable.queryRaw(query));
333
+ return serialize(await queryable.queryRaw(query));
334
334
  });
335
335
  }
336
336
  case "reverse": {
337
- const value = await this.interpretNode(node.args, scope, generators);
337
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
338
338
  return Array.isArray(value) ? value.reverse() : value;
339
339
  }
340
340
  case "unique": {
341
- const value = await this.interpretNode(node.args, scope, generators);
341
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
342
342
  if (!Array.isArray(value)) {
343
343
  return value;
344
344
  }
@@ -348,22 +348,22 @@ var QueryInterpreter = class {
348
348
  return value[0] ?? null;
349
349
  }
350
350
  case "required": {
351
- const value = await this.interpretNode(node.args, scope, generators);
351
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
352
352
  if (isEmpty(value)) {
353
353
  throw new Error("Required value is empty");
354
354
  }
355
355
  return value;
356
356
  }
357
357
  case "mapField": {
358
- const value = await this.interpretNode(node.args.records, scope, generators);
358
+ const value = await this.interpretNode(node.args.records, queryable, scope, generators);
359
359
  return mapField(value, node.args.field);
360
360
  }
361
361
  case "join": {
362
- const parent = await this.interpretNode(node.args.parent, scope, generators);
362
+ const parent = await this.interpretNode(node.args.parent, queryable, scope, generators);
363
363
  const children = await Promise.all(
364
364
  node.args.children.map(async (joinExpr) => ({
365
365
  joinExpr,
366
- childRecords: await this.interpretNode(joinExpr.child, scope, generators)
366
+ childRecords: await this.interpretNode(joinExpr.child, queryable, scope, generators)
367
367
  }))
368
368
  );
369
369
  if (Array.isArray(parent)) {
@@ -374,6 +374,22 @@ var QueryInterpreter = class {
374
374
  }
375
375
  return attachChildrenToParent(asRecord(parent), children);
376
376
  }
377
+ case "transaction": {
378
+ if (!this.#transactionManager.enabled) {
379
+ return this.interpretNode(node.args, queryable, scope, generators);
380
+ }
381
+ const transactionManager = this.#transactionManager.manager;
382
+ const transactionInfo = await transactionManager.startTransaction();
383
+ const transaction = transactionManager.getTransaction(transactionInfo, "new");
384
+ try {
385
+ const value = await this.interpretNode(node.args, transaction, scope, generators);
386
+ await transactionManager.commitTransaction(transactionInfo.id);
387
+ return value;
388
+ } catch (e) {
389
+ await transactionManager.rollbackTransaction(transactionInfo.id);
390
+ throw e;
391
+ }
392
+ }
377
393
  default: {
378
394
  node;
379
395
  throw new Error(`Unexpected node type: ${node.type}`);
@@ -528,11 +544,13 @@ var TransactionManager = class {
528
544
  // Used to provide better error messages than a generic "transaction not found".
529
545
  closedTransactions = [];
530
546
  driverAdapter;
531
- constructor({ driverAdapter }) {
547
+ transactionOptions;
548
+ constructor({ driverAdapter, transactionOptions }) {
532
549
  this.driverAdapter = driverAdapter;
550
+ this.transactionOptions = transactionOptions;
533
551
  }
534
552
  async startTransaction(options) {
535
- const validatedOptions = this.validateOptions(options);
553
+ const validatedOptions = options !== void 0 ? this.validateOptions(options) : this.transactionOptions;
536
554
  const transaction = {
537
555
  id: await randomUUID(),
538
556
  status: "waiting",
package/dist/index.mjs CHANGED
@@ -234,22 +234,22 @@ function serialize(resultSet) {
234
234
 
235
235
  // src/interpreter/QueryInterpreter.ts
236
236
  var QueryInterpreter = class {
237
- #queryable;
237
+ #transactionManager;
238
238
  #placeholderValues;
239
239
  #onQuery;
240
240
  #generators = new GeneratorRegistry();
241
- constructor({ queryable, placeholderValues, onQuery }) {
242
- this.#queryable = queryable;
241
+ constructor({ transactionManager, placeholderValues, onQuery }) {
242
+ this.#transactionManager = transactionManager;
243
243
  this.#placeholderValues = placeholderValues;
244
244
  this.#onQuery = onQuery;
245
245
  }
246
- async run(queryPlan) {
247
- return this.interpretNode(queryPlan, this.#placeholderValues, this.#generators.snapshot());
246
+ async run(queryPlan, queryable) {
247
+ return this.interpretNode(queryPlan, queryable, this.#placeholderValues, this.#generators.snapshot());
248
248
  }
249
- async interpretNode(node, scope, generators) {
249
+ async interpretNode(node, queryable, scope, generators) {
250
250
  switch (node.type) {
251
251
  case "seq": {
252
- const results = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope, generators)));
252
+ const results = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
253
253
  return results[results.length - 1];
254
254
  }
255
255
  case "get": {
@@ -259,10 +259,10 @@ var QueryInterpreter = class {
259
259
  const nestedScope = Object.create(scope);
260
260
  await Promise.all(
261
261
  node.args.bindings.map(async (binding) => {
262
- nestedScope[binding.name] = await this.interpretNode(binding.expr, scope, generators);
262
+ nestedScope[binding.name] = await this.interpretNode(binding.expr, queryable, scope, generators);
263
263
  })
264
264
  );
265
- return this.interpretNode(node.args.expr, nestedScope, generators);
265
+ return this.interpretNode(node.args.expr, queryable, nestedScope, generators);
266
266
  }
267
267
  case "getFirstNonEmpty": {
268
268
  for (const name of node.args.names) {
@@ -274,31 +274,31 @@ var QueryInterpreter = class {
274
274
  return [];
275
275
  }
276
276
  case "concat": {
277
- const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope, generators)));
277
+ const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
278
278
  return parts.reduce((acc, part) => acc.concat(asList(part)), []);
279
279
  }
280
280
  case "sum": {
281
- const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, scope, generators)));
281
+ const parts = await Promise.all(node.args.map((arg) => this.interpretNode(arg, queryable, scope, generators)));
282
282
  return parts.reduce((acc, part) => asNumber(acc) + asNumber(part));
283
283
  }
284
284
  case "execute": {
285
285
  const query = renderQuery(node.args, scope, generators);
286
286
  return this.#withQueryEvent(query, async () => {
287
- return await this.#queryable.executeRaw(query);
287
+ return await queryable.executeRaw(query);
288
288
  });
289
289
  }
290
290
  case "query": {
291
291
  const query = renderQuery(node.args, scope, generators);
292
292
  return this.#withQueryEvent(query, async () => {
293
- return serialize(await this.#queryable.queryRaw(query));
293
+ return serialize(await queryable.queryRaw(query));
294
294
  });
295
295
  }
296
296
  case "reverse": {
297
- const value = await this.interpretNode(node.args, scope, generators);
297
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
298
298
  return Array.isArray(value) ? value.reverse() : value;
299
299
  }
300
300
  case "unique": {
301
- const value = await this.interpretNode(node.args, scope, generators);
301
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
302
302
  if (!Array.isArray(value)) {
303
303
  return value;
304
304
  }
@@ -308,22 +308,22 @@ var QueryInterpreter = class {
308
308
  return value[0] ?? null;
309
309
  }
310
310
  case "required": {
311
- const value = await this.interpretNode(node.args, scope, generators);
311
+ const value = await this.interpretNode(node.args, queryable, scope, generators);
312
312
  if (isEmpty(value)) {
313
313
  throw new Error("Required value is empty");
314
314
  }
315
315
  return value;
316
316
  }
317
317
  case "mapField": {
318
- const value = await this.interpretNode(node.args.records, scope, generators);
318
+ const value = await this.interpretNode(node.args.records, queryable, scope, generators);
319
319
  return mapField(value, node.args.field);
320
320
  }
321
321
  case "join": {
322
- const parent = await this.interpretNode(node.args.parent, scope, generators);
322
+ const parent = await this.interpretNode(node.args.parent, queryable, scope, generators);
323
323
  const children = await Promise.all(
324
324
  node.args.children.map(async (joinExpr) => ({
325
325
  joinExpr,
326
- childRecords: await this.interpretNode(joinExpr.child, scope, generators)
326
+ childRecords: await this.interpretNode(joinExpr.child, queryable, scope, generators)
327
327
  }))
328
328
  );
329
329
  if (Array.isArray(parent)) {
@@ -334,6 +334,22 @@ var QueryInterpreter = class {
334
334
  }
335
335
  return attachChildrenToParent(asRecord(parent), children);
336
336
  }
337
+ case "transaction": {
338
+ if (!this.#transactionManager.enabled) {
339
+ return this.interpretNode(node.args, queryable, scope, generators);
340
+ }
341
+ const transactionManager = this.#transactionManager.manager;
342
+ const transactionInfo = await transactionManager.startTransaction();
343
+ const transaction = transactionManager.getTransaction(transactionInfo, "new");
344
+ try {
345
+ const value = await this.interpretNode(node.args, transaction, scope, generators);
346
+ await transactionManager.commitTransaction(transactionInfo.id);
347
+ return value;
348
+ } catch (e) {
349
+ await transactionManager.rollbackTransaction(transactionInfo.id);
350
+ throw e;
351
+ }
352
+ }
337
353
  default: {
338
354
  node;
339
355
  throw new Error(`Unexpected node type: ${node.type}`);
@@ -488,11 +504,13 @@ var TransactionManager = class {
488
504
  // Used to provide better error messages than a generic "transaction not found".
489
505
  closedTransactions = [];
490
506
  driverAdapter;
491
- constructor({ driverAdapter }) {
507
+ transactionOptions;
508
+ constructor({ driverAdapter, transactionOptions }) {
492
509
  this.driverAdapter = driverAdapter;
510
+ this.transactionOptions = transactionOptions;
493
511
  }
494
512
  async startTransaction(options) {
495
- const validatedOptions = this.validateOptions(options);
513
+ const validatedOptions = options !== void 0 ? this.validateOptions(options) : this.transactionOptions;
496
514
  const transaction = {
497
515
  id: await randomUUID(),
498
516
  status: "waiting",
@@ -1,14 +1,21 @@
1
1
  import { SqlQueryable } from '@prisma/driver-adapter-utils';
2
2
  import { QueryEvent } from '../events';
3
3
  import { QueryPlanNode } from '../QueryPlan';
4
+ import { type TransactionManager } from '../transactionManager/TransactionManager';
5
+ export type QueryInterpreterTransactionManager = {
6
+ enabled: true;
7
+ manager: TransactionManager;
8
+ } | {
9
+ enabled: false;
10
+ };
4
11
  export type QueryInterpreterOptions = {
5
- queryable: SqlQueryable;
12
+ transactionManager: QueryInterpreterTransactionManager;
6
13
  placeholderValues: Record<string, unknown>;
7
14
  onQuery?: (event: QueryEvent) => void;
8
15
  };
9
16
  export declare class QueryInterpreter {
10
17
  #private;
11
- constructor({ queryable, placeholderValues, onQuery }: QueryInterpreterOptions);
12
- run(queryPlan: QueryPlanNode): Promise<unknown>;
18
+ constructor({ transactionManager, placeholderValues, onQuery }: QueryInterpreterOptions);
19
+ run(queryPlan: QueryPlanNode, queryable: SqlQueryable): Promise<unknown>;
13
20
  private interpretNode;
14
21
  }
@@ -4,10 +4,12 @@ export declare class TransactionManager {
4
4
  private transactions;
5
5
  private closedTransactions;
6
6
  private readonly driverAdapter;
7
- constructor({ driverAdapter }: {
7
+ private readonly transactionOptions;
8
+ constructor({ driverAdapter, transactionOptions }: {
8
9
  driverAdapter: SqlDriverAdapter;
10
+ transactionOptions: Options;
9
11
  });
10
- startTransaction(options: Options): Promise<TransactionInfo>;
12
+ startTransaction(options?: Options): Promise<TransactionInfo>;
11
13
  commitTransaction(transactionId: string): Promise<void>;
12
14
  rollbackTransaction(transactionId: string): Promise<void>;
13
15
  getTransaction(txInfo: TransactionInfo, operation: string): Transaction;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma/client-engine-runtime",
3
- "version": "6.6.0-dev.82",
3
+ "version": "6.6.0-dev.84",
4
4
  "description": "This package is intended for Prisma's internal use",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -29,8 +29,8 @@
29
29
  "nanoid": "5.1.5",
30
30
  "ulid": "3.0.0",
31
31
  "uuid": "11.1.0",
32
- "@prisma/debug": "6.6.0-dev.82",
33
- "@prisma/driver-adapter-utils": "6.6.0-dev.82"
32
+ "@prisma/debug": "6.6.0-dev.84",
33
+ "@prisma/driver-adapter-utils": "6.6.0-dev.84"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/jest": "29.5.14",