@zio.dev/zio-blocks 0.0.33 → 0.0.55

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 (215) 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 +21 -16
  4. package/guides/getting-started-with-mux.md +1395 -0
  5. package/guides/query-dsl-extending.md +161 -102
  6. package/guides/query-dsl-fluent-builder.md +217 -157
  7. package/guides/query-dsl-reified-optics.md +12 -10
  8. package/guides/query-dsl-sql.md +640 -165
  9. package/guides/sql-checked-interpolation.md +173 -0
  10. package/guides/sql-transactions.md +286 -0
  11. package/guides/telemetry-guide.md +1130 -0
  12. package/guides/zio-schema-migration.md +29 -22
  13. package/index.md +248 -389
  14. package/package.json +1 -1
  15. package/plans/config-follow-up-prs.md +188 -0
  16. package/plans/config-pr-assessment-roadmap.md +310 -0
  17. package/reference/MuxDataFlow.jsx +250 -0
  18. package/reference/async.md +1499 -0
  19. package/reference/chunk.md +3533 -308
  20. package/reference/codegen/case-class.md +436 -0
  21. package/reference/codegen/emitter-config.md +383 -0
  22. package/reference/codegen/examples.md +664 -0
  23. package/reference/codegen/field.md +316 -0
  24. package/reference/codegen/index.md +317 -0
  25. package/reference/codegen/scala-emitter.md +392 -0
  26. package/reference/codegen/scala-file.md +276 -0
  27. package/reference/codegen/sealed-trait.md +408 -0
  28. package/reference/codegen/type-definition.md +340 -0
  29. package/reference/codegen/type-ref.md +201 -0
  30. package/reference/combinators.md +347 -117
  31. package/reference/config/config-decoder.md +460 -0
  32. package/reference/config/config-source.md +489 -0
  33. package/reference/config/errors.md +278 -0
  34. package/reference/config/flags.md +369 -0
  35. package/reference/config/formats.md +314 -0
  36. package/reference/config/index.md +304 -0
  37. package/reference/config/rollout.md +336 -0
  38. package/reference/context.md +9 -52
  39. package/reference/data-migration.md +269 -0
  40. package/reference/datastar/attributes.md +302 -0
  41. package/reference/datastar/events.md +234 -0
  42. package/reference/datastar/index.md +256 -0
  43. package/reference/datastar/signals.md +230 -0
  44. package/reference/datastar/sse.md +295 -0
  45. package/reference/datastar.md +346 -0
  46. package/reference/docs.md +1461 -345
  47. package/reference/endpoint/auth-type.md +146 -0
  48. package/reference/endpoint/bulk-creation.md +96 -0
  49. package/reference/endpoint/endpoint.md +297 -0
  50. package/reference/endpoint/http-codec.md +249 -0
  51. package/reference/endpoint/index.md +745 -0
  52. package/reference/endpoint/path-codec.md +225 -0
  53. package/reference/endpoint/route-pattern.md +194 -0
  54. package/reference/endpoint/route-tree.md +111 -0
  55. package/reference/endpoint/segment-codec.md +199 -0
  56. package/reference/html.md +1424 -0
  57. package/reference/htmx/attribute-values.md +359 -0
  58. package/reference/htmx/hx-encoding.md +111 -0
  59. package/reference/htmx/hx-params.md +204 -0
  60. package/reference/htmx/hx-swap.md +276 -0
  61. package/reference/htmx/hx-sync.md +251 -0
  62. package/reference/htmx/hx-target.md +314 -0
  63. package/reference/htmx/hx-trigger.md +457 -0
  64. package/reference/htmx/hx-url-update.md +239 -0
  65. package/reference/htmx/index.md +807 -0
  66. package/reference/htmx/response-headers.md +240 -0
  67. package/reference/http-model/headers.md +735 -0
  68. package/reference/http-model/index.md +49 -0
  69. package/reference/http-model/model.md +1517 -0
  70. package/reference/http-model/schema-codecs.md +522 -0
  71. package/reference/http-model/schema.md +750 -0
  72. package/reference/http-model/server-sent-event.md +341 -0
  73. package/reference/jwt.md +195 -0
  74. package/reference/maybe.md +943 -0
  75. package/reference/media-type.md +2 -2
  76. package/reference/mux.md +254 -0
  77. package/reference/mux.mdx +828 -0
  78. package/reference/openapi.md +1351 -0
  79. package/reference/projection.md +654 -0
  80. package/reference/resource-management/defer-handle.md +1 -1
  81. package/reference/resource-management/resource.md +31 -98
  82. package/reference/resource-management/scope.md +28 -220
  83. package/reference/resource-management/wire.md +5 -55
  84. package/reference/ringbuffer/MpmcDiagram.jsx +717 -0
  85. package/reference/ringbuffer/MpscDiagram.jsx +618 -0
  86. package/reference/ringbuffer/SpmcDiagram.jsx +680 -0
  87. package/reference/ringbuffer/SpscDiagram.jsx +677 -0
  88. package/reference/ringbuffer/advanced.mdx +109 -0
  89. package/reference/ringbuffer/index.mdx +145 -0
  90. package/reference/ringbuffer/mpmc.mdx +185 -0
  91. package/reference/ringbuffer/mpsc.mdx +164 -0
  92. package/reference/ringbuffer/spmc.mdx +108 -0
  93. package/reference/ringbuffer/spsc.mdx +416 -0
  94. package/reference/{allows.md → schema/allows.md} +4 -100
  95. package/reference/{binding-resolver.md → schema/binding-resolver.md} +1 -1
  96. package/reference/{binding.md → schema/binding.md} +3 -4
  97. package/reference/schema/built-in-codecs/avro.md +451 -0
  98. package/reference/schema/built-in-codecs/bson.md +510 -0
  99. package/reference/schema/built-in-codecs/csv.md +564 -0
  100. package/reference/schema/built-in-codecs/index.md +77 -0
  101. package/reference/schema/built-in-codecs/json/index.md +295 -0
  102. package/reference/schema/built-in-codecs/json/json-config.md +217 -0
  103. package/reference/{json-patch.md → schema/built-in-codecs/json/json-patch.md} +5 -5
  104. package/reference/{json-schema.md → schema/built-in-codecs/json/json-schema.md} +14 -47
  105. package/reference/schema/built-in-codecs/json/json-selection.md +322 -0
  106. package/reference/{json.md → schema/built-in-codecs/json/json.md} +32 -64
  107. package/reference/schema/built-in-codecs/messagepack.md +508 -0
  108. package/reference/schema/built-in-codecs/thrift.md +433 -0
  109. package/reference/schema/built-in-codecs/toon.md +1078 -0
  110. package/reference/{xml.md → schema/built-in-codecs/xml.md} +13 -9
  111. package/reference/schema/built-in-codecs/yaml.md +552 -0
  112. package/reference/{codec.md → schema/codec.md} +11 -11
  113. package/reference/{dynamic-optic.md → schema/dynamic-optic.md} +196 -5
  114. package/reference/{dynamic-schema.md → schema/dynamic-schema.md} +8 -8
  115. package/reference/schema/format.md +92 -0
  116. package/reference/schema/index.md +52 -0
  117. package/reference/schema/migration.md +297 -0
  118. package/reference/{modifier.md → schema/modifier.md} +58 -7
  119. package/reference/{optics.md → schema/optics.md} +2 -2
  120. package/reference/{patch.md → schema/patch.md} +1 -1
  121. package/{path-interpolator.md → reference/schema/path-interpolator.md} +167 -72
  122. package/reference/schema/reflect-transformer.md +140 -0
  123. package/reference/{schema-evolution → schema/schema-evolution}/as.md +8 -8
  124. package/reference/{schema-evolution → schema/schema-evolution}/index.md +2 -2
  125. package/reference/{schema-evolution → schema/schema-evolution}/into.md +8 -8
  126. package/reference/{schema-expr.md → schema/schema-expr.md} +110 -175
  127. package/reference/schema/schema-search.md +263 -0
  128. package/reference/{schema.md → schema/schema.md} +22 -2
  129. package/reference/{structural-types.md → schema/structural-types.md} +1 -1
  130. package/reference/{type-class-derivation.md → schema/type-class-derivation.md} +63 -1
  131. package/reference/smithy.md +1032 -0
  132. package/reference/sql/db-codec-deriver.md +71 -0
  133. package/reference/sql/db-codec.md +687 -0
  134. package/reference/sql/db-con.md +271 -0
  135. package/reference/sql/db-connection.md +153 -0
  136. package/reference/sql/db-param-writer.md +77 -0
  137. package/reference/sql/db-param.md +66 -0
  138. package/reference/sql/db-result-reader.md +148 -0
  139. package/reference/sql/db-tx.md +114 -0
  140. package/reference/sql/db-value.md +41 -0
  141. package/reference/sql/ddl.md +85 -0
  142. package/reference/sql/frag.md +288 -0
  143. package/reference/sql/index.md +341 -0
  144. package/reference/sql/repo.md +600 -0
  145. package/reference/sql/sql-dialect.md +73 -0
  146. package/reference/sql/sql-logger.md +62 -0
  147. package/reference/sql/sql-name-mapper.md +70 -0
  148. package/reference/sql/table-metadata.md +134 -0
  149. package/reference/sql/table.md +448 -0
  150. package/reference/sql/transactor-zio.md +399 -0
  151. package/reference/sql/transactor.md +363 -0
  152. package/reference/sql-zio.md +112 -0
  153. package/reference/streams/core/index.md +32 -0
  154. package/reference/streams/core/pipeline.md +854 -0
  155. package/reference/streams/core/sink.md +1404 -0
  156. package/reference/streams/core/stream.md +3236 -0
  157. package/reference/streams/execution-and-compatibility/async-execution.md +822 -0
  158. package/reference/streams/execution-and-compatibility/index.md +35 -0
  159. package/reference/streams/execution-and-compatibility/platform-differences.md +297 -0
  160. package/reference/streams/execution-and-compatibility/scala-2-compatibility.md +88 -0
  161. package/reference/streams/execution-and-compatibility/zero-boxing.md +393 -0
  162. package/reference/streams/index.md +726 -0
  163. package/reference/streams/primitives/index.md +30 -0
  164. package/reference/streams/primitives/reader.md +1992 -0
  165. package/reference/streams/primitives/writer.md +1201 -0
  166. package/reference/telemetry/common/any-value.md +90 -0
  167. package/reference/telemetry/common/attribute-key.md +87 -0
  168. package/reference/telemetry/common/attributes.md +118 -0
  169. package/reference/telemetry/common/index.md +39 -0
  170. package/reference/telemetry/common/instrumentation-scope.md +24 -0
  171. package/reference/telemetry/common/resource.md +34 -0
  172. package/reference/telemetry/index.md +311 -0
  173. package/reference/telemetry/logging/index.md +197 -0
  174. package/reference/telemetry/logging/log-enrichment.md +72 -0
  175. package/reference/telemetry/logging/log-formatter.md +100 -0
  176. package/reference/telemetry/logging/log-record-processor.md +56 -0
  177. package/reference/telemetry/logging/log-record.md +44 -0
  178. package/reference/telemetry/logging/log-writer.md +64 -0
  179. package/reference/telemetry/logging/logger-provider.md +142 -0
  180. package/reference/telemetry/logging/logger.md +83 -0
  181. package/reference/telemetry/logging/severity.md +62 -0
  182. package/reference/telemetry/metrics/index.md +150 -0
  183. package/reference/telemetry/metrics/instruments.md +183 -0
  184. package/reference/telemetry/metrics/labeled-instruments.md +74 -0
  185. package/reference/telemetry/metrics/meter-provider.md +76 -0
  186. package/reference/telemetry/metrics/meter.md +98 -0
  187. package/reference/telemetry/metrics/metric-data.md +57 -0
  188. package/reference/telemetry/otel/custom-exporter.md +216 -0
  189. package/reference/telemetry/otel/index.md +212 -0
  190. package/reference/telemetry/tracing/index.md +155 -0
  191. package/reference/telemetry/tracing/sampler.md +89 -0
  192. package/reference/telemetry/tracing/span-builder.md +57 -0
  193. package/reference/telemetry/tracing/span-context.md +39 -0
  194. package/reference/telemetry/tracing/span-data.md +32 -0
  195. package/reference/telemetry/tracing/span-kind.md +55 -0
  196. package/reference/telemetry/tracing/span-processor.md +53 -0
  197. package/reference/telemetry/tracing/span-status.md +47 -0
  198. package/reference/telemetry/tracing/span.md +117 -0
  199. package/reference/telemetry/tracing/tracer-provider.md +91 -0
  200. package/reference/telemetry/tracing/tracer.md +52 -0
  201. package/reference/typeid.md +5 -83
  202. package/sidebars.js +376 -43
  203. package/undocumented-report.md +528 -270
  204. package/reference/formats.md +0 -694
  205. package/reference/http-model.md +0 -1716
  206. package/reference/streams.md +0 -989
  207. package/ringbuffer.md +0 -249
  208. /package/reference/{json-differ.md → schema/built-in-codecs/json/json-differ.md} +0 -0
  209. /package/reference/{dynamic-value.md → schema/dynamic-value.md} +0 -0
  210. /package/reference/{lazy.md → schema/lazy.md} +0 -0
  211. /package/reference/{reflect.md → schema/reflect.md} +0 -0
  212. /package/reference/{registers.md → schema/registers.md} +0 -0
  213. /package/reference/{schema-error.md → schema/schema-error.md} +0 -0
  214. /package/reference/{syntax.md → schema/syntax.md} +0 -0
  215. /package/reference/{validation.md → schema/validation.md} +0 -0
