@zio.dev/zio-blocks 0.0.51 → 0.0.56

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 (166) hide show
  1. package/adr/2026-07-18-data-migration.md +123 -0
  2. package/guides/async-getting-started.md +687 -0
  3. package/guides/compile-time-resource-safety-with-scope.md +6 -0
  4. package/guides/getting-started-with-mux.md +0 -112
  5. package/guides/query-dsl-extending.md +1 -1
  6. package/guides/query-dsl-fluent-builder.md +1 -1
  7. package/guides/query-dsl-reified-optics.md +1 -1
  8. package/guides/query-dsl-sql.md +395 -1
  9. package/guides/sql-checked-interpolation.md +173 -0
  10. package/guides/sql-transactions.md +286 -0
  11. package/guides/telemetry-guide.md +131 -70
  12. package/guides/zio-schema-migration.md +6 -6
  13. package/index.md +200 -559
  14. package/package.json +1 -1
  15. package/reference/async.md +1379 -531
  16. package/reference/chunk.md +3 -3
  17. package/reference/codegen/index.md +1 -1
  18. package/reference/combinators.md +4 -4
  19. package/reference/config/config-decoder.md +460 -0
  20. package/reference/config/config-source.md +489 -0
  21. package/reference/config/errors.md +278 -0
  22. package/reference/config/flags.md +369 -0
  23. package/reference/config/formats.md +314 -0
  24. package/reference/config/index.md +304 -0
  25. package/reference/config/rollout.md +336 -0
  26. package/reference/context.md +6 -49
  27. package/reference/data-migration.md +269 -0
  28. package/reference/datastar/attributes.md +302 -0
  29. package/reference/datastar/events.md +234 -0
  30. package/reference/datastar/index.md +256 -0
  31. package/reference/datastar/signals.md +230 -0
  32. package/reference/datastar/sse.md +295 -0
  33. package/reference/datastar.md +2 -2
  34. package/reference/docs.md +2 -2
  35. package/reference/endpoint/bulk-creation.md +96 -0
  36. package/reference/endpoint/endpoint.md +1 -0
  37. package/reference/endpoint/index.md +9 -89
  38. package/reference/endpoint/path-codec.md +12 -24
  39. package/reference/endpoint/route-pattern.md +4 -6
  40. package/reference/endpoint/segment-codec.md +19 -32
  41. package/reference/html.md +313 -9
  42. package/reference/htmx/index.md +4 -52
  43. package/reference/htmx/response-headers.md +240 -0
  44. package/reference/http-model/headers.md +735 -0
  45. package/reference/http-model/index.md +3 -1
  46. package/reference/http-model/model.md +107 -71
  47. package/reference/http-model/schema-codecs.md +522 -0
  48. package/reference/http-model/schema.md +6 -3
  49. package/reference/http-model/server-sent-event.md +341 -0
  50. package/reference/jwt.md +195 -0
  51. package/reference/maybe.md +128 -11
  52. package/reference/media-type.md +2 -2
  53. package/reference/mux.mdx +7 -2
  54. package/reference/openapi.md +3 -3
  55. package/reference/projection.md +654 -0
  56. package/reference/resource-management/index.md +1 -1
  57. package/reference/resource-management/resource.md +2 -98
  58. package/reference/resource-management/scope.md +1 -209
  59. package/reference/resource-management/wire.md +4 -50
  60. package/reference/ringbuffer/advanced.mdx +1 -1
  61. package/reference/ringbuffer/index.mdx +3 -3
  62. package/reference/ringbuffer/mpmc.mdx +38 -4
  63. package/reference/ringbuffer/mpsc.mdx +36 -4
  64. package/reference/ringbuffer/spmc.mdx +1 -1
  65. package/reference/ringbuffer/spsc.mdx +87 -15
  66. package/reference/schema/allows.md +0 -96
  67. package/reference/schema/binding.md +2 -2
  68. package/reference/schema/built-in-codecs/avro.md +2 -2
  69. package/reference/schema/built-in-codecs/bson.md +50 -20
  70. package/reference/schema/built-in-codecs/csv.md +2 -2
  71. package/reference/schema/built-in-codecs/index.md +3 -3
  72. package/reference/schema/built-in-codecs/json/index.md +2 -2
  73. package/reference/schema/built-in-codecs/json/json.md +1 -0
  74. package/reference/schema/built-in-codecs/messagepack.md +3 -3
  75. package/reference/schema/built-in-codecs/thrift.md +2 -2
  76. package/reference/schema/built-in-codecs/toon.md +3 -3
  77. package/reference/schema/built-in-codecs/yaml.md +2 -2
  78. package/reference/schema/codec.md +11 -11
  79. package/reference/schema/dynamic-optic.md +48 -3
  80. package/reference/schema/dynamic-schema.md +3 -3
  81. package/reference/schema/index.md +2 -0
  82. package/reference/schema/path-interpolator.md +2 -0
  83. package/reference/schema/reflect-transformer.md +140 -0
  84. package/reference/schema/schema-evolution/as.md +4 -4
  85. package/reference/schema/schema-evolution/into.md +2 -2
  86. package/reference/schema/schema-expr.md +2 -2
  87. package/reference/schema/schema-search.md +263 -0
  88. package/reference/schema/schema.md +10 -2
  89. package/reference/schema/type-class-derivation.md +1 -1
  90. package/reference/smithy.md +502 -3
  91. package/reference/sql/db-codec-deriver.md +3 -3
  92. package/reference/sql/db-codec.md +22 -22
  93. package/reference/sql/db-con.md +4 -4
  94. package/reference/sql/db-connection.md +1 -1
  95. package/reference/sql/db-param.md +1 -1
  96. package/reference/sql/db-result-reader.md +4 -2
  97. package/reference/sql/db-tx.md +46 -14
  98. package/reference/sql/ddl.md +1 -1
  99. package/reference/sql/frag.md +44 -10
  100. package/reference/sql/index.md +7 -7
  101. package/reference/sql/repo.md +15 -15
  102. package/reference/sql/sql-dialect.md +1 -1
  103. package/reference/sql/sql-logger.md +1 -1
  104. package/reference/sql/sql-name-mapper.md +3 -3
  105. package/reference/sql/table-metadata.md +3 -3
  106. package/reference/sql/table.md +10 -10
  107. package/reference/sql/transactor-zio.md +1 -1
  108. package/reference/sql/transactor.md +21 -11
  109. package/reference/sql-zio.md +2 -2
  110. package/reference/streams/core/index.md +32 -0
  111. package/reference/streams/{pipeline.md → core/pipeline.md} +210 -74
  112. package/reference/streams/{sink.md → core/sink.md} +331 -353
  113. package/reference/streams/{stream.md → core/stream.md} +919 -209
  114. package/reference/streams/execution-and-compatibility/async-execution.md +822 -0
  115. package/reference/streams/execution-and-compatibility/index.md +35 -0
  116. package/reference/streams/execution-and-compatibility/platform-differences.md +297 -0
  117. package/reference/streams/execution-and-compatibility/scala-2-compatibility.md +88 -0
  118. package/reference/streams/execution-and-compatibility/zero-boxing.md +393 -0
  119. package/reference/streams/index.md +140 -67
  120. package/reference/streams/primitives/index.md +30 -0
  121. package/reference/streams/primitives/reader.md +1992 -0
  122. package/reference/streams/{writer.md → primitives/writer.md} +254 -98
  123. package/reference/telemetry/common/any-value.md +90 -0
  124. package/reference/telemetry/common/attribute-key.md +87 -0
  125. package/reference/telemetry/common/attributes.md +118 -0
  126. package/reference/telemetry/common/index.md +39 -0
  127. package/reference/telemetry/common/instrumentation-scope.md +24 -0
  128. package/reference/telemetry/common/resource.md +34 -0
  129. package/reference/telemetry/index.md +311 -0
  130. package/reference/telemetry/logging/index.md +197 -0
  131. package/reference/telemetry/logging/log-enrichment.md +72 -0
  132. package/reference/telemetry/logging/log-formatter.md +100 -0
  133. package/reference/telemetry/logging/log-record-processor.md +56 -0
  134. package/reference/telemetry/logging/log-record.md +44 -0
  135. package/reference/telemetry/logging/log-writer.md +64 -0
  136. package/reference/telemetry/logging/logger-provider.md +142 -0
  137. package/reference/telemetry/logging/logger.md +83 -0
  138. package/reference/telemetry/logging/severity.md +62 -0
  139. package/reference/telemetry/metrics/index.md +150 -0
  140. package/reference/telemetry/metrics/instruments.md +183 -0
  141. package/reference/telemetry/metrics/labeled-instruments.md +74 -0
  142. package/reference/telemetry/metrics/meter-provider.md +76 -0
  143. package/reference/telemetry/metrics/meter.md +98 -0
  144. package/reference/telemetry/metrics/metric-data.md +57 -0
  145. package/reference/telemetry/otel/custom-exporter.md +216 -0
  146. package/reference/telemetry/otel/index.md +212 -0
  147. package/reference/telemetry/tracing/index.md +155 -0
  148. package/reference/telemetry/tracing/sampler.md +89 -0
  149. package/reference/telemetry/tracing/span-builder.md +57 -0
  150. package/reference/telemetry/tracing/span-context.md +39 -0
  151. package/reference/telemetry/tracing/span-data.md +32 -0
  152. package/reference/telemetry/tracing/span-kind.md +55 -0
  153. package/reference/telemetry/tracing/span-processor.md +53 -0
  154. package/reference/telemetry/tracing/span-status.md +47 -0
  155. package/reference/telemetry/tracing/span.md +117 -0
  156. package/reference/telemetry/tracing/tracer-provider.md +91 -0
  157. package/reference/telemetry/tracing/tracer.md +52 -0
  158. package/reference/typeid.md +0 -64
  159. package/sidebars.js +365 -185
  160. package/undocumented-report.md +528 -270
  161. package/reference/config.md +0 -158
  162. package/reference/streams/concurrent-operators.md +0 -106
  163. package/reference/streams/reader.md +0 -1284
  164. package/reference/streams/scala-2-compatibility.md +0 -55
  165. package/reference/streams/zero-boxing.md +0 -275
  166. package/reference/telemetry.md +0 -693
