@zio.dev/zio-blocks 0.0.33 → 0.0.51

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 (150) hide show
  1. package/guides/compile-time-resource-safety-with-scope.md +16 -17
  2. package/guides/getting-started-with-mux.md +1507 -0
  3. package/guides/query-dsl-extending.md +161 -102
  4. package/guides/query-dsl-fluent-builder.md +217 -157
  5. package/guides/query-dsl-reified-optics.md +12 -10
  6. package/guides/query-dsl-sql.md +246 -165
  7. package/guides/telemetry-guide.md +1069 -0
  8. package/guides/zio-schema-migration.md +29 -22
  9. package/index.md +292 -50
  10. package/package.json +1 -1
  11. package/plans/config-follow-up-prs.md +188 -0
  12. package/plans/config-pr-assessment-roadmap.md +310 -0
  13. package/reference/MuxDataFlow.jsx +250 -0
  14. package/reference/async.md +651 -0
  15. package/reference/chunk.md +3533 -308
  16. package/reference/codegen/case-class.md +436 -0
  17. package/reference/codegen/emitter-config.md +383 -0
  18. package/reference/codegen/examples.md +664 -0
  19. package/reference/codegen/field.md +316 -0
  20. package/reference/codegen/index.md +317 -0
  21. package/reference/codegen/scala-emitter.md +392 -0
  22. package/reference/codegen/scala-file.md +276 -0
  23. package/reference/codegen/sealed-trait.md +408 -0
  24. package/reference/codegen/type-definition.md +340 -0
  25. package/reference/codegen/type-ref.md +201 -0
  26. package/reference/combinators.md +347 -117
  27. package/reference/config.md +158 -0
  28. package/reference/context.md +4 -4
  29. package/reference/datastar.md +346 -0
  30. package/reference/docs.md +1461 -345
  31. package/reference/endpoint/auth-type.md +146 -0
  32. package/reference/endpoint/endpoint.md +297 -0
  33. package/reference/endpoint/http-codec.md +249 -0
  34. package/reference/endpoint/index.md +825 -0
  35. package/reference/endpoint/path-codec.md +237 -0
  36. package/reference/endpoint/route-pattern.md +196 -0
  37. package/reference/endpoint/route-tree.md +111 -0
  38. package/reference/endpoint/segment-codec.md +212 -0
  39. package/reference/html.md +1120 -0
  40. package/reference/htmx/attribute-values.md +359 -0
  41. package/reference/htmx/hx-encoding.md +111 -0
  42. package/reference/htmx/hx-params.md +204 -0
  43. package/reference/htmx/hx-swap.md +276 -0
  44. package/reference/htmx/hx-sync.md +251 -0
  45. package/reference/htmx/hx-target.md +314 -0
  46. package/reference/htmx/hx-trigger.md +457 -0
  47. package/reference/htmx/hx-url-update.md +239 -0
  48. package/reference/htmx/index.md +855 -0
  49. package/reference/http-model/index.md +47 -0
  50. package/reference/http-model/model.md +1481 -0
  51. package/reference/http-model/schema.md +747 -0
  52. package/reference/maybe.md +826 -0
  53. package/reference/media-type.md +2 -2
  54. package/reference/mux.mdx +823 -0
  55. package/reference/openapi.md +1351 -0
  56. package/reference/resource-management/defer-handle.md +1 -1
  57. package/reference/resource-management/resource.md +31 -2
  58. package/reference/resource-management/scope.md +28 -12
  59. package/reference/resource-management/wire.md +3 -7
  60. package/reference/ringbuffer/MpmcDiagram.jsx +717 -0
  61. package/reference/ringbuffer/MpscDiagram.jsx +618 -0
  62. package/reference/ringbuffer/SpmcDiagram.jsx +680 -0
  63. package/reference/ringbuffer/SpscDiagram.jsx +677 -0
  64. package/reference/ringbuffer/advanced.mdx +109 -0
  65. package/reference/ringbuffer/index.mdx +145 -0
  66. package/reference/ringbuffer/mpmc.mdx +151 -0
  67. package/reference/ringbuffer/mpsc.mdx +132 -0
  68. package/reference/ringbuffer/spmc.mdx +108 -0
  69. package/reference/ringbuffer/spsc.mdx +344 -0
  70. package/reference/{allows.md → schema/allows.md} +4 -4
  71. package/reference/{binding-resolver.md → schema/binding-resolver.md} +1 -1
  72. package/reference/{binding.md → schema/binding.md} +2 -3
  73. package/reference/schema/built-in-codecs/avro.md +451 -0
  74. package/reference/schema/built-in-codecs/bson.md +480 -0
  75. package/reference/schema/built-in-codecs/csv.md +564 -0
  76. package/reference/schema/built-in-codecs/index.md +77 -0
  77. package/reference/schema/built-in-codecs/json/index.md +295 -0
  78. package/reference/schema/built-in-codecs/json/json-config.md +217 -0
  79. package/reference/{json-patch.md → schema/built-in-codecs/json/json-patch.md} +5 -5
  80. package/reference/{json-schema.md → schema/built-in-codecs/json/json-schema.md} +14 -47
  81. package/reference/schema/built-in-codecs/json/json-selection.md +322 -0
  82. package/reference/{json.md → schema/built-in-codecs/json/json.md} +32 -64
  83. package/reference/schema/built-in-codecs/messagepack.md +508 -0
  84. package/reference/schema/built-in-codecs/thrift.md +433 -0
  85. package/reference/schema/built-in-codecs/toon.md +1078 -0
  86. package/reference/{xml.md → schema/built-in-codecs/xml.md} +13 -9
  87. package/reference/schema/built-in-codecs/yaml.md +552 -0
  88. package/reference/{codec.md → schema/codec.md} +10 -10
  89. package/reference/{dynamic-optic.md → schema/dynamic-optic.md} +151 -5
  90. package/reference/{dynamic-schema.md → schema/dynamic-schema.md} +8 -8
  91. package/reference/schema/format.md +92 -0
  92. package/reference/schema/index.md +50 -0
  93. package/reference/schema/migration.md +297 -0
  94. package/reference/{modifier.md → schema/modifier.md} +58 -7
  95. package/reference/{optics.md → schema/optics.md} +2 -2
  96. package/reference/{patch.md → schema/patch.md} +1 -1
  97. package/{path-interpolator.md → reference/schema/path-interpolator.md} +165 -72
  98. package/reference/{schema-evolution → schema/schema-evolution}/as.md +8 -8
  99. package/reference/{schema-evolution → schema/schema-evolution}/index.md +2 -2
  100. package/reference/{schema-evolution → schema/schema-evolution}/into.md +8 -8
  101. package/reference/{schema-expr.md → schema/schema-expr.md} +110 -175
  102. package/reference/{schema.md → schema/schema.md} +12 -0
  103. package/reference/{structural-types.md → schema/structural-types.md} +1 -1
  104. package/reference/{type-class-derivation.md → schema/type-class-derivation.md} +63 -1
  105. package/reference/smithy.md +533 -0
  106. package/reference/sql/db-codec-deriver.md +71 -0
  107. package/reference/sql/db-codec.md +687 -0
  108. package/reference/sql/db-con.md +271 -0
  109. package/reference/sql/db-connection.md +153 -0
  110. package/reference/sql/db-param-writer.md +77 -0
  111. package/reference/sql/db-param.md +66 -0
  112. package/reference/sql/db-result-reader.md +146 -0
  113. package/reference/sql/db-tx.md +82 -0
  114. package/reference/sql/db-value.md +41 -0
  115. package/reference/sql/ddl.md +85 -0
  116. package/reference/sql/frag.md +254 -0
  117. package/reference/sql/index.md +341 -0
  118. package/reference/sql/repo.md +600 -0
  119. package/reference/sql/sql-dialect.md +73 -0
  120. package/reference/sql/sql-logger.md +62 -0
  121. package/reference/sql/sql-name-mapper.md +70 -0
  122. package/reference/sql/table-metadata.md +134 -0
  123. package/reference/sql/table.md +448 -0
  124. package/reference/sql/transactor-zio.md +399 -0
  125. package/reference/sql/transactor.md +353 -0
  126. package/reference/sql-zio.md +112 -0
  127. package/reference/streams/concurrent-operators.md +106 -0
  128. package/reference/streams/index.md +653 -0
  129. package/reference/streams/pipeline.md +718 -0
  130. package/reference/streams/reader.md +1284 -0
  131. package/reference/streams/scala-2-compatibility.md +55 -0
  132. package/reference/streams/sink.md +1426 -0
  133. package/reference/streams/stream.md +2526 -0
  134. package/reference/streams/writer.md +1045 -0
  135. package/reference/streams/zero-boxing.md +275 -0
  136. package/reference/telemetry.md +693 -0
  137. package/reference/typeid.md +5 -19
  138. package/sidebars.js +238 -43
  139. package/reference/formats.md +0 -694
  140. package/reference/http-model.md +0 -1716
  141. package/reference/streams.md +0 -989
  142. package/ringbuffer.md +0 -249
  143. /package/reference/{json-differ.md → schema/built-in-codecs/json/json-differ.md} +0 -0
  144. /package/reference/{dynamic-value.md → schema/dynamic-value.md} +0 -0
  145. /package/reference/{lazy.md → schema/lazy.md} +0 -0
  146. /package/reference/{reflect.md → schema/reflect.md} +0 -0
  147. /package/reference/{registers.md → schema/registers.md} +0 -0
  148. /package/reference/{schema-error.md → schema/schema-error.md} +0 -0
  149. /package/reference/{syntax.md → schema/syntax.md} +0 -0
  150. /package/reference/{validation.md → schema/validation.md} +0 -0
