@prisma/orm-family-sql 8.0.0-rc.18-dev.5 → 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.
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-DrqX-jwZ.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
  *
@@ -1085,6 +1114,10 @@ var InFlightOperations = class {
1085
1114
  get started() {
1086
1115
  return this.#started;
1087
1116
  }
1117
+ /** How many operations are in flight. */
1118
+ get count() {
1119
+ return this.#count;
1120
+ }
1088
1121
  get active() {
1089
1122
  return this.#count > 0;
1090
1123
  }
@@ -1118,6 +1151,60 @@ async function runBeforeCompileChain(middleware, initial, ctx) {
1118
1151
  }
1119
1152
  return current;
1120
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
+ }
1121
1208
  function normalizeSpec(spec) {
1122
1209
  if (typeof spec === "string") return {
1123
1210
  codec: { codecId: spec },
@@ -1224,6 +1311,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1224
1311
  closePromise;
1225
1312
  closeRefusal;
1226
1313
  #inFlight = new InFlightOperations();
1314
+ #openActivityHandles = 0;
1227
1315
  #refusing = false;
1228
1316
  #heldQueryables = /* @__PURE__ */ new WeakSet();
1229
1317
  #preparedStatementHandles = /* @__PURE__ */ new WeakMap();
@@ -1345,6 +1433,150 @@ var SqlRuntimeBase = class extends RuntimeCore {
1345
1433
  [preparedStatementExecute](ps, params, options) {
1346
1434
  return this.runPreparedExecuteAgainstQueryable(blindCast(ps), params, this.driver, options);
1347
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
+ }
1348
1580
  /**
1349
1581
  * Returns the raw driver connection. The connection is a `SqlQueryable` — SQL
1350
1582
  * issued on it runs below the middleware/codec/telemetry pipeline. It carries
@@ -1366,12 +1598,36 @@ var SqlRuntimeBase = class extends RuntimeCore {
1366
1598
  }
1367
1599
  await this.verifyMarkerPromise;
1368
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
+ }
1369
1621
  beginOperation(queryable) {
1370
1622
  if (queryable === this.driver && this.#refusing) throw runtimeClosedError();
1371
1623
  return this.#inFlight.begin();
1372
1624
  }
1373
- parentOf(queryable) {
1374
- 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;
1375
1631
  }
1376
1632
  getListDecoder() {
1377
1633
  return sqlNativeArrayListDecoder;
@@ -1450,7 +1706,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1450
1706
  middleware: self.middleware,
1451
1707
  plan,
1452
1708
  context: contextFields,
1453
- parent: self.parentOf(queryable)
1709
+ parent: self.parentOf(queryable, options)
1454
1710
  }, async function* (run) {
1455
1711
  const exec = await self.prepareOperation(plan, codecCtx, run);
1456
1712
  yield* self.streamDecodedRows(run, exec, () => buildDecodeContext(exec.ast, self.contractCodecs), () => queryable.query({
@@ -1476,7 +1732,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1476
1732
  async executeStatisticsInFlight(plan, queryable, options) {
1477
1733
  this.ensureCodecRegistryValidated();
1478
1734
  const { codecCtx, contextFields } = this.createQueryContexts(options);
1479
- return this.executeOn(queryable, plan, contextFields, async (run) => {
1735
+ return this.executeOn(queryable, options, plan, contextFields, async (run) => {
1480
1736
  const exec = await this.prepareOperation(plan, codecCtx, run);
1481
1737
  return this.executeEncodedPlan(run, exec, queryable, codecCtx, () => queryable.execute({
1482
1738
  sql: exec.sql,
@@ -1484,12 +1740,12 @@ var SqlRuntimeBase = class extends RuntimeCore {
1484
1740
  }));
1485
1741
  });
1486
1742
  }
1487
- executeOn(queryable, plan, context, body) {
1743
+ executeOn(queryable, options, plan, context, body) {
1488
1744
  return executeStatement({
1489
1745
  middleware: this.middleware,
1490
1746
  plan,
1491
1747
  context,
1492
- parent: this.parentOf(queryable)
1748
+ parent: this.parentOf(queryable, options)
1493
1749
  }, body);
1494
1750
  }
1495
1751
  async executeEncodedPlan(run, exec, queryable, codecCtx, driverCall) {
@@ -1509,7 +1765,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1509
1765
  async prepare(declaration, callback) {
1510
1766
  this.ensureCodecRegistryValidated();
1511
1767
  const userPlan = callback(buildBindSiteParams(declaration));
1512
- const finalPlan = await this.compilePlan(userPlan, standaloneContext(this.sqlCtx));
1768
+ const finalPlan = await this.compilePlan(userPlan, createContextBeneath(this.sqlCtx, void 0));
1513
1769
  const orderedRefs = collectOrderedParamRefs(finalPlan.ast);
1514
1770
  const referencedNames = /* @__PURE__ */ new Set();
1515
1771
  for (const ref of orderedRefs) if (ref.kind === "prepared-param-ref") referencedNames.add(ref.name);
@@ -1543,7 +1799,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1543
1799
  middleware: self.middleware,
1544
1800
  plan: ps,
1545
1801
  context: contextFields,
1546
- parent: self.parentOf(queryable)
1802
+ parent: self.parentOf(queryable, options)
1547
1803
  }, (run) => self.streamPreparedRows(run, ps, userParams, queryable, codecCtx, endOperation));
1548
1804
  } finally {
1549
1805
  endOperation();
@@ -1594,7 +1850,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1594
1850
  async runPreparedExecuteInFlight(ps, userParams, queryable, options) {
1595
1851
  this.ensureCodecRegistryValidated();
1596
1852
  const { codecCtx, contextFields } = this.createQueryContexts(options);
1597
- 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));
1598
1854
  }