@@ -41,7 +41,7 @@ SqlNameMapper.Identity("firstName")
41
41
 
42
42
  val upper = SqlNameMapper.Custom(_.toUpperCase)
43
43
  // upper: Custom = Custom(
44
- // repl.MdocSession$MdocApp0$$Lambda$20339/0x00007f2996f5b000@1850c853
44
+ // repl.MdocSession$MdocApp0$$Lambda/0x000000003afd1000@5050da69
45
45
  // )
46
46
  upper("firstName")
47
47
  // res4: String = "FIRSTNAME"
@@ -58,9 +58,9 @@ object Order { given schema: Schema[Order] = Schema.derived }
58
58
 
59
59
  // Use UPPERCASE column names instead of snake_case
60
60
  val upperDeriver = DbCodecDeriver.withColumnNameMapper(SqlNameMapper.Custom(_.toUpperCase))
61
- // upperDeriver: DbCodecDeriver = zio.blocks.sql.DbCodecDeriver@646cca72
61
+ // upperDeriver: DbCodecDeriver = zio.blocks.sql.DbCodecDeriver@282873df
62
62
  val codec: DbCodec[Order] = Order.schema.deriving(upperDeriver).derive
63
- // codec: DbCodec[Order] = zio.blocks.sql.DbCodecDeriver$$anon$20@596dacd
63
+ // codec: DbCodec[Order] = zio.blocks.sql.DbCodecDeriver$$anon$10@6838c076
64
64
  codec.columns