@@ -26,7 +26,7 @@ val result = data.get(path).one
26
26
  ```
27
27
 
28
28
  :::tip
29
- For a practical example of extracting column names from `DynamicOptic` paths to generate SQL, see the [Query DSL Part 2: SQL Generation](../guides/query-dsl-sql.md) guide.
29
+ For a practical example of extracting column names from `DynamicOptic` paths to generate SQL, see the [Query DSL Part 2: SQL Generation](../../guides/query-dsl-sql.md) guide.
30
30
  :::
31
31
 
32
32
  ## Motivation
@@ -57,7 +57,7 @@ The relationship between typed and dynamic optics:
57
57
  └──────────────────┘ └──────────────────┘
58
58
  ```
59
59
 
60
- The `Optic[S, A]` and `DynamicOptic` types serve complementary roles in ZIO Blocks' optics system. `Optic[S, A]` provides compile-time type safety through macros or manual construction, operates on typed Scala values, and can be converted to a `DynamicOptic` via the `optic.toDynamic` method. In contrast, `DynamicOptic` performs runtime type checking and is constructed through a builder API or [path interpolator](../path-interpolator.md), operating directly on [DynamicValue](./dynamic-value.md), [Schema](./schema.md), and [Reflect](./reflect.md) representations.
60
+ The `Optic[S, A]` and `DynamicOptic` types serve complementary roles in ZIO Blocks' optics system. `Optic[S, A]` provides compile-time type safety through macros or manual construction, operates on typed Scala values, and can be converted to a `DynamicOptic` via the `optic.toDynamic` method. In contrast, `DynamicOptic` performs runtime type checking and is constructed through a builder API or [path interpolator](./path-interpolator.md), operating directly on [DynamicValue](./dynamic-value.md), [Schema](./schema.md), and [Reflect](./reflect.md) representations.
61
61
 