@@ -584,29 +584,13 @@ sbt "schema-examples/runMain comptime.AllowsCsvExample"
584
584
  ```
585
585
 
586
586
  ```scala title="schema-examples/src/main/scala/comptime/AllowsCsvExample.scala"
587
- /*
588
- * Copyright 2024-2026 John A. De Goes and the ZIO Contributors
589
- *
590
- * Licensed under the Apache License, Version 2.0 (the "License");
591
- * you may not use this file except in compliance with the License.
592
- * You may obtain a copy of the License at
593
- *
594
- * http://www.apache.org/licenses/LICENSE-2.0
595
- *
596
- * Unless required by applicable law or agreed to in writing, software
597
- * distributed under the License is distributed on an "AS IS" BASIS,
598
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
599
- * See the License for the specific language governing permissions and
600
- * limitations under the License.
601
- */
602
-
603
587
  package comptime
604
588
 
605
589
  import zio.blocks.schema._
606
590
  import zio.blocks.schema.comptime.Allows
607
591
  import Allows.{Primitive, Record, `|`}
608
592
  import Allows.{Optional => AOptional}
609
- import util.ShowExpr.show
593
+ import zio.sbt.ExprEval.show
610
594
 
611
595
  // ---------------------------------------------------------------------------
612
596
  // CSV serializer example using Allows[A, S] compile-time shape constraints