65
65
  // res6: IndexedSeq[String] = Vector("ORDERID", "TOTALAMOUNT")
66
66
  ```
@@ -80,7 +80,7 @@ import zio.blocks.sql.{Table, TableNamingPolicy}
80
80
  val table1 = Table.derived[Product]
81
81
  // table1: Table[Product] = Table(
82
82
  // name = "product",
83
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@40f5588b,
83
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@30880538,
84
84
  // columnsMeta = Vector(
85
85
  // ColumnMeta(name = "id", dbValue = DbInt(0), nullable = false),
86
86
  // ColumnMeta(name = "name", dbValue = DbString(""), nullable = false),
@@ -94,7 +94,7 @@ table1.name
94
94
  val table2 = Table.derived[Product](TableNamingPolicy.Plural)
95
95
  // table2: Table[Product] = Table(
96
96
  // name = "products",
97
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@13590a4,
97
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@504beffa,
98
98
  // columnsMeta = Vector(
99
99
  // ColumnMeta(name = "id", dbValue = DbInt(0), nullable = false),
100
100
  // ColumnMeta(name = "name", dbValue = DbString(""), nullable = false),
@@ -108,7 +108,7 @@ table2.name
108
108
  val table3 = Table.derived[Product](TableNamingPolicy.Custom("t_" + _))
109
109
  // table3: Table[Product] = Table(
110
110
  // name = "t_Product",
111
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@2fa45824,
111
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@32e4f8e3,
112
112
  // columnsMeta = Vector(
113
113
  // ColumnMeta(name = "id", dbValue = DbInt(0), nullable = false),
114
114
  // ColumnMeta(name = "name", dbValue = DbString(""), nullable = false),
@@ -46,7 +46,7 @@ object User {
46
46
  val table = Table.derived[User]("users")
47
47
  // table: Table[User] = Table(
48
48
  // name = "users",
49
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@178274d,
49
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@6651357c,
50
50
  // columnsMeta = Vector(
51
51
  // ColumnMeta(name = "id", dbValue = DbInt(0), nullable = false),
52
52
  // ColumnMeta(name = "name", dbValue = DbString(""), nullable = false),
@@ -97,7 +97,7 @@ object BlogPost {
97
97
  val table = Table.derived[BlogPost]
98
98
  // table: Table[BlogPost] = Table(
99
99
  // name = "blog_post",
100
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@56665516,
100
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@6d450c2f,
101
101
  // columnsMeta = Vector(
102
102
  // ColumnMeta(name = "title", dbValue = DbString(""), nullable = false),
103
103
  // ColumnMeta(name = "body", dbValue = DbString(""), nullable = false)
@@ -133,7 +133,7 @@ object UserProfile {
133
133
  val table = Table.derived[UserProfile]("profiles")
134
134
  // table: Table[UserProfile] = Table(
135
135
  // name = "profiles",
136
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@33f920a0,
136
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@55ca7a37,
137
137
  // columnsMeta = Vector(
138
138
  // ColumnMeta(name = "first_name", dbValue = DbString(""), nullable = false),
139
139
  // ColumnMeta(name = "last_name", dbValue = DbString(""), nullable = false)
@@ -173,7 +173,7 @@ object Category {
173
173
  val singular = Table.derived[Category](TableNamingPolicy.Singular)
174
174
  // singular: Table[Category] = Table(
175
175
  // name = "category",
176
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@8cbb675,
176
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@b14761,
177
177
  // columnsMeta = Vector(
178
178
  // ColumnMeta(name = "name", dbValue = DbString(""), nullable = false)
179
179
  // )
@@ -184,7 +184,7 @@ singular.name
184
184
  val plural = Table.derived[Category](TableNamingPolicy.Plural)
185
185
  // plural: Table[Category] = Table(
186
186
  // name = "categories",
187
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@54cdf256,
187
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@27c3ea48,
188
188
  // columnsMeta = Vector(
189
189
  // ColumnMeta(name = "name", dbValue = DbString(""), nullable = false)
190
190
  // )
@@ -195,7 +195,7 @@ plural.name
195
195
  val custom = Table.derived[Category](TableNamingPolicy.Custom(n => s"tbl_$n"))
196
196
  // custom: Table[Category] = Table(
197
197
  // name = "tbl_Category",
198
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@4860b66a,
198
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@6e6a1e8c,
199
199
  // columnsMeta = Vector(
200
200
  // ColumnMeta(name = "name", dbValue = DbString(""), nullable = false)
201
201
  // )
@@ -232,7 +232,7 @@ val meta = IndexedSeq(
232
232
  val table = Table[Tag]("tag", DbCodec[Tag], meta)
233
233
  // table: Table[Tag] = Table(
234
234
  // name = "tag",
235
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@7d9c62e9,
235
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@1b362cb8,
236
236
  // columnsMeta = Vector(
237
237
  // ColumnMeta(name = "id", dbValue = DbInt(0), nullable = false),
238
238
  // ColumnMeta(name = "label", dbValue = DbString(""), nullable = false)
@@ -278,7 +278,7 @@ object OrderLine {
278
278
  val table = Table.derived[OrderLine]
279
279
  // table: Table[OrderLine] = Table(
280
280
  // name = "order_line",
281
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@3d3c4a76,
281
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@59d9d745,
282
282
  // columnsMeta = Vector(
283
283
  // ColumnMeta(name = "product_id", dbValue = DbInt(0), nullable = false),
284
284
  // ColumnMeta(name = "quantity", dbValue = DbInt(0), nullable = false),
@@ -317,7 +317,7 @@ object Product {
317
317
  val table = Table.derived[Product]
318
318
  // table: Table[Product] = Table(
319
319
  // name = "product",
320
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@5f7e746b,
320
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@13a46a35,
321
321
  // columnsMeta = Vector(
322
322
  // ColumnMeta(name = "sku", dbValue = DbString(""), nullable = false),
323
323
  // ColumnMeta(name = "price", dbValue = DbBigDecimal(0), nullable = false),
@@ -366,7 +366,7 @@ object Session {
366
366
  val table = Table.derived[Session]
367
367
  // table: Table[Session] = Table(
368
368
  // name = "session",
369
- // codec = zio.blocks.sql.DbCodecDeriver$$anon$20@3fa2a4af,
369
+ // codec = zio.blocks.sql.DbCodecDeriver$$anon$10@72e9a985,
370
370
  // columnsMeta = Vector(
371
371
  // ColumnMeta(name = "token", dbValue = DbString(""), nullable = false),
372
372
  // ColumnMeta(name = "user_id", dbValue = DbInt(0), nullable = false)
@@ -95,7 +95,7 @@ val transactorLayer: ZLayer[Any, Nothing, TransactorZIO] =
95
95
  Add the `zio-blocks-sql-zio` artifact to your build. It depends on `zio-blocks-sql`, so you do not need to declare both:
96
96
 
97
97
  ```scala