62
62
  ## Design & Structure
63
63
 
@@ -157,7 +157,7 @@ Note: `.atKey` and `.atKeys` require an implicit `Schema[K]` to convert the type
157
157
 
158
158
  ### Path Interpolator
159
159
 
160
- The [`p"..."` path interpolator](../path-interpolator.md) provides a concise compile-time syntax for building
160
+ The [`p"..."` path interpolator](./path-interpolator.md) provides a concise compile-time syntax for building
161
161
  `DynamicOptic` values:
162
162
 
163
163
  ```scala
@@ -181,7 +181,7 @@ val success = p".result<Success>.value"
181
181
  val complex = p""".groups[*].members[0].contacts{"email"}"""
182
182
  ```
183
183
 
184
- See [Path Interpolator](../path-interpolator.md) for the full syntax reference.
184
+ See [Path Interpolator](./path-interpolator.md) for the full syntax reference.
185
185
 
186
186
  ### From Typed Optics
187
187
 
@@ -360,7 +360,7 @@ expected Email, but got Push
360
360
 
361
361
  `DynamicOptic` provides two string formats for different contexts:
362
362
 
363
- - **`toString`** — Compact path syntax matching the [`p"..."` interpolator](../path-interpolator.md) format
363
+ - **`toString`** — Compact path syntax matching the [`p"..."` interpolator](./path-interpolator.md) format
364
364
  - **`toScalaString`** — Scala method call syntax used in error messages