1599
1855
  async executePrepared(run, ps, userParams, queryable, codecCtx) {
1600
1856
  checkAborted(codecCtx, "stream");
@@ -1627,6 +1883,9 @@ var SqlRuntimeBase = class extends RuntimeCore {
1627
1883
  return this.executeEncodedPlan(run, exec, queryable, codecCtx, () => queryable.execute(request));
1628
1884
  }
1629
1885
  async connection() {
1886
+ return (await this.openConnection()).connection;
1887
+ }
1888
+ async openConnection() {
1630
1889
  const endOperation = this.beginOperation(this.driver);
1631
1890
  let driverConn;
1632
1891
  try {
@@ -1639,8 +1898,9 @@ var SqlRuntimeBase = class extends RuntimeCore {
1639
1898
  const wrappedConnection = {
1640
1899
  [transactionStart]: createTransactionStart(),
1641
1900
  transaction() {
1642
- return self.beginTransactionOn(driverConn, wrappedConnection);
1901
+ return self.beginTransactionOn(driverConn, wrappedConnection, void 0);
1643
1902
  },
1903
+ [activitySource]: self.connectionActivitySource(driverConn, () => wrappedConnection),
1644
1904
  async release() {
1645
1905
  await self.#inFlight.track(() => driverConn.release());
1646
1906
  },
@@ -1672,12 +1932,15 @@ var SqlRuntimeBase = class extends RuntimeCore {
1672
1932
  });
1673
1933
  }
1674
1934
  };
1675
- return wrappedConnection;
1935
+ return {
1936
+ driverConnection: driverConn,
1937
+ connection: wrappedConnection
1938
+ };
1676
1939
  }
1677
1940
  /**
1678
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.
1679
1942
  */
1680
- async beginTransactionOn(connection, owner) {
1943
+ async beginTransactionOn(connection, owner, parent) {
1681
1944
  owner[transactionStart].refusedBeforeBegin = false;
1682
1945
  let activity;
1683
1946
  try {
@@ -1687,6 +1950,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1687
1950
  ...this.sqlCtx,
1688
1951
  scope: "transaction"
1689
1952
  },
1953
+ parent,
1690
1954
  holdFinishedChildren: this.#holdFinishedChildren
1691
1955
  });
1692
1956
  } catch (error) {
@@ -1710,7 +1974,8 @@ var SqlRuntimeBase = class extends RuntimeCore {
1710
1974
  wrapTransaction(driverTx, connection, activity) {
1711
1975
  this.#openTransactions.set(driverTx, activity);
1712
1976
  this.#openTransactions.set(connection, activity);
1713
- const stopAdopting = () => {
1977
+ const stopAcceptingChildren = () => {
1978
+ activity.stopAcceptingChildren();
1714
1979
  for (const queryable of [driverTx, connection]) if (this.#openTransactions.get(queryable) === activity) this.#openTransactions.delete(queryable);
1715
1980
  };
1716
1981
  let commitAttempted = false;
@@ -1732,7 +1997,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1732
1997
  [transactionSettlement]: settlement,
1733
1998
  async commit() {
1734
1999
  commitAttempted = true;
1735
- stopAdopting();
2000
+ stopAcceptingChildren();
1736
2001
  try {
1737
2002
  await self.#inFlight.track(() => driverTx.commit());
1738
2003
  } catch (error) {
@@ -1750,7 +2015,7 @@ var SqlRuntimeBase = class extends RuntimeCore {
1750
2015
  await commitEnding;
1751
2016
  },
1752
2017
  async rollback() {
1753
- stopAdopting();
2018
+ stopAcceptingChildren();
1754
2019
  if (settlement.committed) {
1755
2020
  await commitEnding?.catch(() => void 0);
1756
2021
  return;
@@ -1773,6 +2038,13 @@ var SqlRuntimeBase = class extends RuntimeCore {
1773
2038
  commitAttempted
1774
2039
  });
1775
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
+ },
1776
2048
  query(plan, options) {
1777
2049
  return self.queryAgainstQueryable(plan, driverTx, {
1778
2050
  ...options,
@@ -1807,16 +2079,19 @@ var SqlRuntimeBase = class extends RuntimeCore {
1807
2079
  return this.closePromise;
1808
2080
  }
1809
2081
  async closeDriverAfterWork() {
1810
- if (this.closeRefusal === "when-idle") await this.waitForIdleTurn();
2082
+ const warned = { done: false };
2083
+ if (this.closeRefusal === "when-idle") await this.waitForIdleTurn(warned);
1811
2084
  this.#refusing = true;
2085
+ this.warnWhenWaitingOnlyForActivities(warned);
1812
2086
  await this.#inFlight.drained();
1813
2087
  await this.driver.close();
1814
2088
  }
1815
- async waitForIdleTurn() {
2089
+ async waitForIdleTurn(warned) {
1816
2090
  for (;;) {
1817
2091
  const startedBefore = this.#inFlight.started;
1818
2092
  await new Promise((resolve) => scheduleTimer(resolve, 0));
1819
2093
  if (!this.#inFlight.active && this.#inFlight.started === startedBefore) return;
2094
+ this.warnWhenWaitingOnlyForActivities(warned);
1820
2095
  await this.#inFlight.drained();
1821
2096
  }
1822
2097
  }
@@ -1869,13 +2144,25 @@ var SqlRuntimeBase = class extends RuntimeCore {
1869
2144
  });
1870
2145
  }
1871
2146
  };
1872
- function standaloneContext(fields) {
1873
- return {
1874
- ...fields,
1875
- parent: void 0,
1876
- state: createStateStore().state,
1877
- inTransaction: () => false
1878
- };
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
+ })());
1879
2166
  }
1880
2167
  function transactionClosedError() {
1881
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.", {});
@@ -1898,26 +2185,56 @@ async function withTransaction(runtime, fn) {
1898
2185
  if (invalidated) throw transactionClosedError();
1899
2186
  }
1900
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
+ }
1901
2232
  const txContext = {
2233
+ ...guardedQueryable(transaction),
1902
2234
  get invalidated() {
1903
2235
  return invalidated;
1904
2236
  },
1905
- query(plan, options) {
1906
- if (invalidated) throw transactionClosedError();
1907
- return new AsyncIterableResult(guardedStream(transaction.query(plan, options)));
1908
- },
1909
- async execute(plan, options) {
1910
- if (invalidated) throw transactionClosedError();
1911
- return transaction.execute(plan, options);
1912
- },
1913
- [preparedStatementQuery](ps, params, options) {
1914
- if (invalidated) throw transactionClosedError();
1915
- return new AsyncIterableResult(guardedStream(runPreparedQuery(transaction, ps, params, options)));
1916
- },
1917
- [preparedStatementExecute](ps, params, options) {
1918
- if (invalidated) throw transactionClosedError();
1919
- return runPreparedExecute(transaction, ps, params, options);
1920
- }
2237
+ [activitySource]: guardedSource(transaction)
1921
2238
  };
1922
2239
  let connectionDisposed = false;
1923
2240
  const destroyConnection = async (reason) => {
@@ -1968,6 +2285,6 @@ async function withTransaction(runtime, fn) {
1968
2285
  }
1969
2286
  }
1970
2287
  //#endregion
1971
- 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 };
1972
2289
 
1973
2290
  //# sourceMappingURL=runtime.mjs.map