98
- libraryDependencies += "dev.zio" %% "zio-blocks-sql-zio" % "0.0.51"
98
+ libraryDependencies += "dev.zio" %% "zio-blocks-sql-zio" % "0.0.56"
99
99
  ```
100
100
 
101
101
  The artifact is JVM-only and requires Scala 3.
@@ -25,9 +25,12 @@ The structural shape of the trait is:
25
25
  trait Transactor {
26
26
  def connect[A](f: DbCon ?=> A): A
27
27
  def transact[A](f: DbTx ?=> A): A
28
+ def transact[A](isolation: TransactionIsolation, readOnly: Boolean)(f: DbTx ?=> A): A
28
29
  }
29
30
  ```
30
31
 
32
+ The no-arg `transact` preserves the driver’s default isolation level and `readOnly` flag, while the two-arg overload lets callers request an explicit `TransactionIsolation` (`ReadUncommitted(1)`, `ReadCommitted(2)`, `RepeatableRead(4)`, `Serializable(8)`) and read-only mode, plus the savepoint-based nested transaction support described in `DbTx`.
33
+
31
34
  `JdbcTransactor` is the concrete JDBC-backed implementation. Its companion object provides factory methods for all common connection strategies:
32
35
 
33
36
  ```scala
@@ -122,7 +125,7 @@ import zio.blocks.sql._
122
125
  // Without credentials — useful for SQLite or URL-embedded auth
123
126
  val sqlite: JdbcTransactor =
124
127
  JdbcTransactor.fromUrl("jdbc:sqlite::memory:", SqlDialect.SQLite)
125
- // sqlite: JdbcTransactor = zio.blocks.sql.JdbcTransactor@6bc883b
128
+ // sqlite: JdbcTransactor = zio.blocks.sql.JdbcTransactor@fa1ea01
126
129
  ```
