@prisma/orm-family-sql 8.0.0-rc.18-dev.4 → 8.0.0-rc.18-dev.6

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 (51) hide show
  1. package/dist/builder.d.mts +1 -1
  2. package/dist/builder__runtime.d.mts +3 -3
  3. package/dist/builder__runtime.mjs +1 -1
  4. package/dist/builder__types.d.mts +3 -2
  5. package/dist/collection-methods-BnR4UjcW-tiz3frtf.d.mts +77 -0
  6. package/dist/collection-methods-BnR4UjcW-tiz3frtf.d.mts.map +1 -0
  7. package/dist/collection-methods-DoBrRR69.d.mts +1 -0
  8. package/dist/{db-BmrN9nRS-DEogPltL.d.mts → db-BmrN9nRS-CDq1n2be.d.mts} +3 -2
  9. package/dist/db-BmrN9nRS-CDq1n2be.d.mts.map +1 -0
  10. package/dist/{prepared-statement-Bs9TKj5u-CInk8vXF.d.mts → index-UHjF-U84.d.mts} +212 -162
  11. package/dist/index-UHjF-U84.d.mts.map +1 -0
  12. package/dist/{index-reference-CflkzYSd.d.mts → index-reference-DJX-CNsb-D2qUlYq2.d.mts} +12 -3
  13. package/dist/index-reference-DJX-CNsb-D2qUlYq2.d.mts.map +1 -0
  14. package/dist/{index-reference-D693Lu-E.mjs → index-reference-DR62gjQS.mjs} +16 -3
  15. package/dist/index-reference-DR62gjQS.mjs.map +1 -0
  16. package/dist/index-reference-ZZrszBDq.d.mts +1 -0
  17. package/dist/orm-client.d.mts +57 -11
  18. package/dist/orm-client.d.mts.map +1 -1
  19. package/dist/orm-client.mjs +120 -2
  20. package/dist/orm-client.mjs.map +1 -1
  21. package/dist/{query-lane-context-C2AXsoFa-COSQOvZz.d.mts → query-lane-context-C42-u9L1-Bxa4DkI_.d.mts} +7 -2
  22. package/dist/query-lane-context-C42-u9L1-Bxa4DkI_.d.mts.map +1 -0
  23. package/dist/query-lane-context-DW5q2RAY.d.mts +1 -0
  24. package/dist/relational-core.d.mts +3 -3
  25. package/dist/relational-core__aggregate-descriptor-registry.d.mts +1 -1
  26. package/dist/relational-core__codec-descriptor-registry.d.mts +1 -1
  27. package/dist/relational-core__collection-methods.d.mts +3 -0
  28. package/dist/relational-core__collection-methods.mjs +1 -0
  29. package/dist/relational-core__index-reference.d.mts +3 -2
  30. package/dist/relational-core__index-reference.mjs +2 -2
  31. package/dist/relational-core__query-lane-context.d.mts +2 -2
  32. package/dist/relational-core__types.d.mts +2 -2
  33. package/dist/runtime.d.mts +4 -4
  34. package/dist/runtime.mjs +362 -44
  35. package/dist/runtime.mjs.map +1 -1
  36. package/dist/runtime__internal__prepared-query.d.mts +1 -1
  37. package/dist/transaction-state-DR3nKTmH-BZ-54Zu0.d.mts +115 -0
  38. package/dist/transaction-state-DR3nKTmH-BZ-54Zu0.d.mts.map +1 -0
  39. package/dist/types-BkA6tyT-.d.mts +1 -0
  40. package/dist/{types-D09NAayg-CNrpjo7Z.d.mts → types-Cl4MLNrS-lbf-K25i.d.mts} +3 -3
  41. package/dist/{types-D09NAayg-CNrpjo7Z.d.mts.map → types-Cl4MLNrS-lbf-K25i.d.mts.map} +1 -1
  42. package/package.json +19 -18
  43. package/dist/db-BmrN9nRS-DEogPltL.d.mts.map +0 -1
  44. package/dist/index-qr6LA3dl.d.mts +0 -84
  45. package/dist/index-qr6LA3dl.d.mts.map +0 -1
  46. package/dist/index-reference-CflkzYSd.d.mts.map +0 -1
  47. package/dist/index-reference-D693Lu-E.mjs.map +0 -1
  48. package/dist/prepared-statement-Bs9TKj5u-CInk8vXF.d.mts.map +0 -1
  49. package/dist/query-lane-context-BsZs5lvB.d.mts +0 -1
  50. package/dist/query-lane-context-C2AXsoFa-COSQOvZz.d.mts.map +0 -1
  51. package/dist/types-DAkmn9FV.d.mts +0 -1