@@ -708,29 +692,13 @@ sbt "schema-examples/runMain comptime.AllowsEventBusExample"
708
692
  ```
709
693
 
710
694
  ```scala title="schema-examples/src/main/scala/comptime/AllowsEventBusExample.scala"
711
- /*
712
- * Copyright 2024-2026 John A. De Goes and the ZIO Contributors
713
- *
714
- * Licensed under the Apache License, Version 2.0 (the "License");
715
- * you may not use this file except in compliance with the License.
716
- * You may obtain a copy of the License at
717
- *
718
- * http://www.apache.org/licenses/LICENSE-2.0
719
- *
720
- * Unless required by applicable law or agreed to in writing, software
721
- * distributed under the License is distributed on an "AS IS" BASIS,
722
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
723
- * See the License for the specific language governing permissions and
724
- * limitations under the License.
725
- */
726
-
727
695
  package comptime
728
696
 
729
697
  import zio.blocks.schema._
730
698
  import zio.blocks.schema.comptime.Allows
731
699
  import Allows.{Primitive, Record, Sequence, `|`}
732
700
  import Allows.{Optional => AOptional}
733
- import util.ShowExpr.show
701
+ import zio.sbt.ExprEval.show
734
702
 
735
703
  // ---------------------------------------------------------------------------