127
130
 
128
131
  Use the three-argument overload when the database requires a username and password supplied separately:
@@ -138,7 +141,7 @@ val postgres: JdbcTransactor =
138
141
  "secret",
139
142
  SqlDialect.PostgreSQL
140
143
  )
141
- // postgres: JdbcTransactor = zio.blocks.sql.JdbcTransactor@40cda9e
144
+ // postgres: JdbcTransactor = zio.blocks.sql.JdbcTransactor@6fff1b52
142
145
  ```
143
146
 
144
147
  :::caution
@@ -225,16 +228,19 @@ Inside `connect`, auto-commit is left at its default state (typically `true` for
225
228
 
226
229
  ### Transaction Management
227
230
 
228
- `Transactor#transact` builds on `connect` by adding full transaction semantics: it disables auto-commit before executing the body, commits when the body returns normally, and rolls back when the body throws. The connection is always closed after commit or rollback.
229
-
230
- It acquires a connection, sets `autoCommit = false`, synthesizes a `DbTx` given value, and runs the body. On success it calls `conn.commit()`. On any exception it calls `conn.rollback()`, adds any rollback failure as a suppressed exception, and rethrows the original. The connection is closed in the `finally` block regardless of outcome:
231
+ `Transactor#transact` builds on `connect` by adding full transaction semantics: it disables auto-commit before executing the body, commits when the body returns normally, and rolls back when the body throws. The connection is always closed after commit or rollback. Two overloads are available — a no-arg form that preserves the driver’s defaults and a two-arg form that sets isolation and `readOnly` explicitly:
231
232
 