package/dist/runtime.mjs CHANGED
@@ -9,15 +9,44 @@ import { isStructuredError, structuredError } from "@prisma/orm-framework/utils/
9
9
  import { ifDefined } from "@prisma/orm-framework/utils/defined";
10
10
  import { createHash } from "node:crypto";
11
11
  import { materializeCodec, resolveCodecDescriptorOrThrow } from "@prisma/orm-framework/components/codec";
12
- import { blindCast } from "@prisma/orm-framework/utils/casts";
12
+ import { blindCast, castAs } from "@prisma/orm-framework/utils/casts";
13
13
  import { assertNever, isInternalError } from "@prisma/orm-framework/utils/internal-error";
14
14
  import { canonicalStringify } from "@prisma/orm-framework/utils/canonical-stringify";
15
15
  import { checkContractComponentRequirements, mergeCapabilityMatrices } from "@prisma/orm-framework/components/components";
16
- import { AsyncIterableResult, RuntimeCore, applyMutationDefaults, assertMutationDefaultGeneratorsAvailable, checkAborted, checkMiddlewareCompatibility, collectMutationDefaultGenerators, createStateStore, executeStatement, raceAgainstAbort, runtimeError as runtimeError$1, startTransactionActivity, streamStatement } from "@prisma/orm-framework/components/runtime";
16
+ import { AsyncIterableResult, RuntimeCore, applyMutationDefaults, assertMutationDefaultGeneratorsAvailable, checkAborted, checkMiddlewareCompatibility, collectMutationDefaultGenerators, createContextBeneath, executeStatement, raceAgainstAbort, runtimeError as runtimeError$1, startClientActivity, startTransactionActivity, streamStatement } from "@prisma/orm-framework/components/runtime";
17
17
  import { canonicalizeJson } from "@prisma/orm-framework/components/utils";
18
+ import { invariant } from "@prisma/orm-framework/utils/assertions";
18
19
  import { createExecutionStack } from "@prisma/orm-framework/components/execution";
19
20
  import { hashContent } from "@prisma/orm-framework/utils/hash-content";
20
- //#region ../../../2-sql/5-runtime/dist/exports-BxFmkVE5.mjs
21
+ //#region ../../../2-sql/5-runtime/dist/exports-B30eE9m7.mjs
22
+ /** The symbol-keyed member through which a runtime, connection, transaction, `withTransaction` context or activity handle starts activities; user-facing types do not show it. */
23
+ const activitySource = Symbol("activitySource");
24
+ function hasActivitySourceMember(target) {
25
+ return activitySource in target;
26
+ }
27
+ /** The `activitySource` member of a queryable; `undefined` for a queryable that cannot start activities, such as a test stub. */
28
+ function findActivitySource(target) {
29
+ return hasActivitySourceMember(target) ? target[activitySource] : void 0;
30
+ }
31
+ function activitySourceOf(target) {
32
+ const source = findActivitySource(target);
33
+ invariant(source !== void 0, "The queryable cannot start activities");
34
+ return source;
35
+ }
36
+ /** An activity source that starts activities on whatever queryable `target()` returns when called, for an object that sends its statements to a queryable it looks up each time. */
37
+ function delegatingActivitySource(target) {
38
+ return {
39
+ startActivity: (activity) => startActivityOn(target(), activity),
40
+ planContentHash: (plan) => planContentHashOn(target(), plan)
41
+ };
42
+ }
43
+ /** Starts an activity on a queryable through its `activitySource` member. */
44
+ function startActivityOn(target, activity) {
45
+ return activitySourceOf(target).startActivity(activity);
46
+ }
47
+ function planContentHashOn(target, plan) {
48
+ return activitySourceOf(target).planContentHash(plan);
49
+ }
21
50
  /**
22
51
  * Build an {@link AstCodecResolver} bound to a descriptor registry and a per-call instance-context factory.
23
52
  *
@@ -794,6 +823,7 @@ function createExecutionContext(options) {
794
823
  queryOperations: queryOperationRegistry,
795
824
  types,
796
825
  rawCodecInferer: stack.adapter.rawCodecInferer,
826
+ collectionMethods: contributors.flatMap((contributor) => contributor.collectionMethods?.() ?? []),
797
827
  applyMutationDefaults: (options) => applyMutationDefaults(contract.execution, mutationDefaultGeneratorRegistry, options)
798
828
  };
799
829
  }
@@ -1084,6 +1114,10 @@ var InFlightOperations = class {
1084
1114
  get started() {
1085
1115
  return this.#started;
1086
1116
  }
1117
+ /** How many operations are in flight. */
1118
+ get count() {
1119
+ return this.#count;
1120
+ }
1087
1121
  get active() {
1088
1122
  return this.#count > 0;
1089
1123
  }