365
365
 
366
366
  | Node | `toString` | `toScalaString` |
@@ -396,6 +396,152 @@ val serialized: DynamicValue = opticSchema.toDynamicValue(path)
396
396
  ```
397
397
 
398
398
 
399
+ ## Search Optics
400
+
401
+ A **Search optic** recursively traverses a data structure to find **all occurrences** matching a type or schema. It produces a `Traversal[S, A]` that collects matches in depth-first, left-to-right order.
402
+
403
+ ### Motivation
404
+
405
+ Search optics address scenarios where you need to:
406
+
407
+ - **Find all values of a specific type** across deeply nested structures (e.g., all `String` fields in a nested record)
408
+ - **Extract all data matching a structural pattern** (e.g., all records with `{ name: string, age: int }` schema)
409
+ - **Transform all matching occurrences** in untyped or partially-typed data
410
+ - **Query data without knowing the exact path** — the search discovers all paths automatically
411
+
412
+ ### Typed API: `.searchFor[T]`
413
+
414
+ Use the `.searchFor[T]` extension method on a `CompanionOptics` to search for all values of type `T`:
415
+
416
+ ```scala
417
+ import zio.blocks.schema._
418
+
419
+ case class Person(name: String, age: Int)
420
+ object Person {
421
+ implicit val schema: Schema[Person] = Schema.derived
422
+ }
423
+
424
+ case class Address(city: String)
425
+ object Address {
426
+ implicit val schema: Schema[Address] = Schema.derived
427
+ }
428
+
429
+ case class Company(name: String, employees: List[Person], hq: Address)
430
+ object Company extends CompanionOptics[Company] {
431
+ implicit val schema: Schema[Company] = Schema.derived
432
+ }
433
+
434
+ // Find all Person instances within a Company
435
+ val personSearch: Traversal[Company, Person] = Company.optic(_.searchFor[Person])
436
+
437
+ val company = Company(
438
+ "Acme",
439
+ List(Person("Alice", 30), Person("Bob", 25)),
440
+ Address("NYC")
441
+ )
442
+
443
+ // Modify all persons (increment their age)
444
+ val updated: Company = personSearch.modify(company, p => p.copy(age = p.age + 1))
445
+ // Company("Acme", List(Person("Alice", 31), Person("Bob", 26)), Address("NYC"))
446
+ ```
447
+
448
+ ### Dynamic API: Path Strings with `#` Prefix
449
+
450
+ Use the `#` prefix in path strings to specify type or schema patterns:
451
+
452
+ ```scala
453
+ import zio.blocks.schema._
454
+
455
+ val data = DynamicValue.Record(
456
+ "company" -> DynamicValue.Record(
457
+ "name" -> DynamicValue.string("Acme"),
458
+ "employees" -> DynamicValue.Sequence(
459
+ DynamicValue.Record("name" -> DynamicValue.string("Alice")),
460
+ DynamicValue.Record("name" -> DynamicValue.string("Bob"))
461
+ )
462
+ )
463
+ )
464
+
465
+ // Find all strings in the data
466
+ val allStrings = data.get(p"#string").toChunk
467
+ // Chunk(
468
+ // DynamicValue.string("Acme"),
469
+ // DynamicValue.string("Alice"),
470
+ // DynamicValue.string("Bob")
471
+ // )
472
+
473
+ // Find all records matching a schema
474
+ val recordsWithName = data.get(p"#record { name: string }").toChunk
475
+
476
+ // Modify all matching values
477
+ val modified = data.modify(p"#string")(dv =>
478
+ dv match {
479
+ case DynamicValue.Primitive(PrimitiveValue.String(s)) =>
480
+ DynamicValue.string(s.toUpperCase)
481
+ case other => other
482
+ }
483
+ )
484
+ ```
485
+
486
+ ### Supported Patterns
487
+
488
+ Search optics support both **type-based** and **schema-based** patterns:
489
+
490
+ | Pattern | Matches | Example |
491
+ |--------------------------------|----------------------------------------|---------------------------|
492
+ | `#Nominal` (type name) | Values of that type name | `#Person` |
493
+ | `#int`, `#string`, `#boolean` | Specific primitive types (case-insensitive) | `#int`, `#string`, `#boolean` |
494
+ | `#record { ... }` | Records with matching fields | `#record { name: string }` |
495
+ | `#variant { ... }` | Variant cases with matching content | `#variant { Error: string }` |
496
+ | `#list(...)` | Lists/sequences with element type | `#list(string)` |
497
+ | `#map(...)` | Maps with key and value types | `#map(string, int)` |
498
+ | `#option(...)` | Optional values with inner type | `#option(int)` |
499
+
500
+ ### Traversal Order
501
+
502
+ Results are collected in **depth-first, left-to-right order**:
503
+
504
+ ```scala
505
+ import zio.blocks.schema._
506
+
507
+ val nested = DynamicValue.Record(
508
+ "a" -> DynamicValue.int(1),
509
+ "b" -> DynamicValue.Record(
510
+ "c" -> DynamicValue.int(2),
511
+ "d" -> DynamicValue.int(3)
512
+ ),
513
+ "e" -> DynamicValue.int(4)
514
+ )
515
+
516
+ // Depth-first, left-to-right: 1, 2, 3, 4
517
+ val allInts = nested.get(p"#int").toChunk
518
+ // Chunk(1, 2, 3, 4)
519
+ ```
520
+
521
+ ### Known Limitation: Nominal Matching in Untyped Contexts
522
+
523
+ `Nominal` pattern matching (e.g., `#Person`) returns `false` when applied to `DynamicValue` or `Json` because these untyped structures carry no type identity. To match nominally-typed data, use one of these approaches:
524
+
525
+ - **Use the typed API**: `optic(_.searchFor[Person])`
526
+ - **Or use structural patterns**: `p"#record { name: string, age: int }"`
527
+
528
+ Here's how the two approaches differ in practice:
529
+
530
+ ```scala
531
+ import zio.blocks.schema._
532
+
533
+ val dynamicData: DynamicValue = ???
534
+
535
+ // This won't match — no type identity available
536
+ val nominalMatch = dynamicData.get(p"#Person").toChunk
537
+ // Chunk()
538
+
539
+ // This works — structural matching
540
+ val structuralMatch = dynamicData.get(p"#record { name: string, age: int }").toChunk
541
+ // Chunk(...matching records...)
542
+ ```
543
+
399
544
  ## See Also