232
233
  ```scala
233
234
  trait Transactor {
234
235
  def transact[A](f: DbTx ?=> A): A
236
+ def transact[A](isolation: TransactionIsolation, readOnly: Boolean)(f: DbTx ?=> A): A
235
237
  }
236
238
  ```
237
239
 
240
+ The two-arg overload acquires a connection, saves the previous isolation level and `readOnly` flag, calls `setTransactionIsolation(isolation.jdbcLevel)` (fail-fast — isolation failures propagate) and best-effort `setReadOnly(readOnly)` (SQLite may throw, which is swallowed), sets `autoCommit = false` (fail-fast), synthesizes a `DbTx` given value, and runs the body. On success it calls `conn.commit()`. On any exception it calls `conn.rollback()`, adds any rollback failure as a suppressed exception, and rethrows the original. Previous isolation, `readOnly`, and `autoCommit` are restored and the connection is closed in the `finally` block regardless of outcome. SQLite natively supports only `SERIALIZABLE` — other levels are accepted via `setTransactionIsolation` but the engine still behaves as serializable.
241
+
242
+ The no-arg overload preserves driver defaults (e.g. PostgreSQL `READ_COMMITTED`) and does not force `SERIALIZABLE`; it simply sets `autoCommit = false` before running the body, with the same commit/rollback and cleanup guarantees.
243
+
238
244
  Because `DbTx extends DbCon`, the `DbTx` given satisfies any `DbCon ?=>` requirement inside the block. We can mix `Repo` CRUD calls with raw `sql"..."` fragments freely:
239
245
 
240
246
  ```scala
@@ -246,12 +252,12 @@ case class User(id: Int, name: String, email: String)
246
252
  object User { implicit val schema: Schema[User] = Schema.derived }
247
253
 
248
254
  implicit val userCodec: DbCodec[User] = User.schema.deriving(DbCodecDeriver).derive
249
- // userCodec: DbCodec[User] = zio.blocks.sql.DbCodecDeriver$$anon$20@72550983
255
+ // userCodec: DbCodec[User] = zio.blocks.sql.DbCodecDeriver$$anon$10@74798ce9
250
256
 
251
257
  val repo = Repo.derived[User, Int]("users", "id", _.id)
252
- // repo: Repo[User, Int] = zio.blocks.sql.Repo$DerivedRepo@144fc885
258
+ // repo: Repo[User, Int] = zio.blocks.sql.Repo$DerivedRepo@25a2fe55
253
259
  val transactor = JdbcTransactor.fromUrl("jdbc:sqlite::memory:", SqlDialect.SQLite)
254
- // transactor: JdbcTransactor = zio.blocks.sql.JdbcTransactor@12877e41
260
+ // transactor: JdbcTransactor = zio.blocks.sql.JdbcTransactor@57b2f789
255
261
 
256
262
  transactor.transact {
257
263
  repo.table.createTable(summon[DbTx].dialect).update
@@ -272,6 +278,10 @@ transactor.transact {
272
278
  If `commit` itself throws after a successful body, the transaction is rolled back and the commit exception propagates. The body's return value is discarded in that case.
273
279
  :::
274
280
 
281
+ ### Nested Transactions (Savepoints)
282
+
283
+ Inside `transact`, nested work is emulated via SQL savepoints on the same JDBC connection through `DbTx` — `summon[DbTx].transact { ... }`, `DbTx.transactNested`, or the top-level `transactNested` helper. Savepoints are named `zib_tx_1 .. zib_tx_N` with depth tracked in `DbTx.currentDepth`; inner success issues `RELEASE SAVEPOINT`, failure issues `ROLLBACK TO SAVEPOINT` then rethrows. See [DbTx](db-tx) for full savepoint semantics.
284
+
275
285
  ## JdbcTransactor
276
286
 
277
287
  `JdbcTransactor` is the only concrete implementation of `Transactor` in the `sql` module. It holds three constructor parameters: `connectionFactory`, `dialect`, and `sqlLogger`. The factory methods on its companion object cover the most common configurations; the primary constructor is available for custom setups such as test harnesses that inject a pre-existing connection:
@@ -323,12 +333,12 @@ case class User(id: Int, name: String, email: String)
323
333
  object User { implicit val schema: Schema[User] = Schema.derived }
324
334
 
325
335
  implicit val userCodec: DbCodec[User] = User.schema.deriving(DbCodecDeriver).derive
326
- // userCodec: DbCodec[User] = zio.blocks.sql.DbCodecDeriver$$anon$20@460334f6
336
+ // userCodec: DbCodec[User] = zio.blocks.sql.DbCodecDeriver$$anon$10@3454ab4b
327
337
 
328
338
  val repo = Repo.derived[User, Int]("users", "id", _.id)
329
- // repo: Repo[User, Int] = zio.blocks.sql.Repo$DerivedRepo@25787e5
339
+ // repo: Repo[User, Int] = zio.blocks.sql.Repo$DerivedRepo@bab4308
330
340
  val transactor = JdbcTransactor.fromUrl("jdbc:sqlite::memory:", SqlDialect.SQLite)
331
- // transactor: JdbcTransactor = zio.blocks.sql.JdbcTransactor@7fefa5d1
341
+ // transactor: JdbcTransactor = zio.blocks.sql.JdbcTransactor@74ce711c
332
342
 
333
343
  // Helper that composes two Repo calls — requires only DbCon, not Transactor
334
344
  def upsertUser(user: User)(using DbCon): Unit = {
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  id: sql-zio
3
- title: "SQL — ZIO Integration"
3
+ title: "ZIO Integration"
4
4
  ---
5
5
 
6
6
  `zio-blocks-sql-zio` is the ZIO adapter for `zio-blocks-sql`. It wraps the
@@ -16,7 +16,7 @@ and effect-aware methods. For a full method-by-method reference on
16
16
  ## Installation
17
17
 
18
18
  ```scala
