effect 4.1.1 → 4.1.2

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 (142) hide show
  1. package/ai-docs/package.json +2 -2
  2. package/dist/ByteSize.d.ts.map +1 -1
  3. package/dist/ByteSize.js +27 -14
  4. package/dist/ByteSize.js.map +1 -1
  5. package/dist/Iterable.d.ts.map +1 -1
  6. package/dist/Iterable.js +27 -24
  7. package/dist/Iterable.js.map +1 -1
  8. package/dist/JsonSchema.d.ts.map +1 -1
  9. package/dist/JsonSchema.js +27 -6
  10. package/dist/JsonSchema.js.map +1 -1
  11. package/dist/MutableRef.d.ts.map +1 -1
  12. package/dist/MutableRef.js +0 -7
  13. package/dist/MutableRef.js.map +1 -1
  14. package/dist/Ref.d.ts.map +1 -1
  15. package/dist/Ref.js +0 -8
  16. package/dist/Ref.js.map +1 -1
  17. package/dist/Schedule.d.ts.map +1 -1
  18. package/dist/Schedule.js +8 -3
  19. package/dist/Schedule.js.map +1 -1
  20. package/dist/Stream.d.ts.map +1 -1
  21. package/dist/Stream.js +6 -5
  22. package/dist/Stream.js.map +1 -1
  23. package/dist/ai/McpServer.d.ts.map +1 -1
  24. package/dist/ai/McpServer.js +61 -33
  25. package/dist/ai/McpServer.js.map +1 -1
  26. package/dist/ai/internal/mcpProtocol/v2026_07_28.js +4 -3
  27. package/dist/ai/internal/mcpProtocol/v2026_07_28.js.map +1 -1
  28. package/dist/ai/internal/structured-output.js +11 -2
  29. package/dist/ai/internal/structured-output.js.map +1 -1
  30. package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  31. package/dist/cluster/ClusterWorkflowEngine.js +18 -9
  32. package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
  33. package/dist/cluster/Entity.d.ts +26 -0
  34. package/dist/cluster/Entity.d.ts.map +1 -1
  35. package/dist/cluster/Entity.js.map +1 -1
  36. package/dist/cluster/MessageStorage.d.ts +6 -6
  37. package/dist/cluster/MessageStorage.d.ts.map +1 -1
  38. package/dist/cluster/MessageStorage.js +1 -3
  39. package/dist/cluster/MessageStorage.js.map +1 -1
  40. package/dist/cluster/Runners.d.ts.map +1 -1
  41. package/dist/cluster/Runners.js +13 -2
  42. package/dist/cluster/Runners.js.map +1 -1
  43. package/dist/cluster/Sharding.d.ts +13 -0
  44. package/dist/cluster/Sharding.d.ts.map +1 -1
  45. package/dist/cluster/Sharding.js.map +1 -1
  46. package/dist/cluster/internal/clusterAbandon.d.ts.map +1 -1
  47. package/dist/cluster/internal/clusterAbandon.js +6 -4
  48. package/dist/cluster/internal/clusterAbandon.js.map +1 -1
  49. package/dist/cluster/internal/entityManager.js +48 -4
  50. package/dist/cluster/internal/entityManager.js.map +1 -1
  51. package/dist/cluster/internal/transactionNotifications.d.ts +5 -0
  52. package/dist/cluster/internal/transactionNotifications.d.ts.map +1 -0
  53. package/dist/cluster/internal/transactionNotifications.js +5 -0
  54. package/dist/cluster/internal/transactionNotifications.js.map +1 -0
  55. package/dist/encoding/Json5.d.ts +44 -0
  56. package/dist/encoding/Json5.d.ts.map +1 -0
  57. package/dist/encoding/Json5.js +56 -0
  58. package/dist/encoding/Json5.js.map +1 -0
  59. package/dist/encoding/Jsonc.d.ts +47 -0
  60. package/dist/encoding/Jsonc.d.ts.map +1 -0
  61. package/dist/encoding/Jsonc.js +120 -0
  62. package/dist/encoding/Jsonc.js.map +1 -0
  63. package/dist/encoding/SchemaBinary.d.ts +94 -0
  64. package/dist/encoding/SchemaBinary.d.ts.map +1 -1
  65. package/dist/encoding/SchemaBinary.js +219 -6
  66. package/dist/encoding/SchemaBinary.js.map +1 -1
  67. package/dist/encoding/index.d.ts +10 -0
  68. package/dist/encoding/index.d.ts.map +1 -1
  69. package/dist/encoding/index.js +10 -0
  70. package/dist/encoding/index.js.map +1 -1
  71. package/dist/eventlog/EventLogServer.d.ts.map +1 -1
  72. package/dist/eventlog/EventLogServer.js +28 -12
  73. package/dist/eventlog/EventLogServer.js.map +1 -1
  74. package/dist/http/HttpClient.d.ts +15 -9
  75. package/dist/http/HttpClient.d.ts.map +1 -1
  76. package/dist/http/HttpClient.js +18 -11
  77. package/dist/http/HttpClient.js.map +1 -1
  78. package/dist/internal/dateTime.js +17 -3
  79. package/dist/internal/dateTime.js.map +1 -1
  80. package/dist/internal/jsonParser.d.ts +5 -0
  81. package/dist/internal/jsonParser.d.ts.map +1 -0
  82. package/dist/internal/jsonParser.js +280 -0
  83. package/dist/internal/jsonParser.js.map +1 -0
  84. package/dist/internal/persistence.js +8 -1
  85. package/dist/internal/persistence.js.map +1 -1
  86. package/dist/internal/sql.js +16 -0
  87. package/dist/internal/sql.js.map +1 -1
  88. package/dist/internal/version.js +1 -1
  89. package/dist/observability/OtlpExporter.d.ts +4 -0
  90. package/dist/observability/OtlpExporter.d.ts.map +1 -1
  91. package/dist/observability/OtlpExporter.js +40 -12
  92. package/dist/observability/OtlpExporter.js.map +1 -1
  93. package/dist/persistence/RateLimiter.d.ts +7 -0
  94. package/dist/persistence/RateLimiter.d.ts.map +1 -1
  95. package/dist/persistence/RateLimiter.js +13 -4
  96. package/dist/persistence/RateLimiter.js.map +1 -1
  97. package/dist/rpc/RpcServer.d.ts.map +1 -1
  98. package/dist/rpc/RpcServer.js +10 -1
  99. package/dist/rpc/RpcServer.js.map +1 -1
  100. package/dist/sql/SqlClient.d.ts +8 -0
  101. package/dist/sql/SqlClient.d.ts.map +1 -1
  102. package/dist/sql/SqlClient.js +36 -12
  103. package/dist/sql/SqlClient.js.map +1 -1
  104. package/dist/sql/Statement.d.ts +5 -0
  105. package/dist/sql/Statement.d.ts.map +1 -1
  106. package/dist/sql/Statement.js +8 -6
  107. package/dist/sql/Statement.js.map +1 -1
  108. package/package.json +4 -4
  109. package/src/ByteSize.ts +29 -14
  110. package/src/Iterable.ts +20 -14
  111. package/src/JsonSchema.ts +45 -7
  112. package/src/MutableRef.ts +1 -8
  113. package/src/Ref.ts +0 -8
  114. package/src/Schedule.ts +8 -6
  115. package/src/Stream.ts +6 -5
  116. package/src/ai/McpServer.ts +66 -43
  117. package/src/ai/internal/mcpProtocol/v2026_07_28.ts +4 -5
  118. package/src/ai/internal/structured-output.ts +10 -4
  119. package/src/cluster/ClusterWorkflowEngine.ts +29 -28
  120. package/src/cluster/Entity.ts +52 -0
  121. package/src/cluster/MessageStorage.ts +3 -6
  122. package/src/cluster/Runners.ts +16 -2
  123. package/src/cluster/Sharding.ts +13 -0
  124. package/src/cluster/internal/clusterAbandon.ts +7 -7
  125. package/src/cluster/internal/entityManager.ts +65 -5
  126. package/src/cluster/internal/transactionNotifications.ts +7 -0
  127. package/src/encoding/Json5.ts +59 -0
  128. package/src/encoding/Jsonc.ts +126 -0
  129. package/src/encoding/SchemaBinary.ts +228 -7
  130. package/src/encoding/index.ts +12 -0
  131. package/src/eventlog/EventLogServer.ts +36 -12
  132. package/src/http/HttpClient.ts +34 -22
  133. package/src/internal/dateTime.ts +26 -3
  134. package/src/internal/jsonParser.ts +307 -0
  135. package/src/internal/persistence.ts +9 -1
  136. package/src/internal/sql.ts +25 -0
  137. package/src/internal/version.ts +1 -1
  138. package/src/observability/OtlpExporter.ts +42 -18
  139. package/src/persistence/RateLimiter.ts +13 -4
  140. package/src/rpc/RpcServer.ts +12 -1
  141. package/src/sql/SqlClient.ts +48 -14
  142. package/src/sql/Statement.ts +8 -13