736
704
  // Event bus / message broker example using Allows[A, S]
@@ -830,29 +798,13 @@ sbt "schema-examples/runMain comptime.AllowsGraphQLTreeExample"
830
798
  ```
831
799
 
832
800
  ```scala title="schema-examples/src/main/scala/comptime/AllowsGraphQLTreeExample.scala"
833
- /*
834
- * Copyright 2024-2026 John A. De Goes and the ZIO Contributors
835
- *
836
- * Licensed under the Apache License, Version 2.0 (the "License");
837
- * you may not use this file except in compliance with the License.
838
- * You may obtain a copy of the License at
839
- *
840
- * http://www.apache.org/licenses/LICENSE-2.0
841
- *
842
- * Unless required by applicable law or agreed to in writing, software
843
- * distributed under the License is distributed on an "AS IS" BASIS,
844
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
845
- * See the License for the specific language governing permissions and
846
- * limitations under the License.
847
- */
848
-
849
801
  package comptime
850
802
 
851
803
  import zio.blocks.schema._
852
804
  import zio.blocks.schema.comptime.Allows
853
805
  import Allows.{Primitive, Record, Sequence, `|`}
854
806
  import Allows.{Optional => AOptional, Self => ASelf}
855
- import util.ShowExpr.show
807
+ import zio.sbt.ExprEval.show
856
808
 
857
809
  // ---------------------------------------------------------------------------
858
810
  // GraphQL / tree structure example using Self for recursive grammars
@@ -970,28 +922,12 @@ sbt "schema-examples/runMain comptime.AllowsSealedTraitExample"
970
922
  ```
971
923
 
972
924
  ```scala title="schema-examples/src/main/scala/comptime/AllowsSealedTraitExample.scala"
973
- /*
974
- * Copyright 2024-2026 John A. De Goes and the ZIO Contributors
975
- *
976
- * Licensed under the Apache License, Version 2.0 (the "License");
977
- * you may not use this file except in compliance with the License.
978
- * You may obtain a copy of the License at
979
- *
980
- * http://www.apache.org/licenses/LICENSE-2.0
981
- *
982
- * Unless required by applicable law or agreed to in writing, software
983
- * distributed under the License is distributed on an "AS IS" BASIS,
984
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
985
- * See the License for the specific language governing permissions and
986
- * limitations under the License.
987
- */
988
-
989
925
  package comptime
990
926
 
991
927
  import zio.blocks.schema._
992
928
  import zio.blocks.schema.comptime.Allows
993
929
  import Allows.{Primitive, Record}
994
- import util.ShowExpr.show
930
+ import zio.sbt.ExprEval.show
995
931
 
996
932
  // ---------------------------------------------------------------------------
997
933
  // Sealed trait auto-unwrap example