19
- libraryDependencies += "dev.zio" %% "zio-blocks-sql-zio" % "0.0.51"
19
+ libraryDependencies += "dev.zio" %% "zio-blocks-sql-zio" % "0.0.56"
20
20
  ```
21
21
 
22
22
  ## Quick Start
@@ -0,0 +1,32 @@
1
+ ---
2
+ id: index
3
+ title: "Core Types"
4
+ description: "Core Types index: Stream, Pipeline, and Sink, the declarative descriptions you compose into a stream processing pipeline."
5
+ keywords:
6
+ - "Pull-Based Streams"
7
+ - "Stream Composition"
8
+ - "Core Types Overview"
9
+ - "Sink"
10
+ sidebar_label: "Core Types"
11
+ ---
12
+
13
+ `Stream`, `Pipeline`, and `Sink` are the three types you compose to build a pipeline. Each is a lazy, immutable description rather than a running process: you assemble one with ordinary combinators, and nothing executes until a terminal operation such as `stream.runAsync(sink)` — or `stream.run(sink)`, which is JVM-only — compiles and drives it.
14
+
15
+ Compiling is what materializes a description into a [`Reader`](../primitives/reader.md), the stateful cursor a sink pulls from. Those live primitives are documented under [Low-Level Primitives](../primitives/index.md); this section covers the descriptions you write.
16
+
17
+ ## Stream
18
+
19
+ [`Stream[+E, +A]`](./stream.md) describes a source of elements of type `A` that may fail with `E`. Values are produced lazily, so a stream can outlive what fits in memory and can hold an external resource open only while it is being drained.
20
+
21
+ ## Pipeline
22
+
23
+ [`Pipeline[-In, +Out]`](./pipeline.md) describes a reusable transformation from `In` to `Out`. Reach for it when the same steps apply to more than one stream. Pipelines compose with `andThen`, apply to a stream with `stream.via(pipe)`, and to a sink with `pipe.andThenSink(sink)`.
24
+
25
+ ## Sink
26
+
27
+ [`Sink[+E, -A, +Z]`](./sink.md) describes how to consume elements of type `A` into a result `Z`, possibly failing with `E` — the endpoint of a pipeline, built once and reusable across streams.
28
+
29
+ ## See Also
30
+
31
+ - [Streams Reference](../index.md) — module overview
32
+ - [Low-Level Primitives](../primitives/index.md) — the `Reader` and `Writer` cursors these compile into