@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
@@ -0,0 +1,199 @@
1
+ ---
2
+ id: segment-codec
3
+ title: "SegmentCodec"
4
+ ---
5
+
6
+ `SegmentCodec[A]` describes a single URL path segment. It supports basic typed segment kinds — `SegmentCodec.bool`, `SegmentCodec.int`, `SegmentCodec.long`, `SegmentCodec.string`, `SegmentCodec.uuid`, and `SegmentCodec.literal` — as well as intra-segment composition via `~`, which combines multiple typed parts within a single path segment (for example, `v42` as a literal prefix followed by an integer). Ambiguous adjacencies (`string ~ string`, numeric ~ numeric in any `Int`/`Long` order, anything involving `Trailing`) are rejected at runtime with `IllegalArgumentException`. Combine representation first, then transform: `transform` / `transformOrFail` lift a segment into a `PathCodec`, ending intra-segment composition. The core type-level shape is:
7
+
8
+ ```scala
9
+ sealed trait SegmentCodec[A]
10
+ ```
11
+
12
+ (The trait also includes methods for `~` composition, `transform` lifting, documentation, examples, formatting, and rendering.)
13
+
14
+ ## Motivation
15
+
16
+ Standard routing libraries treat path segments as plain strings, deferring all parsing to handler code. `SegmentCodec` encodes the type of each segment statically, so the compiler knows whether a segment produces an `Int`, a `UUID`, or a custom domain type. This enables:
17
+
18
+ - **Type-safe path building**: `PathCodec.int("id")` produces a `PathCodec[Int]`, not `PathCodec[String]`.
19
+ - **Bidirectional conversion**: every `SegmentCodec` can both decode a string into `A` and format an `A` back to a string.
20
+ - **Fail-fast combination validation**: the `~` operator rejects ambiguous adjacencies (`string ~ string`, numeric ~ numeric) at composition time, so bad splits surface immediately instead of misrouting.
21
+
22
+ ## Segment Kinds
23
+
24
+ Each segment kind maps to a specific URL token type. Literal segments match a fixed string; the others capture and parse dynamic values.
25
+
26
+ ### Literal segments
27
+
28
+ A `Literal` segment matches exactly one fixed string value. Use `SegmentCodec.literal` with a compile-time string constant:
29
+
30
+ ```scala
31
+ import zio.blocks.endpoint._
32
+ import zio.blocks.endpoint.RoutePattern._
33
+
34
+ val usersLit: SegmentCodec.Literal = SegmentCodec.literal("users")
35
+ ```
36
+
37
+ `SegmentCodec.literal` is a macro: it validates that the value is a non-empty, URL-safe, single-segment string at compile time and rejects `""`, `"foo/bar"`, or strings requiring percent-encoding.
38
+
39
+ ### Typed dynamic segments
40
+
41
+ Standard typed segment constructors each accept a name string for documentation and OpenAPI path parameter labels:
42
+
43
+ ```scala
44
+ import zio.blocks.endpoint._
45
+ import zio.blocks.endpoint.RoutePattern._
46
+
47
+ val boolSeg: SegmentCodec[Boolean] = SegmentCodec.bool("flag")
48
+ val intSeg: SegmentCodec[Int] = SegmentCodec.int("id")
49
+ val longSeg: SegmentCodec[Long] = SegmentCodec.long("id")
50
+ val stringSeg: SegmentCodec[String] = SegmentCodec.string("slug")
51
+ val uuidSeg: SegmentCodec[java.util.UUID] = SegmentCodec.uuid("id")
52
+ ```
53
+
54
+ If a route should capture a segment for matching or formatting but the handler intentionally does not consume the variable, the leaf dynamic segment codecs expose `.unused`:
55
+
56
+ ```scala
57
+ import zio.blocks.endpoint.SegmentCodec
58
+
59
+ val requiredId = SegmentCodec.int("id")
60
+ val ignoredId = SegmentCodec.int("id").unused
61
+ ```
62
+
63
+ `.unused` keeps decoding, formatting, rendering, and composition identical. The only difference is at the type level: downstream tooling (handler macros, static checks) sees the variable as intentionally unused and does not require the handler to bind it.
64
+
65
+ The ordering of match priority in the routing trie follows the kind: `Literal` matches first, then `Int`, `Long`, `UUID`, `Bool`, `String`, `Combined`, and `Trailing` last.
66
+
67
+ ### Trailing segment
68
+
69
+ `SegmentCodec.Trailing` captures all remaining path segments as a `zio.http.Path`. Use it for wildcard routes; it always has the lowest priority in the trie:
70
+
71
+ ```scala
72
+ import zio.blocks.endpoint._
73
+ import zio.blocks.endpoint.RoutePattern._
74
+ import zio.http.Path
75
+
76
+ val rest: SegmentCodec[Path] = SegmentCodec.Trailing
77
+ ```
78
+
79
+ ## Intra-Segment Composition with `~`
80
+
81
+ The `~` operator combines two `SegmentCodec` values into a `Combined` codec that matches a single path segment containing both parts consecutively. This is useful for version strings like `v42` or prefixed identifiers like `usr-550e8400`:
82
+
83
+ ```scala
84
+ import zio.blocks.endpoint._
85
+ import zio.blocks.endpoint.RoutePattern._
86
+
87
+ val versionSeg: SegmentCodec[Int] =
88
+ SegmentCodec.literal("v") ~ SegmentCodec.int("major")
89
+ ```
90
+
91
+ The type is automatically flattened (eliminating `Unit` from the literal), so the resulting codec decodes `"v42"` into `42` and formats `42` back to `"v42"`.
92
+
93
+ ### Runtime adjacency validation
94
+
95
+ The `~` operator checks the physical adjacency at composition time. Two categories of combination are always rejected with `IllegalArgumentException`:
96
+
97
+ - **Two string segments**: `SegmentCodec.string("a") ~ SegmentCodec.string("b")` — both are unbounded greedy matchers; the parser cannot know where one ends and the other begins.
98
+ - **Two numeric segments**: `SegmentCodec.int("a") ~ SegmentCodec.int("b")` — numeric segments are also ambiguously bounded (any `Int`/`Long` order, including through a flattened combined tail).
99
+
100
+ Anything involving `Trailing` is likewise rejected. Combinations that are safe compose normally:
101
+
102
+ ```scala
103
+ import zio.blocks.endpoint._
104
+ import zio.blocks.endpoint.RoutePattern._
105
+
106
+ // Safe: literal delimiter separates two dynamic segments
107
+ val versionMajorMinor =
108
+ SegmentCodec.literal("v") ~ SegmentCodec.int("major") ~
109
+ SegmentCodec.literal("x") ~ SegmentCodec.int("minor")
110
+
111
+ // Safe: UUID in the middle, bounded by strings on both sides
112
+ val prefixedUuid =
113
+ SegmentCodec.string("prefix") ~ SegmentCodec.uuid("id") ~ SegmentCodec.string("suffix")
114
+ ```
115
+
116
+ Attempting an ambiguous combination like `string ~ string` throws `IllegalArgumentException` at composition time, not a silent misroute.
117
+
118
+ ## Type Transformations
119
+
120
+ Combine representation first, then transform: `transform` / `transformOrFail` map the decoded segment value into a domain type and lift the segment into a `PathCodec`, ending intra-segment composition (a transformed codec no longer offers `~`; compose with `/` instead).
121
+
122
+ ### `SegmentCodec#transform`
123
+
124
+ To map the decoded segment value to a different type, use `SegmentCodec#transform`. Both the decode and encode functions must be total:
125
+
126
+ ```scala
127
+ import zio.blocks.endpoint._
128
+ import zio.blocks.endpoint.RoutePattern._
129
+
130
+ final case class UserId(value: java.util.UUID)
131
+
132
+ val userIdCodec: PathCodec[UserId] =
133
+ SegmentCodec.uuid("id").transform(UserId(_), _.value)
134
+ ```
135
+
136
+ ### `SegmentCodec#transformOrFail`
137
+
138
+ When decoding can fail, use `SegmentCodec#transformOrFail`. A `Left` result causes segment matching to fail for that candidate:
139
+
140
+ ```scala
141
+ import zio.blocks.endpoint._
142
+ import zio.blocks.endpoint.RoutePattern._
143
+
144
+ final case class PositiveInt(value: Int)
145
+
146
+ val positiveIntCodec: PathCodec[PositiveInt] =
147
+ SegmentCodec.int("count").transformOrFail(
148
+ n => if (n > 0) Right(PositiveInt(n)) else Left(s"Expected positive, got $n"),
149
+ p => Right(p.value)
150
+ )
151
+ ```
152
+
153
+ ## Formatting and Rendering
154
+
155
+ These methods convert a typed value back to a string for use in URL construction and documentation output.
156
+
157
+ ### `SegmentCodec#format`
158
+
159
+ To format a typed value into a single-segment `Path`:
160
+
161
+ ```scala
162
+ import zio.blocks.endpoint._
163
+ import zio.blocks.endpoint.RoutePattern._
164
+ import zio.http.Path
165
+
166
+ val seg = SegmentCodec.int("id")
167
+ val path: Path = seg.format(42)
168
+ ```
169
+
170
+ ### `SegmentCodec#render`
171
+
172
+ To produce the human-readable representation of the segment for use in OpenAPI path parameters and documentation:
173
+
174
+ ```scala
175
+ import zio.blocks.endpoint._
176
+ import zio.blocks.endpoint.RoutePattern._
177
+
178
+ val intSeg = SegmentCodec.int("id")
179
+ val rendered: String = intSeg.render()
180
+ ```
181
+
182
+ By default, `SegmentCodec.render` produces `/{name}` for dynamic segments and `/{value}` for literal segments (including the leading slash in both cases). This leading slash is part of the segment's representation, not added by path composition. To customize the format, pass prefix and suffix arguments: `intSeg.render(":", "")` produces `/:id`. Both dynamic and literal segments always include this leading slash in their rendered form.
183
+
184
+ ## Priority Ordering
185
+
186
+ When `RouteTree` builds a routing trie, it uses `SegmentCodec.Kind` ordering to resolve ambiguous matches. Literals always win; within dynamic segments, more specific types take priority:
187
+
188
+ | Priority | Kind |
189
+ | -------- | ---------- |
190
+ | 1 | `Literal` |
191
+ | 2 | `Int` |
192
+ | 3 | `Long` |
193
+ | 4 | `UUID` |
194
+ | 5 | `Bool` |
195
+ | 6 | `String` |
196
+ | 7 | `Combined` |
197
+ | 8 | `Trailing` |
198
+
199
+ This ordering ensures that `/users/42` matches an `Int` route before a `String` route, and `/users/active` matches a `String` route because `"active"` is not a valid integer.