@@ -10,12 +10,11 @@
10
10
  * @since 4.0.0
11
11
  */
12
12
  import * as Cause from "../Cause.ts"
13
- import { Clock } from "../Clock.ts"
14
13
  import * as Context from "../Context.ts"
15
14
  import * as Effect from "../Effect.ts"
16
15
  import * as Exit from "../Exit.ts"
17
16
  import { identity } from "../Function.ts"
18
- import { CurrentTransactionService } from "../internal/sql.ts"
17
+ import { CurrentTransactionService, recordConnectionWait, waitClock } from "../internal/sql.ts"
19
18
  import * as Option from "../Option.ts"
20
19
  import { hasProperty } from "../Predicate.ts"
21
20
  import type * as Queue from "../Queue.ts"
@@ -283,6 +282,8 @@ export declare namespace SqlClient {
283
282
  let clientIdCounter = 0
284
283
  let transactionSemaphoreIdCounter = 0
285
284
 
285
+ const ATTR_DB_OPERATION_NAME = "db.operation.name"
286
+
286
287
  /**
287
288
  * Constructs a `SqlClient` from connection acquirers, a compiler, transaction
288
289
  * commands, tracing attributes, optional row transforms, and reactive query
@@ -552,6 +553,14 @@ const makeAfterCommit =
552
553
  * caller's context has no `SqlClient`, so their requests don't share a batch
553
554
  * with requests outside the transaction.
554
555
  *
556
+ * Each callback below except `acquireConnection` is traced like a statement,
557
+ * in its own client span under the `sql.transaction` span, named after the
558
+ * operation and the target derived from `spanAttributes`, such as
559
+ * `COMMIT mydb`. With `Statement.SpanPropagationEnabled`, a top-level
560
+ * transaction also records how long `acquireConnection` took as
561
+ * `db.client.connection.wait_time_ms`, so work a driver does there, such as
562
+ * starting the transaction, counts as waiting for the connection.
563
+ *
555
564
  * @stability unstable
556
565
  * @category transactions
557
566
  * @since 4.0.0
@@ -592,6 +601,7 @@ export const makeWithTransaction = <I, S>(options: {
592
601
  `effect/sql/SqlClient/TransactionSemaphore/${transactionSemaphoreIdCounter++}`
593
602
  )
594
603
  const afterCommit = makeAfterCommit(options.transactionService)
604
+ const target = Statement.spanTarget(options.spanAttributes)
595
605
  const deferInvalidations = (reactivity: Reactivity): Reactivity => {
596
606
  const invalidate = (keys: Parameters<Reactivity["invalidate"]>[0]) =>
597
607
  afterCommit(Effect.sync(() => reactivity.invalidateUnsafe(keys)))
@@ -609,13 +619,32 @@ export const makeWithTransaction = <I, S>(options: {
609
619
  }
610
620
  const services = fiber.context
611
621
  const reactivity = Context.getOrUndefined(services, Reactivity)
612
- const clock = fiber.getRef(Clock)
622
+ const propagate = fiber.cache.tracerEnabled && fiber.getRef(Statement.SpanPropagationEnabled)
623
+ const waitedClock = propagate ? waitClock(fiber) : undefined
624
+ // Runs a transaction control in a span of its own, so a failure ends
625
+ // that span with the control's own exit.
626
+ const control = (operation: string, effect: Effect.Effect<void, SqlError>) =>
627
+ Effect.useSpan(
628
+ target === undefined ? operation : `${operation} ${target}`,
629
+ { kind: "client", parent: span },
630
+ (controlSpan) => {
631
+ for (const [key, value] of options.spanAttributes) {
632
+ controlSpan.attribute(key, value)
633
+ }
634
+ controlSpan.attribute(ATTR_DB_OPERATION_NAME, operation)
635
+ return effect
636
+ }
637
+ )
613
638
  const connOption = Context.getOption(services, options.transactionService)
614
639
  const conn: Effect.Effect<readonly [Scope.Closeable | undefined, S], SqlError> = connOption._tag === "Some"
615
640
  ? Effect.succeed([undefined, connOption.value[0]] as const)
616
641
  : Effect.flatMap(Scope.make(), (scope) =>
617
642
  Scope.provide(options.acquireConnection(restore), scope).pipe(
618
- Effect.map((conn) => [scope, conn] as const),
643
+ Effect.provideService(Tracer.ParentSpan, span),
644
+ Effect.map((conn) => {
645
+ if (waitedClock !== undefined) recordConnectionWait(span, waitedClock)
646
+ return [scope, conn] as const
647
+ }),
619
648
  Effect.onError((cause) => Scope.close(scope, Exit.failCause(cause)))
620
649
  ))
621
650
  const id = connOption._tag === "Some" ? connOption.value[1] + 1 : 0
@@ -625,12 +654,16 @@ export const makeWithTransaction = <I, S>(options: {
625
654
  open: true
626
655
  }
627
656
  let committed = false
657
+ const start = (conn: S) =>
658
+ id === 0
659
+ ? control("BEGIN", options.begin(conn, fiber.getRef(BeginTransaction)))
660
+ : control("SAVEPOINT", options.savepoint(conn, id))
628
661
  const transaction = Effect.flatMap(
629
662
  conn,
630
663
  (
631
664
  [scope, conn]
632
665
  ) =>
633
- (id === 0 ? options.begin(conn, fiber.getRef(BeginTransaction)) : options.savepoint(conn, id)).pipe(
666
+ start(conn).pipe(
634
667
  Effect.flatMap(() => {
635
668
  const level = [conn, id] as const
636
669
  afterCommitBuffers.set(level, buffer)
@@ -649,30 +682,31 @@ export const makeWithTransaction = <I, S>(options: {
649
682
  let effect: Effect.Effect<void, SqlError>
650
683
  if (Exit.isSuccess(exit)) {
651
684
  if (id === 0) {
652
- span.event("effect.sql.transaction.commit", clock.currentTimeNanosUnsafe())
653
685
  const onCommitFailure = options.onCommitFailure
686
+ const commit = control("COMMIT", options.commit(conn))
654
687
  effect = onCommitFailure
655
- ? Effect.catchCause(options.commit(conn), (commitCause) =>
656
- Effect.matchCauseEffect(onCommitFailure(conn), {
688
+ ? Effect.catchCause(commit, (commitCause) =>
689
+ Effect.matchCauseEffect(control("ROLLBACK", onCommitFailure(conn)), {
657
690
  onFailure: (cleanupCause) =>
658
691
  Effect.failCause(failuresToDefects(Cause.combine(commitCause, cleanupCause))),
659
692
  onSuccess: () => Effect.failCause(commitCause)
660
693
  }))
661
- : options.commit(conn)
694
+ : commit
662
695
  } else {
663
- span.event("effect.sql.transaction.savepoint", clock.currentTimeNanosUnsafe())
664
696
  effect = Effect.void
665
697
  }
666
698
  } else {
667
- span.event("effect.sql.transaction.rollback", clock.currentTimeNanosUnsafe())
668
699
  effect = Effect.orDie(
669
700
  id > 0
670
- ? options.rollbackSavepoint(conn, id)
671
- : options.rollback(conn)
701
+ ? control("ROLLBACK TO SAVEPOINT", options.rollbackSavepoint(conn, id))
702
+ : control("ROLLBACK", options.rollback(conn))
672
703
  )
673
704
  }
674
705
  if (id > 0 && options.releaseSavepoint) {
675
- effect = Effect.andThen(effect, Effect.orDie(options.releaseSavepoint(conn, id)))
706
+ effect = Effect.andThen(
707
+ effect,
708
+ Effect.orDie(control("RELEASE SAVEPOINT", options.releaseSavepoint(conn, id)))
709
+ )
676
710
  }
677
711
  return Effect.flatMap(effect, () => {
678
712
  committed = Exit.isSuccess(exit)
@@ -20,6 +20,7 @@ import type * as Fiber from "../Fiber.ts"
20
20
  import { constUndefined } from "../Function.ts"
21
21
  import * as internalEffect from "../internal/effect.ts"
22
22
  import * as InternalRecord from "../internal/record.ts"
23
+ import { recordConnectionWait, waitClock } from "../internal/sql.ts"
23
24
  import { hasProperty } from "../Predicate.ts"
24
25
  import { TracerTimingEnabled } from "../References.ts"
25
26
  import * as Stream from "../Stream.ts"
@@ -154,6 +155,11 @@ export const CurrentTransformer = Context.Reference<Transformer | undefined>("ef
154
155
  * waited for a connection as `db.client.connection.wait_time_ms`. Defaults to
155
156
  * `false`; ignored when tracing is disabled.
156
157
  *
158
+ * **Details**
159
+ *
160
+ * A top-level transaction also records how long it waited for its
161
+ * connection on its `sql.transaction` span.
162
+ *
157
163
  * @stability unstable
158
164
  * @category services
159
165
  * @since 4.0.0
@@ -1402,7 +1408,6 @@ export const spanName = (spanAttributes: ReadonlyArray<readonly [string, unknown
1402
1408
  // internal
1403
1409
 
1404
1410
  const ATTR_DB_QUERY_TEXT = "db.query.text"
1405
- const ATTR_DB_CLIENT_CONNECTION_WAIT_TIME = "db.client.connection.wait_time_ms"
1406
1411
  const ATTR_SQL_METHOD = "effect.sql.method"
1407
1412
 
1408
1413
  // the last value wins, matching the order the attributes are applied to spans
@@ -1511,6 +1516,8 @@ const StatementProto: Omit<
1511
1516
  span.attribute(ATTR_SQL_METHOD, operation)
1512
1517
  span.attribute(ATTR_DB_QUERY_TEXT, sql)
1513
1518
  const propagate = fiber.cache.tracerEnabled && fiber.getRef(SpanPropagationEnabled)
1519
+ // Measured from the span's start, so the wait also covers compiling the
1520
+ // statement and any `CurrentTransformer` run first.
1514
1521
  const clock = propagate ? waitClock(fiber) : undefined
1515
1522
  const run = clock === undefined
1516
1523
  ? (connection: Connection) => f(connection, sql, params)
@@ -1627,18 +1634,6 @@ const StatementProto: Omit<
1627
1634
  }
1628
1635
  }
1629
1636
 
1630
- // Without span timing, the span has no start time to measure from.
1631
- const waitClock = (fiber: Fiber.Fiber<unknown, unknown>): Clock | undefined =>
1632
- fiber.getRef(TracerTimingEnabled) ? fiber.getRef(Clock) : undefined
1633
-
1634
- // Measured from the statement span's start to the connection hand-off, so it
1635
- // also covers compiling the statement and any `CurrentTransformer` run first.
1636
- const recordConnectionWait = (span: Tracer.Span, clock: Clock): void =>
1637
- span.attribute(
1638
- ATTR_DB_CLIENT_CONNECTION_WAIT_TIME,
1639
- Number(clock.currentTimeNanosUnsafe() - span.status.startTime) / 1e6
1640
- )
1641
-
1642
1637
  const withStatement = <A, X, E, R>(
1643
1638
  self: StatementImpl<A>,
1644
1639
  span: Tracer.Span,