400
545
 
401
546
  - [DynamicSchema](./dynamic-schema.md) — use `DynamicSchema#get` with a `DynamicOptic` to navigate schema trees and inspect nested type structures.
547
+ - [Optics](./optics.md) — reference page for typed `Optic[S, A]` and reflective optics concepts.
@@ -41,7 +41,7 @@ DynamicSchema ←── reconstructed from storage
41
41
  Schema[OrderPlaced] ←── operational again, can encode and decode
42
42
  ```
43
43
 
44
- This pattern enables schema registries: the Checkout Service registers its event schema on startup; the Fulfillment Service fetches it and rebinds it against its own type definitions, guaranteeing it uses the exact schema that was in effect when the event was encoded. See [BindingResolver](./binding-resolver.md) for the complete rebinding API.
44
+ This pattern enables schema registries: the Checkout Service registers its event schema on startup; the Fulfillment Service fetches it and rebinds it against its own type definitions, guaranteeing it uses the exact schema that was in effect when the event was encoded. See [BindingResolver](binding-resolver.md) for the complete rebinding API.
45
45
 
46
46
  ## Creating a DynamicSchema
47
47
 
@@ -83,7 +83,7 @@ dynamic
83
83
  // value = Primitive(
84
84
  // primitiveType = String(None),
85
85
  // typeId = String,
86
- // primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@5ca5d848,
86
+ // primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@480c1083,
87
87
  // doc = Doc(blocks = IndexedSeq(), metadata = Map()),
88
88
  // modifiers = List(),
89
89
  // storedDefaultValue = None,
@@ -97,7 +97,7 @@ dynamic
97
97
  // value = Primitive(
98
98
  // primitiveType = Int(None),
99
99
  // typeId = Int,
100
- // primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@5ca5d848,
100
+ // primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@480c1083,
101
101
  // doc = Doc(blocks = IndexedSeq(), metadata = Map()),
102
102
  // modifiers = List(),
103
103
  // storedDefaultValue = None,
@@ -115,7 +115,7 @@ dynamic
115
115
  // value = Primitive(
116
116
  // primitiveType = String(None),
117
117
  // typeId = String,
118
- // primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@5ca5d848,
118
+ // primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@480c1083,
119
119
  // doc = Doc(blocks = IndexedSeq(), metadata = Map()),
120
120
  // modifiers = List(),
121
121
  // storedDefaultValue = None,
@@ -232,7 +232,7 @@ dynSchema.check(valid)
232
232
  dynSchema.check(missing)
233
233
  // res8: Option[SchemaError] = Some(
234
234
  // SchemaError(
235
- // List(MissingField(source = DynamicOptic(IndexedSeq()), fieldName = "y"))
235
+ // List(MissingField(source = DynamicOptic(ArraySeq()), fieldName = "y"))
236
236
  // )
237
237
  // )
238
238
  dynSchema.check(wrongType)
@@ -240,7 +240,7 @@ dynSchema.check(wrongType)
240
240
  // SchemaError(
241
241
  // List(
242
242
  // ExpectationMismatch(
243
- // source = DynamicOptic(IndexedSeq(Field("y"))),
243
+ // source = DynamicOptic(ArraySeq(Field("y"))),
244
244
  // expectation = "Expected Int, got String"
245
245
  // )
246
246
  // )
@@ -339,7 +339,7 @@ rebound.fromDynamicValue(encoded)
339
339
  If `DynamicSchema#rebind` cannot find a binding for any type in the unbound schema tree, it throws a `RebindException` at runtime. Ensure the resolver covers every concrete type — records, variants, wrappers, primitives, and standard collections — that appears in the schema. `BindingResolver.defaults` covers all standard primitives, `java.time` types, `List`, `Map`, `Option`, and other standard collections.