@@ -1117,6 +1151,60 @@ async function runBeforeCompileChain(middleware, initial, ctx) {
1117
1151
  }
1118
1152
  return current;
1119
1153
  }
1154
+ /**
1155
+ * Begins a transaction on a connection the transaction owns. The connection is released once the transaction has committed or rolled back, and destroyed after a failed rollback or a failed start other than a refusal before `BEGIN`. After a failed commit it stays held for the rollback that follows. A release that fails after the transaction settled is passed to `log.error`, and `commit()` or `rollback()` keeps its own outcome.
1156
+ */
1157
+ async function beginOwnedTransaction(connection, begin, log) {
1158
+ let transaction;
1159
+ try {
1160
+ transaction = await begin();
1161
+ } catch (error) {
1162
+ if (wasRefusedBeforeBegin(connection)) await connection.release().catch(() => void 0);
1163
+ else await connection.destroy(error).catch(() => void 0);
1164
+ throw error;
1165
+ }
1166
+ let disposed = false;
1167
+ const dispose = async (destroyReason) => {
1168
+ if (disposed) return;
1169
+ disposed = true;
1170
+ if (destroyReason !== void 0) {
1171
+ await connection.destroy(destroyReason.reason).catch(() => void 0);
1172
+ return;
1173
+ }
1174
+ try {
1175
+ await connection.release();
1176
+ } catch (error) {
1177
+ try {
1178
+ log.error({
1179
+ event: "runtime.connection.release.error",
1180
+ error
1181
+ });
1182
+ } catch {}
1183
+ }
1184
+ };
1185
+ return Object.assign(castAs(Object.create(transaction)), {
1186
+ async commit() {
1187
+ try {
1188
+ await transaction.commit();
1189
+ } catch (error) {
1190
+ if (settlementOf(transaction)?.committed === true) await dispose();
1191
+ throw error;
1192
+ }
1193
+ await dispose();
1194
+ },
1195
+ async rollback() {
1196
+ try {
1197
+ await transaction.rollback();
1198
+ } catch (error) {
1199
+ const settlement = settlementOf(transaction);
1200
+ const settled = settlement?.rolledBack === true || settlement?.committed === true;
1201
+ await dispose(settled ? void 0 : { reason: error });
1202
+ throw error;
1203
+ }
1204
+ await dispose();
1205
+ }
1206
+ });
1207
+ }
1120
1208
  function normalizeSpec(spec) {
1121
1209
  if (typeof spec === "string") return {
1122
1210
  codec: { codecId: spec },
@@ -1223,6 +1311,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1223
1311
  closePromise;
1224
1312
  closeRefusal;
1225
1313
  #inFlight = new InFlightOperations();
1314
+ #openActivityHandles = 0;
1226
1315
  #refusing = false;
1227
1316
  #heldQueryables = /* @__PURE__ */ new WeakSet();
1228
1317
  #preparedStatementHandles = /* @__PURE__ */ new WeakMap();
@@ -1344,6 +1433,150 @@ var SqlRuntimeBase = class extends RuntimeCore {
1344
1433
  [preparedStatementExecute](ps, params, options) {
1345
1434
  return this.runPreparedExecuteAgainstQueryable(blindCast(ps), params, this.driver, options);
1346
1435
  }
1436
+ [activitySource] = {
1437
+ startActivity: (activity) => this.startActivityOnRoute(this.queryableRoute(this.driver, "runtime", () => void 0, {
1438
+ transaction: (parent) => this.beginOwnedTransactionBeneath(parent),
1439
+ runtimeWork: true
1440
+ }), activity, void 0),
1441
+ planContentHash: (plan) => this.planContentHashFor(plan, "runtime", void 0)
1442
+ };
1443
+ /**
1444
+ * Starts a client activity whose statements and transaction run on `route`, beneath `parent` or, without one, beneath `route.parent()`.
1445
+ */
1446
+ async startActivityOnRoute(route, activity, parent) {
1447
+ const endWork = route.runtimeWork ? this.beginActivityWork() : () => void 0;
1448
+ let run;
1449
+ try {
1450
+ run = await startClientActivity(activity, {
1451
+ middleware: this.middleware,
1452
+ context: {
1453
+ ...this.sqlCtx,
1454
+ scope: route.scope
1455
+ },
1456
+ parent: parent ?? route.parent(),
1457
+ holdFinishedChildren: this.#holdFinishedChildren
1458
+ });
1459
+ } catch (error) {
1460
+ endWork();
1461
+ throw error;
1462
+ }
1463
+ return this.activityHandle(run, route, endWork);
1464
+ }
1465
+ /** The content hash of the statement `plan` would send on a queryable of `scope` beneath `parent`. */
1466
+ async planContentHashFor(plan, scope, parent) {
1467
+ this.ensureCodecRegistryValidated();
1468
+ if (isExecutionPlan(plan)) return computeSqlContentHash(Object.freeze({
1469
+ ...plan,
1470
+ params: await encodeParams(plan, {}, this.contractCodecs)
1471
+ }));
1472
+ const compiled = await this.compilePlan(plan, createContextBeneath({
1473
+ ...this.sqlCtx,
1474
+ scope
1475
+ }, parent));
1476
+ return computeSqlContentHash(await this.encodeDraftParams(this.lowerToDraft(compiled), {}));
1477
+ }
1478
+ /** An activity route whose statements run on `queryable`. */
1479
+ queryableRoute(queryable, scope, parent, options) {
1480
+ return {
1481
+ scope,
1482
+ parent,
1483
+ ...options,
1484
+ query: (plan, executeOptions) => this.queryAgainstQueryable(plan, queryable, {
1485
+ ...executeOptions,
1486
+ scope
1487
+ }),
1488
+ execute: (plan, executeOptions) => this.executeStatisticsAgainstQueryable(plan, queryable, {
1489
+ ...executeOptions,
1490
+ scope
1491
+ }),
1492
+ preparedQuery: (statement, params, executeOptions) => this.runPreparedQueryAgainstQueryable(statement, params, queryable, {
1493
+ ...executeOptions,
1494
+ scope
1495
+ }),
1496
+ preparedExecute: (statement, params, executeOptions) => this.runPreparedExecuteAgainstQueryable(statement, params, queryable, {
1497
+ ...executeOptions,
1498
+ scope
1499
+ })
1500
+ };
1501
+ }
1502
+ /** The activity route of a held connection that `owner` wraps: its statements run on `connection`, and its transactions begin there. */
1503
+ connectionRoute(connection, owner) {
1504
+ const openTransaction = this.#openTransactions.get(connection);
1505
+ return this.queryableRoute(connection, "connection", () => openTransaction, {
1506
+ transaction: openTransaction === void 0 ? (parent) => this.beginTransactionBeneathOn(connection, owner, parent) : void 0,
1507
+ runtimeWork: false
1508
+ });
1509
+ }
1510
+ beginTransactionBeneathOn(connection, owner, parent) {
1511
+ const openTransaction = this.#openTransactions.get(connection);
1512
+ if (openTransaction !== void 0) return Promise.reject(transactionAlreadyOpenError(parent, openTransaction));
1513
+ return this.beginTransactionOn(connection, owner, parent);
1514
+ }
1515
+ /** The `activitySource` member of a held connection that `owner()` wraps. */
1516
+ connectionActivitySource(connection, owner) {
1517
+ return {
1518
+ startActivity: (activity) => this.startActivityOnRoute(this.connectionRoute(connection, owner()), activity, void 0),
1519
+ planContentHash: (plan) => this.planContentHashFor(plan, "connection", this.#openTransactions.get(connection))
1520
+ };
1521
+ }
1522
+ activityHandle(run, route, endWork) {
1523
+ const self = this;
1524
+ const beneath = (options) => ({
1525
+ ...options,
1526
+ activityParent: run
1527
+ });
1528
+ const beginTransaction = route.transaction;
1529
+ const source = {
1530
+ async startActivity(activity) {
1531
+ run.assertAcceptsChildren();
1532
+ return self.startActivityOnRoute(route, activity, run);
1533
+ },
1534
+ planContentHash(plan) {
1535
+ return self.planContentHashFor(plan, route.scope, run);
1536
+ }
1537
+ };
1538
+ return {
1539
+ ...source,
1540
+ [activitySource]: source,
1541
+ activity: run.activity,
1542
+ get intercepted() {
1543
+ return run.intercepted;
1544
+ },
1545
+ query(plan, options) {
1546
+ return rowsBeneath(run, () => route.query(plan, beneath(options)));
1547
+ },
1548
+ async execute(plan, options) {
1549
+ run.assertAcceptsChildren();
1550
+ return route.execute(plan, beneath(options));
1551
+ },
1552
+ [preparedStatementQuery](ps, params, options) {
1553
+ return rowsBeneath(run, () => route.preparedQuery(blindCast(ps), params, beneath(options)));
1554
+ },
1555
+ async [preparedStatementExecute](ps, params, options) {
1556
+ run.assertAcceptsChildren();
1557
+ return route.preparedExecute(blindCast(ps), params, beneath(options));
1558
+ },
1559
+ async end(end) {
1560
+ try {
1561
+ await run.end(end);
1562
+ } finally {
1563
+ endWork();
1564
+ }
1565
+ },
1566
+ ...ifDefined("transaction", beginTransaction === void 0 ? void 0 : async () => {
1567
+ run.assertAcceptsChildren();
1568
+ return beginTransaction(run);
1569
+ })
1570
+ };
1571
+ }
1572
+ async beginOwnedTransactionBeneath(parent) {
1573
+ const { driverConnection, connection } = await this.openConnection();
1574
+ return this.ownTransaction(connection, () => this.beginTransactionOn(driverConnection, connection, parent));
1575
+ }
1576
+ /** Begins a transaction with `begin` on a connection the transaction owns; see `beginOwnedTransaction`. */
1577
+ ownTransaction(connection, begin) {
1578
+ return beginOwnedTransaction(connection, begin, this.sqlCtx.log);
1579
+ }
1347
1580
  /**
1348
1581
  * Returns the raw driver connection. The connection is a `SqlQueryable` — SQL
1349
1582
  * issued on it runs below the middleware/codec/telemetry pipeline. It carries
@@ -1365,12 +1598,36 @@ var SqlRuntimeBase = class extends RuntimeCore {
1365
1598
  }
1366
1599
  await this.verifyMarkerPromise;
1367
1600
  }
1601
+ beginActivityWork() {
1602
+ const endOperation = this.beginOperation(this.driver);
1603
+ this.#openActivityHandles++;
1604
+ let ended = false;
1605
+ return () => {
1606
+ if (ended) return;
1607
+ ended = true;
1608
+ this.#openActivityHandles--;
1609
+ endOperation();
1610
+ };
1611
+ }
1612
+ warnWhenWaitingOnlyForActivities(warned) {
1613
+ if (warned.done || this.#openActivityHandles === 0) return;
1614
+ if (this.#inFlight.count !== this.#openActivityHandles) return;
1615
+ warned.done = true;
1616
+ this.sqlCtx.log.warn({
1617
+ event: "runtime.close.waiting-for-activities",
1618
+ openActivities: this.#openActivityHandles
1619
+ });
1620
+ }
1368
1621
  beginOperation(queryable) {
1369
1622
  if (queryable === this.driver && this.#refusing) throw runtimeClosedError();
1370
1623
  return this.#inFlight.begin();
1371
1624
  }
1372
- parentOf(queryable) {
1373
- return this.#openTransactions.get(queryable);
1625
+ parentOf(queryable, options) {
1626
+ const openTransaction = this.#openTransactions.get(queryable);
1627
+ const activityParent = options?.activityParent;
1628
+ if (activityParent === void 0) return openTransaction;
1629
+ if (openTransaction !== void 0 && !activityParent.ctx.inTransaction()) throw activityOutsideTransactionError(activityParent, openTransaction);
1630
+ return activityParent;
1374
1631
  }
1375
1632
  getListDecoder() {
1376
1633
  return sqlNativeArrayListDecoder;
@@ -1449,7 +1706,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1449
1706
  middleware: self.middleware,
1450
1707
  plan,
1451
1708
  context: contextFields,
1452
- parent: self.parentOf(queryable)
1709
+ parent: self.parentOf(queryable, options)
1453
1710
  }, async function* (run) {
1454
1711
  const exec = await self.prepareOperation(plan, codecCtx, run);
1455
1712
  yield* self.streamDecodedRows(run, exec, () => buildDecodeContext(exec.ast, self.contractCodecs), () => queryable.query({
@@ -1475,7 +1732,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1475
1732
  async executeStatisticsInFlight(plan, queryable, options) {
1476
1733
  this.ensureCodecRegistryValidated();
1477
1734
  const { codecCtx, contextFields } = this.createQueryContexts(options);
1478
- return this.executeOn(queryable, plan, contextFields, async (run) => {
1735
+ return this.executeOn(queryable, options, plan, contextFields, async (run) => {
1479
1736
  const exec = await this.prepareOperation(plan, codecCtx, run);
1480
1737
  return this.executeEncodedPlan(run, exec, queryable, codecCtx, () => queryable.execute({
1481
1738
  sql: exec.sql,
@@ -1483,12 +1740,12 @@ var SqlRuntimeBase = class extends RuntimeCore {
1483
1740
  }));
1484
1741
  });
1485
1742
  }
1486
- executeOn(queryable, plan, context, body) {
1743
+ executeOn(queryable, options, plan, context, body) {
1487
1744
  return executeStatement({
1488
1745
  middleware: this.middleware,
1489
1746
  plan,
1490
1747
  context,
1491
- parent: this.parentOf(queryable)
1748
+ parent: this.parentOf(queryable, options)
1492
1749
  }, body);
1493
1750
  }
1494
1751
  async executeEncodedPlan(run, exec, queryable, codecCtx, driverCall) {
@@ -1508,7 +1765,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1508
1765
  async prepare(declaration, callback) {
1509
1766
  this.ensureCodecRegistryValidated();
1510
1767
  const userPlan = callback(buildBindSiteParams(declaration));
1511
- const finalPlan = await this.compilePlan(userPlan, standaloneContext(this.sqlCtx));
1768
+ const finalPlan = await this.compilePlan(userPlan, createContextBeneath(this.sqlCtx, void 0));
1512
1769
  const orderedRefs = collectOrderedParamRefs(finalPlan.ast);
1513
1770
  const referencedNames = /* @__PURE__ */ new Set();
1514
1771
  for (const ref of orderedRefs) if (ref.kind === "prepared-param-ref") referencedNames.add(ref.name);
@@ -1542,7 +1799,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1542
1799
  middleware: self.middleware,
1543
1800
  plan: ps,
1544
1801
  context: contextFields,
1545
- parent: self.parentOf(queryable)
1802
+ parent: self.parentOf(queryable, options)
1546
1803
  }, (run) => self.streamPreparedRows(run, ps, userParams, queryable, codecCtx, endOperation));
1547
1804
  } finally {
1548
1805
  endOperation();
@@ -1593,7 +1850,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1593
1850
  async runPreparedExecuteInFlight(ps, userParams, queryable, options) {
1594
1851
  this.ensureCodecRegistryValidated();
1595
1852
  const { codecCtx, contextFields } = this.createQueryContexts(options);
1596
- return this.executeOn(queryable, ps, contextFields, (run) => this.executePrepared(run, ps, userParams, queryable, codecCtx));
1853
+ return this.executeOn(queryable, options, ps, contextFields, (run) => this.executePrepared(run, ps, userParams, queryable, codecCtx));
1597
1854
  }
1598
1855
  async executePrepared(run, ps, userParams, queryable, codecCtx) {
1599
1856
  checkAborted(codecCtx, "stream");
@@ -1626,6 +1883,9 @@ var SqlRuntimeBase = class extends RuntimeCore {
1626
1883
  return this.executeEncodedPlan(run, exec, queryable, codecCtx, () => queryable.execute(request));
1627
1884
  }
1628
1885
  async connection() {
1886
+ return (await this.openConnection()).connection;
1887
+ }
1888
+ async openConnection() {
1629
1889
  const endOperation = this.beginOperation(this.driver);
1630
1890
  let driverConn;
1631
1891
  try {
@@ -1638,8 +1898,9 @@ var SqlRuntimeBase = class extends RuntimeCore {
1638
1898
  const wrappedConnection = {
1639
1899
  [transactionStart]: createTransactionStart(),
1640
1900
  transaction() {
1641
- return self.beginTransactionOn(driverConn, wrappedConnection);
1901
+ return self.beginTransactionOn(driverConn, wrappedConnection, void 0);
1642
1902
  },
1903
+ [activitySource]: self.connectionActivitySource(driverConn, () => wrappedConnection),
1643
1904
  async release() {
1644
1905
  await self.#inFlight.track(() => driverConn.release());
1645
1906
  },
@@ -1671,12 +1932,15 @@ var SqlRuntimeBase = class extends RuntimeCore {
1671
1932
  });
1672
1933
  }
1673
1934
  };
1674
- return wrappedConnection;
1935
+ return {
1936
+ driverConnection: driverConn,
1937
+ connection: wrappedConnection
1938
+ };
1675
1939
  }
1676
1940
  /**
1677
1941
  * Begins a transaction on `connection`, which `owner` wraps, as a transaction activity. When the transaction's `activityStarted` hooks refuse the start, no `BEGIN` is sent, `owner` is recorded as clean, and `withTransaction` releases it; after any other start failure it destroys it. The transaction's `activityStarted` hooks run before `BEGIN`. Every statement sent on the transaction, or on `connection`, from the end of `BEGIN` until `commit()` or `rollback()` is called is the transaction's child, and is finalized when the transaction ends, with its outcome. `commit()` and `rollback()` resolve after every finalization hook has run. A subclass that holds its own connection begins its transactions here.
1678
1942
  */
1679
- async beginTransactionOn(connection, owner) {
1943
+ async beginTransactionOn(connection, owner, parent) {
1680
1944
  owner[transactionStart].refusedBeforeBegin = false;
1681
1945
  let activity;
1682
1946
  try {
@@ -1686,6 +1950,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1686
1950
  ...this.sqlCtx,
1687
1951
  scope: "transaction"
1688
1952
  },
1953
+ parent,
1689
1954
  holdFinishedChildren: this.#holdFinishedChildren
1690
1955
  });
1691
1956
  } catch (error) {
@@ -1709,7 +1974,8 @@ var SqlRuntimeBase = class extends RuntimeCore {
1709
1974
  wrapTransaction(driverTx, connection, activity) {
1710
1975
  this.#openTransactions.set(driverTx, activity);
1711
1976
  this.#openTransactions.set(connection, activity);
1712
- const stopAdopting = () => {
1977
+ const stopAcceptingChildren = () => {
1978
+ activity.stopAcceptingChildren();
1713
1979
  for (const queryable of [driverTx, connection]) if (this.#openTransactions.get(queryable) === activity) this.#openTransactions.delete(queryable);
1714
1980
  };
1715
1981
  let commitAttempted = false;
@@ -1731,7 +1997,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1731
1997
  [transactionSettlement]: settlement,
1732
1998
  async commit() {
1733
1999
  commitAttempted = true;
1734
- stopAdopting();
2000
+ stopAcceptingChildren();
1735
2001
  try {
1736
2002
  await self.#inFlight.track(() => driverTx.commit());
1737
2003
  } catch (error) {
@@ -1749,7 +2015,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1749
2015
  await commitEnding;
1750
2016
  },
1751
2017
  async rollback() {
1752
- stopAdopting();
2018
+ stopAcceptingChildren();
1753
2019
  if (settlement.committed) {
1754
2020
  await commitEnding?.catch(() => void 0);
1755
2021
  return;
@@ -1772,6 +2038,13 @@ var SqlRuntimeBase = class extends RuntimeCore {
1772
2038
  commitAttempted
1773
2039
  });
1774
2040
  },
2041
+ [activitySource]: {
2042
+ startActivity: (clientActivity) => self.startActivityOnRoute(self.queryableRoute(driverTx, "transaction", () => activity, {
2043
+ transaction: void 0,
2044
+ runtimeWork: false
2045
+ }), clientActivity, void 0),
2046
+ planContentHash: (plan) => self.planContentHashFor(plan, "transaction", activity)
2047
+ },
1775
2048
  query(plan, options) {
1776
2049
  return self.queryAgainstQueryable(plan, driverTx, {
1777
2050
  ...options,
@@ -1806,16 +2079,19 @@ var SqlRuntimeBase = class extends RuntimeCore {
1806
2079
  return this.closePromise;
1807
2080
  }
1808
2081
  async closeDriverAfterWork() {
1809
- if (this.closeRefusal === "when-idle") await this.waitForIdleTurn();
2082
+ const warned = { done: false };
2083
+ if (this.closeRefusal === "when-idle") await this.waitForIdleTurn(warned);
1810
2084
  this.#refusing = true;
2085
+ this.warnWhenWaitingOnlyForActivities(warned);
1811
2086
  await this.#inFlight.drained();
1812
2087
  await this.driver.close();
1813
2088
  }
1814
- async waitForIdleTurn() {
2089
+ async waitForIdleTurn(warned) {
1815
2090
  for (;;) {
1816
2091
  const startedBefore = this.#inFlight.started;
1817
2092
  await new Promise((resolve) => scheduleTimer(resolve, 0));
1818
2093
  if (!this.#inFlight.active && this.#inFlight.started === startedBefore) return;
2094
+ this.warnWhenWaitingOnlyForActivities(warned);
1819
2095
  await this.#inFlight.drained();
1820
2096
  }
1821
2097
  }
@@ -1868,13 +2144,25 @@ var SqlRuntimeBase = class extends RuntimeCore {
1868
2144
  });
1869
2145
  }
1870
2146
  };
1871
- function standaloneContext(fields) {
1872
- return {
1873
- ...fields,
1874
- parent: void 0,
1875
- state: createStateStore().state,
1876
- inTransaction: () => false
1877
- };
2147
+ function activityOutsideTransactionError(parent, openTransaction) {
2148
+ return runtimeError$1("RUNTIME.ACTIVITY_OUTSIDE_TRANSACTION", `Work was sent through a '${parent.activity.kind}' activity onto a connection whose open transaction the activity is not part of. Start the activity on the transaction instead.`, {
2149
+ kind: parent.activity.kind,
2150
+ id: parent.activity.id,
2151
+ transactionId: openTransaction.activity.id
2152
+ });
2153
+ }
2154
+ function transactionAlreadyOpenError(parent, openTransaction) {
2155
+ return runtimeError$1("RUNTIME.TRANSACTION_ALREADY_OPEN", `A transaction is already open on this connection; a '${parent.activity.kind}' activity cannot begin another until it commits or rolls back.`, {
2156
+ kind: parent.activity.kind,
2157
+ id: parent.activity.id,
2158
+ transactionId: openTransaction.activity.id
2159
+ });
2160
+ }
2161
+ function rowsBeneath(run, rows) {
2162
+ return new AsyncIterableResult((async function* () {
2163
+ run.assertAcceptsChildren();
2164
+ yield* rows();
2165
+ })());
1878
2166
  }
1879
2167
  function transactionClosedError() {
1880
2168
  return runtimeError$1("RUNTIME.TRANSACTION_CLOSED", "Cannot use a transaction operation after the transaction has ended. Consume query results and await execute calls inside the transaction callback.", {});
@@ -1897,26 +2185,56 @@ async function withTransaction(runtime, fn) {
1897
2185
  if (invalidated) throw transactionClosedError();
1898
2186
  }
1899
2187
  }
2188
+ function guardedQueryable(target) {
2189
+ return {
2190
+ query(plan, options) {
2191
+ if (invalidated) throw transactionClosedError();
2192
+ return new AsyncIterableResult(guardedStream(target.query(plan, options)));
2193
+ },
2194
+ async execute(plan, options) {
2195
+ if (invalidated) throw transactionClosedError();
2196
+ return target.execute(plan, options);
2197
+ },
2198
+ [preparedStatementQuery](ps, params, options) {
2199
+ if (invalidated) throw transactionClosedError();
2200
+ return new AsyncIterableResult(guardedStream(runPreparedQuery(target, ps, params, options)));
2201
+ },
2202
+ [preparedStatementExecute](ps, params, options) {
2203
+ if (invalidated) throw transactionClosedError();
2204
+ return runPreparedExecute(target, ps, params, options);
2205
+ }
2206
+ };
2207
+ }
2208
+ function guardedSource(target) {
2209
+ return {
2210
+ async startActivity(activity) {
2211
+ if (invalidated) throw transactionClosedError();
2212
+ return guardedHandle(await startActivityOn(target, activity));
2213
+ },
2214
+ planContentHash(plan) {
2215
+ return planContentHashOn(target, plan);
2216
+ }
2217
+ };
2218
+ }
2219
+ function guardedHandle(handle) {
2220
+ const source = guardedSource(handle);
2221
+ return {
2222
+ ...source,
2223
+ ...guardedQueryable(handle),
2224
+ [activitySource]: source,
2225
+ activity: handle.activity,
2226
+ get intercepted() {
2227
+ return handle.intercepted;
2228
+ },
2229
+ end: (end) => handle.end(end)
2230
+ };
2231
+ }
1900
2232
  const txContext = {
2233
+ ...guardedQueryable(transaction),
1901
2234
  get invalidated() {
1902
2235
  return invalidated;
1903
2236
  },
1904
- query(plan, options) {
1905
- if (invalidated) throw transactionClosedError();
1906
- return new AsyncIterableResult(guardedStream(transaction.query(plan, options)));
1907
- },
1908
- async execute(plan, options) {
1909
- if (invalidated) throw transactionClosedError();
1910
- return transaction.execute(plan, options);
1911
- },
1912
- [preparedStatementQuery](ps, params, options) {
1913
- if (invalidated) throw transactionClosedError();
1914
- return new AsyncIterableResult(guardedStream(runPreparedQuery(transaction, ps, params, options)));
1915
- },
1916
- [preparedStatementExecute](ps, params, options) {
1917
- if (invalidated) throw transactionClosedError();
1918
- return runPreparedExecute(transaction, ps, params, options);
1919
- }
2237
+ [activitySource]: guardedSource(transaction)
1920
2238
  };
1921
2239
  let connectionDisposed = false;
1922
2240
  const destroyConnection = async (reason) => {
@@ -1967,6 +2285,6 @@ async function withTransaction(runtime, fn) {
1967
2285
  }
1968
2286
  }
1969
2287
  //#endregion
1970
- export { PreparedExecutionImpl, PreparedStatementImpl, SqlRuntimeBase, budgets, createAstCodecRegistry, createExecutionContext, createSqlExecutionStack, deriveParamMetadata, encodeParamsWithMetadata, extractCodecIds, lints, lowerSqlPlan, validateCodecRegistryCompleteness, validateContractCodecMappings, withTransaction };
2288
+ export { PreparedExecutionImpl, PreparedStatementImpl, SqlRuntimeBase, activitySource, budgets, createAstCodecRegistry, createExecutionContext, createSqlExecutionStack, delegatingActivitySource, deriveParamMetadata, encodeParamsWithMetadata, extractCodecIds, findActivitySource, lints, lowerSqlPlan, planContentHashOn, startActivityOn, validateCodecRegistryCompleteness, validateContractCodecMappings, withTransaction };
1971
2289
 
1972
2290
  //# sourceMappingURL=runtime.mjs.map