@@ -1081,22 +1017,6 @@ object AllowsSealedTraitExample extends App {
1081
1017
  Demonstrates how Allows constraints are verified at compile time — the code below shows valid examples that compile successfully, and includes comments showing which patterns would be rejected:
1082
1018
 
1083
1019
  ```scala title="schema-examples/src/main/scala/comptime/RdbmsExample.scala"
1084
- /*
1085
- * Copyright 2024-2026 John A. De Goes and the ZIO Contributors
1086
- *
1087
- * Licensed under the Apache License, Version 2.0 (the "License");
1088
- * you may not use this file except in compliance with the License.
1089
- * You may obtain a copy of the License at
1090
- *
1091
- * http://www.apache.org/licenses/LICENSE-2.0
1092
- *
1093
- * Unless required by applicable law or agreed to in writing, software
1094
- * distributed under the License is distributed on an "AS IS" BASIS,
1095
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1096
- * See the License for the specific language governing permissions and
1097
- * limitations under the License.
1098
- */
1099
-
1100
1020
  package comptime
1101
1021
 
1102
1022
  import zio.blocks.schema._
@@ -1290,22 +1210,6 @@ object RdbmsDemo {
1290
1210
  Demonstrates how Allows enforces recursive schema constraints at compile time:
1291
1211
 
1292
1212
  ```scala title="schema-examples/src/main/scala/comptime/DocumentStoreExample.scala"
1293
- /*
1294
- * Copyright 2024-2026 John A. De Goes and the ZIO Contributors
1295
- *
1296
- * Licensed under the Apache License, Version 2.0 (the "License");
1297
- * you may not use this file except in compliance with the License.
1298
- * You may obtain a copy of the License at
1299
- *
1300
- * http://www.apache.org/licenses/LICENSE-2.0
1301
- *
1302
- * Unless required by applicable law or agreed to in writing, software
1303
- * distributed under the License is distributed on an "AS IS" BASIS,
1304
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1305
- * See the License for the specific language governing permissions and
1306
- * limitations under the License.
1307
- */
1308
-
1309
1213
  package comptime
1310
1214
 
1311
1215
  import zio.blocks.schema._
@@ -466,4 +466,4 @@ val rebound: Schema[Address] = Schema[Address].toDynamicSchema.rebind[Address](r
466
466
  If `DynamicSchema#rebind` cannot find a binding for any type present in the unbound schema tree, it throws at runtime. Make sure the resolver covers every concrete type—records, variants, wrappers, primitives, and collections—that appears in the schema.
467
467
  :::
468
468
 
469
- See [Binding](./binding.md) for details on each binding kind, and [Schema](./schema.md) for the overall structure of the schema system.
469
+ See [Binding](binding.md) for details on each binding kind, and [Schema](schema.md) for the overall structure of the schema system.
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  id: binding
3
- title: "The Binding Data Type"
4
- sidebar_label: Binding
3
+ title: "Binding"
5
4
  ---
6
5
 
7
6
  `Binding` is a sealed trait in ZIO Blocks that provides the operational machinery for constructing and deconstructing values of schema-described types. While `Reflect` describes the **structure** of data types, `Binding` provides the **behavior** needed to work with those types at runtime.
@@ -337,9 +336,9 @@ Used when the schema of the data is not known at compile time, such as JSON payl
337
336
  When `F[_, _] = NoBinding` in `Reflect[F[_, _], A]` the `Reflect` structure contains only pure data (no functions) and becomes fully serializable. This enables:
338
337
 
339
338
  1. **Schema serialization**: Convert schemas to JSON Schema or other formats, making them portable
340
- 2. **Schema rebinding**: Deserialize a schema and rebind it using a `TypeRegistry`, so it becomes type-safe and operational again
339
+ 2. **Schema rebinding**: Deserialize a schema and rebind it using a `BindingResolver`, so it becomes type-safe and operational again
341
340
 
342
- We will cover schema serialization and rebinding in more detail in the `Reflect` data type documentation page. For the full API of the binding lookup mechanism used during rebinding, see [BindingResolver](./binding-resolver.md).
341
+ [ReflectTransformer](./reflect-transformer.md) covers schema serialization and rebinding in full detail — the transformer that strips bindings, the one that reattaches them, and how each is exposed as `Schema#toDynamicSchema`/`DynamicSchema#rebind`. For the full API of the binding lookup mechanism used during rebinding, see [BindingResolver](binding-resolver.md).
343
342
 
344
343
  ## Summary
345
344
 
@@ -0,0 +1,451 @@
1
+ ---
2
+ id: avro
3
+ title: "Avro Codec Module"
4
+ ---
5
+
6
+ `zio-blocks-schema-avro` is a **schema-driven Avro codec module** for serializing and deserializing Scala types to and from Avro binary format. It provides comprehensive encoding and decoding with support for 27 primitive types, records, variants, sequences, maps, and recursive types. Core types: `AvroCodec`, `AvroCodecDeriver`, `AvroFormat`.
7
+
8
+ The module integrates with Apache Avro to provide native binary serialization with automatic schema generation and support for recursive data structures with cycle detection.
9
+
10
+ ## Motivation
11
+
12
+ Avro is a powerful serialization format prevalent in distributed systems, messaging platforms, and data pipelines. Manually writing Avro encoders and decoders is error-prone and repetitive, especially for complex types with records, nested structures, and recursive definitions. `zio-blocks-schema-avro` eliminates this friction by deriving codec instances directly from your Scala types using ZIO Schema. You describe your data shape once, and the module handles:
13
+ - Full Avro type support (records, unions, arrays, maps, nested structures)
14
+ - Automatic Avro schema generation from Scala types
15
+ - Configurable sum type handling (union fields with discriminators)
16
+ - Precise error reporting with location traces showing the path to errors
17
+ - Recursive type support with automatic cycle detection
18
+ - Multiple encoding paths: ByteBuffer, byte arrays, and streams
19
+ - Multiple decoding paths: ByteBuffer, byte arrays, and streams
20
+ - JVM support (not available for Scala.js)
21
+
22
+ Rather than writing custom encoders or relying on string-based Avro schema configuration, you work with strongly-typed schemas that the compiler validates.
23
+
24
+ ## Installation
25
+
26
+ Add the module to your `build.sbt` (JVM-only, not available for Scala.js):
27
+
28
+ ```sbt
29
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-avro" % "0.0.55"
30
+ ```
31
+
32
+ Supported Scala versions: 2.13.x and 3.x
33
+
34
+ ## Introduction
35
+
36
+ The module provides a complete pipeline for Avro codec derivation and usage:
37
+
38
+ 1. **Define your type** — Any Scala type with a `Schema` instance
39
+ 2. **Derive a codec** — Use `Schema.derive(AvroFormat)` to obtain an `AvroCodec[A]`
40
+ 3. **Encode or decode** — Call `codec.encode(value)` or `codec.decode(bytes)`
41
+ 4. **Handle errors** — Catch `SchemaError` with location traces showing where the error occurred
42
+
43
+ The derivation process is automatic for all supported types (all 27 primitives, records, variants, sequences, maps). The module automatically generates Avro schemas and handles encoding/decoding without manual configuration.
44
+
45
+ ## How They Work Together
46
+
47
+ The Avro codec pipeline flows through these layers:
48
+
49
+ ```
50
+ 1. User defines Schema[A] for their type
51
+ ↓
52
+ 2. Schema[A].derive(AvroFormat) creates AvroCodec[A]
53
+ ↓
54
+ 3. AvroCodecDeriver derives Encoder and Decoder implementations
55
+ - For primitives: type-specific Avro encoders/decoders
56
+ - For records: field-by-field composition with Avro record schema
57
+ - For variants: union type encoding with discriminator support
58
+ - For sequences: array encoding/decoding
59
+ - For maps: map encoding/decoding
60
+ ↓
61
+ 4. AvroCodec provides multiple encoding paths
62
+ - encode(value) → Array[Byte]
63
+ - encode(value, output: OutputStream) → Unit
64
+ - encode(value, buffer: ByteBuffer) → Unit
65
+ ↓
66
+ 5. AvroCodec provides multiple decoding paths
67
+ - decode(bytes: Array[Byte]) → Either[SchemaError, A]
68
+ - decode(input: InputStream) → Either[SchemaError, A]
69
+ - decode(buffer: ByteBuffer) → Either[SchemaError, A]
70
+ ↓
71
+ 6. AvroCodec.avroSchema exposes generated Avro schema
72
+ Useful for compatibility checks and schema documentation
73
+ ↓
74
+ 7. Errors include location traces
75
+ Shows path (.field[index].nested) to error location
76
+ ```
77
+
78
+ **Typical workflow:**
79
+
80
+ A user type flows through the derivation and encoding pipeline as follows:
81
+
82
+ ```
83
+ User type (e.g., case class Person)
84
+ ↓
85
+ Schema.derived (automatic via macro)
86
+ ↓
87
+ Schema[Person].derive(AvroFormat) → AvroCodec[Person]
88
+ ↓
89
+ Use codec.encode(person) to serialize → Array[Byte]
90
+ Use codec.decode(bytes) to deserialize → Either[SchemaError, Person]
91
+ ↓
92
+ Handle SchemaError with location trace on failure
93
+ ```
94
+
95
+ ### Type Relationships
96
+
97
+ - **`AvroCodec[A]`** — Main public API; contains encoder and decoder for bidirectional serialization
98
+ - **`AvroCodecDeriver`** — Configuration and derivation system; generates codecs from Schema
99
+ - **`AvroFormat`** — Integration with ZIO Schema format system; enables `Schema[A].derive(AvroFormat)`
100
+ - **`SchemaError`** — Error type with location traces; renders as paths like `.field[0].nested`
101
+
102
+ ## Common Patterns
103
+
104
+ This section shows practical patterns for working with Avro codecs in real-world scenarios.
105
+
106
+ ### Pattern 1: Derive and Encode a Simple Record
107
+
108
+ To derive and use an Avro codec for a record type:
109
+
110
+ ```scala
111
+ import zio.blocks.schema._
112
+ import zio.blocks.schema.avro._
113
+
114
+ case class Person(name: String, age: Int, email: String)
115
+
116
+ object Person {
117
+ implicit val schema: Schema[Person] = Schema.derived
118
+ }
119
+
120
+ val codec = Person.schema.derive(AvroFormat)
121
+ val person = Person("Alice", 30, "alice@example.com")
122
+ val bytes = codec.encode(person)
123
+ ```
124
+
125
+ ### Pattern 2: Decode Avro with Error Handling
126
+
127
+ When decoding Avro data, errors include location traces showing where the problem occurred.
128
+
129
+ To decode bytes and handle errors with location information:
130
+
131
+ ```scala
132
+ import zio.blocks.schema._
133
+ import zio.blocks.schema.avro._
134
+
135
+ case class Employee(id: Int, name: String, salary: Double)
136
+
137
+ object Employee {
138
+ implicit val schema: Schema[Employee] = Schema.derived
139
+ }
140
+
141
+ val codec = Employee.schema.derive(AvroFormat)
142
+ val bytes = Array[Byte](1, 4, 6) // truncated data
143
+
144
+ val result = codec.decode(bytes)
145
+
146
+ result match {
147
+ case Right(employee) => println(s"Decoded: $employee")
148
+ case Left(error) =>
149
+ println(s"Error at ${error.getMessage}")
150
+ }
151
+ ```
152
+
153
+ ### Pattern 3: Inspect the Generated Avro Schema
154
+
155
+ Access the derived Avro schema to verify compatibility or document the serialization format.
156
+
157
+ To inspect the Avro schema for a type:
158
+
159
+ ```scala
160
+ import zio.blocks.schema._
161
+ import zio.blocks.schema.avro._
162
+
163
+ case class Product(name: String, price: Double, inStock: Boolean)
164
+
165
+ object Product {
166
+ implicit val schema: Schema[Product] = Schema.derived
167
+ }
168
+
169
+ val codec = Product.schema.derive(AvroFormat)
170
+ val avroSchema = codec.avroSchema
171
+ println(avroSchema.toString)
172
+ ```
173
+
174
+ ### Pattern 4: Handle Recursive Types
175
+
176
+ Recursive types (types that reference themselves) are fully supported with automatic cycle detection.
177
+
178
+ To define and encode a recursive data structure:
179
+
180
+ ```scala
181
+ import zio.blocks.schema._
182
+ import zio.blocks.schema.avro._
183
+
184
+ sealed trait Tree
185
+ case class Leaf(value: Int) extends Tree
186
+ case class Branch(left: Tree, right: Tree) extends Tree
187
+
188
+ object Tree {
189
+ implicit val schema: Schema[Tree] = Schema.derived
190
+ }
191
+
192
+ val codec = Tree.schema.derive(AvroFormat)
193
+ val tree: Tree = Branch(Leaf(1), Branch(Leaf(2), Leaf(3)))
194
+ val bytes = codec.encode(tree)
195
+ ```
196
+
197
+ ---
198
+
199
+ ## AvroCodec[A]
200
+
201
+ Main codec type for encoding and decoding values to and from Avro binary format. Contains encoder and decoder for bidirectional serialization.
202
+
203
+ ### Overview
204
+
205
+ `AvroCodec[A]` holds both an encoder and decoder, providing a complete solution for serializing and deserializing values in Avro binary format. The codec is derived automatically from a `Schema[A]` using `AvroFormat`.
206
+
207
+ ### Accessing the Avro Schema
208
+
209
+ To get the derived Avro schema from a codec:
210
+
211
+ ```scala
212
+ import zio.blocks.schema._
213
+ import zio.blocks.schema.avro._
214
+
215
+ case class User(id: Int, name: String)
216
+
217
+ object User {
218
+ implicit val schema: Schema[User] = Schema.derived
219
+ }
220
+
221
+ val codec = User.schema.derive(AvroFormat)
222
+ val avroSchema = codec.avroSchema
223
+ ```
224
+
225
+ ### Encoding Values to Byte Array
226
+
227
+ Use the codec to convert values to byte arrays:
228
+
229
+ ```scala
230
+ import zio.blocks.schema._
231
+ import zio.blocks.schema.avro._
232
+
233
+ case class Product(name: String, price: Double)
234
+
235
+ object Product {
236
+ implicit val schema: Schema[Product] = Schema.derived
237
+ }
238
+
239
+ val codec = Product.schema.derive(AvroFormat)
240
+ val product = Product("Widget", 9.99)
241
+ val bytes = codec.encode(product)
242
+ ```
243
+
244
+ ### Encoding Values to OutputStream
245
+
246
+ Write encoded values directly to an output stream:
247
+
248
+ ```scala
249
+ import zio.blocks.schema._
250
+ import zio.blocks.schema.avro._
251
+ import java.io.ByteArrayOutputStream
252
+
253
+ case class Item(name: String, quantity: Int)
254
+
255
+ object Item {
256
+ implicit val schema: Schema[Item] = Schema.derived
257
+ }
258
+
259
+ val codec = Item.schema.derive(AvroFormat)
260
+ val item = Item("Gadget", 42)
261
+ val output = new ByteArrayOutputStream()
262
+ codec.encode(item, output)
263
+ val bytes = output.toByteArray
264
+ ```
265
+
266
+ ### Decoding Values from Byte Array
267
+
268
+ Use the codec to convert byte arrays back to values:
269
+
270
+ ```scala
271
+ import zio.blocks.schema._
272
+ import zio.blocks.schema.avro._
273
+
274
+ case class Record(id: Int, value: String)
275
+
276
+ object Record {
277
+ implicit val schema: Schema[Record] = Schema.derived
278
+ }
279
+
280
+ val codec = Record.schema.derive(AvroFormat)
281
+ // In real usage, bytes would come from a previous encoding or external source
282
+ val record = Record(123, "test")
283
+ val buffer = java.nio.ByteBuffer.allocate(256)
284
+ codec.encode(record, buffer)
285
+ buffer.flip()
286
+ val bytes = new Array[Byte](buffer.remaining())
287
+ buffer.get(bytes)
288
+
289
+ val result: Either[zio.blocks.schema.SchemaError, Record] = codec.decode(bytes)
290
+ ```
291
+
292
+ ### Decoding Values from InputStream
293
+
294
+ Read and decode values from an input stream:
295
+
296
+ ```scala
297
+ import zio.blocks.schema._
298
+ import zio.blocks.schema.avro._
299
+ import java.io.ByteArrayInputStream
300
+
301
+ case class Data(timestamp: Long, payload: String)
302
+
303
+ object Data {
304
+ implicit val schema: Schema[Data] = Schema.derived
305
+ }
306
+
307
+ val codec = Data.schema.derive(AvroFormat)
308
+ // Use encoded bytes from a previous encoding
309
+ val data = Data(System.currentTimeMillis(), "example payload")
310
+ val buffer = java.nio.ByteBuffer.allocate(256)
311
+ codec.encode(data, buffer)
312
+ buffer.flip()
313
+ val bytes = new Array[Byte](buffer.remaining())
314
+ buffer.get(bytes)
315
+ val input = new ByteArrayInputStream(bytes)
316
+ val result = codec.decode(input)
317
+ ```
318
+
319
+ ---
320
+
321
+ ## AvroCodecDeriver
322
+
323
+ Configuration and derivation system for creating `AvroCodec[A]` instances from `Schema[A]`.
324
+
325
+ ### Overview
326
+
327
+ `AvroCodecDeriver` implements the schema-driven derivation of Avro codecs. It automatically handles 27 primitive types and complex types (records, variants, sequences, maps), generating appropriate Avro schemas and encoder/decoder implementations.
328
+
329
+ ### How Derivation Works
330
+
331
+ To create a codec from a schema:
332
+
333
+ ```scala
334
+ import zio.blocks.schema._
335
+ import zio.blocks.schema.avro._
336
+
337
+ case class Person(name: String, age: Int)
338
+
339
+ object Person {
340
+ implicit val schema: Schema[Person] = Schema.derived
341
+ }
342
+
343
+ val codec = Person.schema.derive(AvroFormat)
344
+ // codec: AvroCodec[Person] = zio.blocks.schema.avro.AvroCodecDeriver$$anon$4@601650a
345
+ ```
346
+
347
+ ### Primitive Type Support
348
+
349
+ All 27 ZIO Schema primitives are supported:
350
+ - Numeric: `Byte`, `Short`, `Int`, `Long`, `Float`, `Double`, `BigInt`, `BigDecimal`
351
+ - Logical: `Boolean`, `Char`, `String`
352
+ - Temporal: `Instant`, `LocalDate`, `LocalDateTime`, `LocalTime`, `Duration`, `Period`, `Year`, `YearMonth`, `MonthDay`, `Month`, `DayOfWeek`, `ZonedDateTime`, `OffsetDateTime`, `OffsetTime`, `ZoneId`, `ZoneOffset`
353
+ - Special: `UUID`, `Currency`, `Unit`
354
+
355
+ ### Record Type Support
356
+
357
+ Case classes (records) are fully supported. Each field becomes a named field in the Avro record schema:
358
+
359
+ ```scala
360
+ import zio.blocks.schema._
361
+ import zio.blocks.schema.avro._
362
+
363
+ case class Address(street: String, city: String, zip: String)
364
+
365
+ object Address {
366
+ implicit val schema: Schema[Address] = Schema.derived
367
+ }
368
+
369
+ val codec = Address.schema.derive(AvroFormat)
370
+ ```
371
+
372
+ ### Variant Type Support
373
+
374
+ Sealed traits and sum types are encoded as Avro union types:
375
+
376
+ ```scala
377
+ import zio.blocks.schema._
378
+ import zio.blocks.schema.avro._
379
+
380
+ sealed trait Status
381
+ case class Active(since: String) extends Status
382
+ case class Inactive(reason: String) extends Status
383
+
384
+ object Status {
385
+ implicit val schema: Schema[Status] = Schema.derived
386
+ }
387
+
388
+ val codec = Status.schema.derive(AvroFormat)
389
+ ```
390
+
391
+ ---
392
+
393
+ ## AvroFormat
394
+
395
+ Integration point with ZIO Schema's format system. Provides `BinaryFormat[AvroCodec]` to enable `Schema[A].derive(AvroFormat)` for any supported type.
396
+
397
+ ### Using AvroFormat
398
+
399
+ To derive an Avro codec using the standard format:
400
+
401
+ ```scala
402
+ import zio.blocks.schema._
403
+ import zio.blocks.schema.avro._
404
+
405
+ case class Sensor(id: Long, temperature: Double, humidity: Float)
406
+
407
+ object Sensor {
408
+ implicit val schema: Schema[Sensor] = Schema.derived
409
+ }
410
+
411
+ val codec = Sensor.schema.derive(AvroFormat)
412
+ ```
413
+
414
+ `AvroFormat` is a singleton object extending `BinaryFormat[AvroCodec]` with the MIME type `"application/avro"` and the `AvroCodecDeriver` as its derivation strategy.
415
+
416
+ ---
417
+
418
+ ## Error Handling
419
+
420
+ Avro decoding errors include location traces showing the path through nested structures where the error occurred.
421
+
422
+ ### Understanding Error Traces
423
+
424
+ Errors render as paths like `.field[0].nested.value` showing exactly where decoding failed:
425
+
426
+ ```scala
427
+ import zio.blocks.schema._
428
+ import zio.blocks.schema.avro._
429
+
430
+ case class Contact(emails: Seq[String])
431
+
432
+ object Contact {
433
+ implicit val schema: Schema[Contact] = Schema.derived
434
+ }
435
+
436
+ val codec = Contact.schema.derive(AvroFormat)
437
+ // Example invalid Avro bytes that will fail decoding
438
+ val invalidBytes: Array[Byte] = Array(0xFF.toByte, 0xFF.toByte)
439
+
440
+ val result = codec.decode(invalidBytes)
441
+
442
+ result match {
443
+ case Right(contact) => println(s"Success: $contact")
444
+ case Left(error) =>
445
+ println(s"Error: ${error.getMessage}")
446
+ }
447
+ ```
448
+
449
+ ### Zero-Overhead Error Handling
450
+
451
+ Errors use zero-overhead exceptions (no stack traces) for efficient error reporting in stream processing scenarios where errors are expected and handled inline.