340
340
  :::
341
341
 
342
- See [BindingResolver](./binding-resolver.md) for the full resolver API including `BindingResolver.reflection` for automatic binding via reflection.
342
+ See [BindingResolver](binding-resolver.md) for the full resolver API including `BindingResolver.reflection` for automatic binding via reflection.
343
343
 
344
344
  ## Structural Navigation
345
345
 
@@ -546,7 +546,7 @@ gatewaySchema.fromDynamicValue(incoming)
546
546
 
547
547
  ### With `BindingResolver`
548
548
 
549
- The primary consumer of `DynamicSchema` in a type-safe context is `DynamicSchema#rebind`, which requires a `BindingResolver` to reattach runtime bindings. See [BindingResolver](./binding-resolver.md) for the complete rebinding API, including `BindingResolver.reflection` for automatic binding discovery.
549
+ The primary consumer of `DynamicSchema` in a type-safe context is `DynamicSchema#rebind`, which requires a `BindingResolver` to reattach runtime bindings. See [BindingResolver](binding-resolver.md) for the complete rebinding API, including `BindingResolver.reflection` for automatic binding discovery.
550
550
 
551
551
  ### With `DynamicOptic`
552
552
 
@@ -0,0 +1,92 @@
1
+ ---
2
+ id: format
3
+ title: "Format Type"
4
+ sidebar_label: "Format"
5
+ ---
6
+
7
+ A `Format` is an abstraction that bundles together everything needed to serialize and deserialize data in a specific format (JSON, Avro, MessagePack, etc.). It unifies metadata related to serialization formats, such as MIME type and codec deriver, in a single place.
8
+
9
+ ## Overview
10
+
11
+ The `Format` trait defines the structure for any serialization format. Each format specifies the types for decoding input, encoding output, the codec typeclass, MIME type, and the deriver used to generate codecs from schemas:
12
+
13
+ ```scala
14
+ import zio.blocks.schema.codec.Codec
15
+ import zio.blocks.schema.derive.Deriver
16
+
17
+ trait Format {
18
+ type DecodeInput
19
+ type EncodeOutput
20
+ type TypeClass[A] <: Codec[DecodeInput, EncodeOutput, A]
21
+ def mimeType: String
22
+ def deriver: Deriver[TypeClass]
23
+ }
24
+ ```
25
+
26
+ This design allows for a consistent API across different formats when deriving codecs from schemas. Having MIME type information helps with runtime content negotiation and format routing, for example in HTTP servers or message queues.
27
+
28
+ ## Using a Format
29
+
30
+ You can easily call [`Schema[A].derive(format)`](./type-class-derivation.md#using-the-deriver-to-derive-type-class-instances) for any format that implements the `Format` trait to obtain a codec that can encode and decode values of type `A` according to that format's rules:
31
+
32
+ ```scala
33
+ import zio.blocks.schema._
34
+ import zio.blocks.schema.toon._
35
+
36
+ case class Person(name: String, age: Int)
37
+
38
+ object Person {
39
+ implicit val schema: Schema[Person] = Schema.derived
40
+ }
41
+
42
+ val codec = Schema[Person].derive(ToonFormat)
43
+ val bytes: Array[Byte] = codec.encode(Person("Alice", 30))
44
+ val decoded: Either[SchemaError, Person] = codec.decode(bytes)
45
+ ```
46
+
47
+ ## Format Categories
48
+
49
+ Formats are categorized into `BinaryFormat` and `TextFormat`, which specify the types of input and output for encoding and decoding:
50
+
51
+ ```scala
52
+ sealed trait Format
53
+ abstract class BinaryFormat[A] extends Format { }
54
+ abstract class TextFormat[A] extends Format { }
55
+ ```
56
+
57
+ **BinaryFormat** — Encodes and decodes data as bytes. Used for compact, efficient serialization (e.g., Avro, Thrift, MessagePack).
58
+
59
+ **TextFormat** — Encodes and decodes data as text strings. Used for human-readable formats (e.g., JSON, YAML, TOON).
60
+
61
+ ### Example: JsonFormat
62
+
63
+ The `JsonFormat` is a `BinaryFormat` that represents JSON serialization, where both the input for decoding and output for encoding are `ByteBuffer`, the MIME type is `application/json`, and the deriver for generating codecs from schemas is `JsonCodecDeriver`:
64
+
65
+ ```scala
66
+ import zio.blocks.schema.json._
67
+
68
+ object MyJsonFormat extends zio.blocks.schema.codec.BinaryFormat("application/json", JsonCodecDeriver)
69
+ ```
70
+
71
+ ## Defining a Custom Format
72
+
73
+ To add a new serialization format, define a `BinaryFormat` (or `TextFormat`) singleton with a custom `Deriver`:
74
+
75
+ ```scala
76
+ import zio.blocks.schema.codec.BinaryCodec
77
+
78
+ // 1. Define your codec base class
79
+ abstract class MyCodec[A] extends BinaryCodec[A]
80
+
81
+ // 2. Implement a Deriver[MyCodec] (see Type-class Derivation docs)
82
+ // val myDeriver: Deriver[MyCodec] = ...
83
+
84
+ // 3. Create the format singleton
85
+ // object MyFormat extends BinaryFormat[MyCodec]("application/x-myformat", myDeriver)
86
+ ```
87
+
88
+ For details on implementing a `Deriver`, see [Type-class Derivation](./type-class-derivation.md).
89
+
90
+ ## Available Formats
91
+
92
+ ZIO Blocks provides multiple built-in formats. See the [Built-in Formats and Codecs](./built-in-codecs/index.md) section for a complete list of supported serialization formats and their respective codec modules.
@@ -0,0 +1,50 @@
1
+ ---
2
+ id: index
3
+ title: "ZIO Blocks Schema"
4
+ sidebar_label: "Schema"
5
+ ---
6
+
7
+ ## Introduction
8
+
9
+ ZIO Blocks Schema is the core type system and serialization framework that provides reified structural metadata for Scala data types. It enables type-safe schema definition, validation, optics-based data access, multi-format serialization, and runtime introspection — all derived from a single `Schema` definition.
10
+
11
+ **Core Type System:**
12
+ - [`Schema`](./schema.md) — Primary data type containing reified structure of a Scala data type
13
+ - [`Reflect`](./reflect.md) — Foundational data structure containing reified structural information
14
+ - [`Binding`](./binding.md) — Operational machinery for constructing and deconstructing values
15
+ - [`Registers`](./registers.md) — Register-based design for zero-allocation construction and deconstruction
16
+ - [`Structural Types`](./structural-types.md) — Duck typing with ZIO Blocks schemas
17
+
18
+ **Dynamic & Runtime Data:**
19
+ - [`DynamicValue`](./dynamic-value.md) — Schema-less, dynamically-typed representation of any structured value
20
+ - [`DynamicSchema`](./dynamic-schema.md) — Type-erased schema container for serialization and transport
21
+ - [`Lazy`](./lazy.md) — Deferred computation with monadic abstraction, memoization, and stack-safe evaluation
22
+
23
+ **Navigation & Transformation:**
24
+ - [`Optics`](./optics.md) — Reflective optics for type-safe, composable access to nested data structures
25
+ - [`DynamicOptic`](./dynamic-optic.md) — Runtime path through nested data structures
26
+ - [`Path Interpolator`](./path-interpolator.md) — Compile-time string interpolator `p"..."` for constructing `DynamicOptic` instances
27
+ - [`SchemaExpr`](./schema-expr.md) — Schema-aware expressions for evaluation and query language translation
28
+ - [`Patch`](./patch.md) — Type-safe, serializable transformations of data structures
29
+ - [`Modifier`](./modifier.md) — Mechanism to attach metadata and configuration to schema elements
30
+
31
+ **Serialization:**
32
+ - [`Codec`](./codec.md) — Base abstraction for encoding and decoding values between formats
33
+ - [`Format`](./format.md) — Unified abstraction bundling serialization and deserialization for a specific format
34
+ - [`Type Class Derivation`](./type-class-derivation.md) — Automatic generation of type class instances from schemas
35
+ - [`Syntax`](./syntax.md) — Extension methods for fluent JSON encoding/decoding and patching
36
+
37
+ **Formats:**
38
+ - [`JSON Codec`](./built-in-codecs/json/) — Complete JSON support: ADT for JSON values, fluent navigation, encoding/decoding, diffs, patches, and JSON Schema 2020-12 validation
39
+ - [`Xml`](./built-in-codecs/xml.md) — Type-safe, immutable representation of XML document structures
40
+
41
+ **Validation & Errors:**
42
+ - [`Validation`](./validation.md) — Declarative constraints on primitive values
43
+ - [`SchemaError`](./schema-error.md) — Structured error type for schema operations
44
+ - [`Allows`](./allows.md) — Compile-time capability token proving a type satisfies a structural grammar
45
+
46
+ ## Overview
47
+
48
+ The ZIO Blocks Schema module revolves around the `Schema` and `Reflect` types, which capture the complete structural description of Scala data types at runtime. From a single schema definition, you get automatic derivation of codecs (`Codec`, `Formats`), type-safe data access (`Optics`, `DynamicOptic`), structural validation (`Validation`, `SchemaError`), patching (`Patch`, `JsonPatch`), and serialization to multiple formats (`Json`, `Xml`, `JSON Schema`).
49
+
50
+ The type system is powered by a register-based architecture (`Registers`) that eliminates boxing overhead, and supports both compile-time (`Allows`) and runtime (`DynamicValue`, `DynamicSchema`) type manipulation. The `Deriver` system (`Type Class Derivation`) enables automatic generation of any type class instance from schema metadata.