@zio.dev/zio-blocks 0.0.51 → 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 (164) 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 -583
  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/index.md +9 -89
  37. package/reference/endpoint/path-codec.md +12 -24
  38. package/reference/endpoint/route-pattern.md +4 -6
  39. package/reference/endpoint/segment-codec.md +19 -32
  40. package/reference/html.md +313 -9
  41. package/reference/htmx/index.md +4 -52
  42. package/reference/htmx/response-headers.md +240 -0
  43. package/reference/http-model/headers.md +735 -0
  44. package/reference/http-model/index.md +3 -1
  45. package/reference/http-model/model.md +107 -71
  46. package/reference/http-model/schema-codecs.md +522 -0
  47. package/reference/http-model/schema.md +6 -3
  48. package/reference/http-model/server-sent-event.md +341 -0
  49. package/reference/jwt.md +195 -0
  50. package/reference/maybe.md +128 -11
  51. package/reference/media-type.md +2 -2
  52. package/reference/mux.md +254 -0
  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/resource.md +2 -98
  57. package/reference/resource-management/scope.md +1 -209
  58. package/reference/resource-management/wire.md +4 -50
  59. package/reference/ringbuffer/advanced.mdx +1 -1
  60. package/reference/ringbuffer/index.mdx +3 -3
  61. package/reference/ringbuffer/mpmc.mdx +38 -4
  62. package/reference/ringbuffer/mpsc.mdx +36 -4
  63. package/reference/ringbuffer/spmc.mdx +1 -1
  64. package/reference/ringbuffer/spsc.mdx +87 -15
  65. package/reference/schema/allows.md +0 -96
  66. package/reference/schema/binding.md +2 -2
  67. package/reference/schema/built-in-codecs/avro.md +2 -2
  68. package/reference/schema/built-in-codecs/bson.md +50 -20
  69. package/reference/schema/built-in-codecs/csv.md +2 -2
  70. package/reference/schema/built-in-codecs/index.md +3 -3
  71. package/reference/schema/built-in-codecs/json/index.md +2 -2
  72. package/reference/schema/built-in-codecs/messagepack.md +3 -3
  73. package/reference/schema/built-in-codecs/thrift.md +2 -2
  74. package/reference/schema/built-in-codecs/toon.md +3 -3
  75. package/reference/schema/built-in-codecs/yaml.md +2 -2
  76. package/reference/schema/codec.md +11 -11
  77. package/reference/schema/dynamic-optic.md +48 -3
  78. package/reference/schema/dynamic-schema.md +3 -3
  79. package/reference/schema/index.md +2 -0
  80. package/reference/schema/path-interpolator.md +2 -0
  81. package/reference/schema/reflect-transformer.md +140 -0
  82. package/reference/schema/schema-evolution/as.md +4 -4
  83. package/reference/schema/schema-evolution/into.md +2 -2
  84. package/reference/schema/schema-expr.md +2 -2
  85. package/reference/schema/schema-search.md +263 -0
  86. package/reference/schema/schema.md +10 -2
  87. package/reference/schema/type-class-derivation.md +1 -1
  88. package/reference/smithy.md +502 -3
  89. package/reference/sql/db-codec-deriver.md +3 -3
  90. package/reference/sql/db-codec.md +22 -22
  91. package/reference/sql/db-con.md +4 -4
  92. package/reference/sql/db-connection.md +1 -1
  93. package/reference/sql/db-param.md +1 -1
  94. package/reference/sql/db-result-reader.md +4 -2
  95. package/reference/sql/db-tx.md +46 -14
  96. package/reference/sql/ddl.md +1 -1
  97. package/reference/sql/frag.md +44 -10
  98. package/reference/sql/index.md +7 -7
  99. package/reference/sql/repo.md +15 -15
  100. package/reference/sql/sql-dialect.md +1 -1
  101. package/reference/sql/sql-logger.md +1 -1
  102. package/reference/sql/sql-name-mapper.md +3 -3
  103. package/reference/sql/table-metadata.md +3 -3
  104. package/reference/sql/table.md +10 -10
  105. package/reference/sql/transactor-zio.md +1 -1
  106. package/reference/sql/transactor.md +21 -11
  107. package/reference/sql-zio.md +1 -1
  108. package/reference/streams/core/index.md +32 -0
  109. package/reference/streams/{pipeline.md → core/pipeline.md} +210 -74
  110. package/reference/streams/{sink.md → core/sink.md} +331 -353
  111. package/reference/streams/{stream.md → core/stream.md} +919 -209
  112. package/reference/streams/execution-and-compatibility/async-execution.md +822 -0
  113. package/reference/streams/execution-and-compatibility/index.md +35 -0
  114. package/reference/streams/execution-and-compatibility/platform-differences.md +297 -0
  115. package/reference/streams/execution-and-compatibility/scala-2-compatibility.md +88 -0
  116. package/reference/streams/execution-and-compatibility/zero-boxing.md +393 -0
  117. package/reference/streams/index.md +140 -67
  118. package/reference/streams/primitives/index.md +30 -0
  119. package/reference/streams/primitives/reader.md +1992 -0
  120. package/reference/streams/{writer.md → primitives/writer.md} +254 -98
  121. package/reference/telemetry/common/any-value.md +90 -0
  122. package/reference/telemetry/common/attribute-key.md +87 -0
  123. package/reference/telemetry/common/attributes.md +118 -0
  124. package/reference/telemetry/common/index.md +39 -0
  125. package/reference/telemetry/common/instrumentation-scope.md +24 -0
  126. package/reference/telemetry/common/resource.md +34 -0
  127. package/reference/telemetry/index.md +311 -0
  128. package/reference/telemetry/logging/index.md +197 -0
  129. package/reference/telemetry/logging/log-enrichment.md +72 -0
  130. package/reference/telemetry/logging/log-formatter.md +100 -0
  131. package/reference/telemetry/logging/log-record-processor.md +56 -0
  132. package/reference/telemetry/logging/log-record.md +44 -0
  133. package/reference/telemetry/logging/log-writer.md +64 -0
  134. package/reference/telemetry/logging/logger-provider.md +142 -0
  135. package/reference/telemetry/logging/logger.md +83 -0
  136. package/reference/telemetry/logging/severity.md +62 -0
  137. package/reference/telemetry/metrics/index.md +150 -0
  138. package/reference/telemetry/metrics/instruments.md +183 -0
  139. package/reference/telemetry/metrics/labeled-instruments.md +74 -0
  140. package/reference/telemetry/metrics/meter-provider.md +76 -0
  141. package/reference/telemetry/metrics/meter.md +98 -0
  142. package/reference/telemetry/metrics/metric-data.md +57 -0
  143. package/reference/telemetry/otel/custom-exporter.md +216 -0
  144. package/reference/telemetry/otel/index.md +212 -0
  145. package/reference/telemetry/tracing/index.md +155 -0
  146. package/reference/telemetry/tracing/sampler.md +89 -0
  147. package/reference/telemetry/tracing/span-builder.md +57 -0
  148. package/reference/telemetry/tracing/span-context.md +39 -0
  149. package/reference/telemetry/tracing/span-data.md +32 -0
  150. package/reference/telemetry/tracing/span-kind.md +55 -0
  151. package/reference/telemetry/tracing/span-processor.md +53 -0
  152. package/reference/telemetry/tracing/span-status.md +47 -0
  153. package/reference/telemetry/tracing/span.md +117 -0
  154. package/reference/telemetry/tracing/tracer-provider.md +91 -0
  155. package/reference/telemetry/tracing/tracer.md +52 -0
  156. package/reference/typeid.md +0 -64
  157. package/sidebars.js +150 -12
  158. package/undocumented-report.md +528 -270
  159. package/reference/config.md +0 -158
  160. package/reference/streams/concurrent-operators.md +0 -106
  161. package/reference/streams/reader.md +0 -1284
  162. package/reference/streams/scala-2-compatibility.md +0 -55
  163. package/reference/streams/zero-boxing.md +0 -275
  164. package/reference/telemetry.md +0 -693
@@ -0,0 +1,240 @@
1
+ ---
2
+ id: response-headers
3
+ title: Request and Response Headers
4
+ ---
5
+
6
+ `zio.http.htmx.headers` provides typed HTTP headers for the request/response side of an HTMX exchange: the headers HTMX sends with every request, and the headers a handler sets to steer the client afterward. Each header follows the same `Header` / `Header.Typed` pattern that `zio.http` applies everywhere else, so reading one from a `Request` or `Response` returns a parsed domain value instead of a raw string, and several response headers reuse the same `HxSwap`, `HxTarget`, and `HxUrlUpdate` types that back the attribute DSL, keeping the two sides of an interaction consistent.
7
+
8
+ Here are the core patterns for reading and writing HTMX headers:
9
+
10
+ ```scala
11
+ import zio.http.{Header, Headers, Request, Response, URL}
12
+ import zio.http.htmx.headers._
13
+
14
+ // Reading a request header HTMX sent
15
+ def handle(request: Request): Boolean =
16
+ request.header(HxRequest).exists(_.enabled)
17
+
18
+ // Setting response headers that steer the client afterward
19
+ val response = Response.ok.addHeaders(
20
+ Headers(HxRefresh.name -> "true", HxTriggerHeader.name -> "orderPlaced")
21
+ )
22
+ ```
23
+
24
+ ## Overview
25
+
26
+ The module splits into two directions and reuses supporting types from the attribute DSL for structured values:
27
+
28
+ | Direction | Type | Wire name | Shape |
29
+ | --------- | ------------------------ | ---------------------------- | -------------------------------------------------- |
30
+ | Request | `HxRequest` | `hx-request` | `Boolean`, always `true` on an HTMX request |
31
+ | Request | `HxBoosted` | `hx-boosted` | `Boolean`, set when the request came from `hxBoost` |
32
+ | Request | `HxHistoryRestoreRequest` | `hx-history-restore-request` | `Boolean` |
33
+ | Request | `HxCurrentUrl` | `hx-current-url` | non-empty `String` or `URL` |
34
+ | Request | `HxTargetId` | `hx-target` | non-empty `String` (target element id) |
35
+ | Request | `HxTriggerId` | `hx-trigger` | non-empty `String` (triggering element id) |
36
+ | Request | `HxTriggerName` | `hx-trigger-name` | non-empty `String` |
37
+ | Request | `HxPrompt` | `hx-prompt` | `String`, trimmed |
38
+ | Response | `HxRedirect` | `hx-redirect` | non-empty `String` or `URL` |
39
+ | Response | `HxRefresh` | `hx-refresh` | `Boolean` |
40
+ | Response | `HxPushUrl` | `hx-push-url` | `HxUrlUpdate` |
41
+ | Response | `HxReplaceUrl` | `hx-replace-url` | `HxUrlUpdate` |
42
+ | Response | `HxReswap` | `hx-reswap` | `HxSwap` |
43
+ | Response | `HxRetarget` | `hx-retarget` | `CssSelector` |
44
+ | Response | `HxReselect` | `hx-reselect` | `CssSelector` |
45
+ | Response | `HxTriggerHeader` | `hx-trigger` | `HxEventPayload` |
46
+ | Response | `HxTriggerAfterSettle` | `hx-trigger-after-settle` | `HxEventPayload` |
47
+ | Response | `HxTriggerAfterSwap` | `hx-trigger-after-swap` | `HxEventPayload` |
48
+ | Response | `HxLocation` | `hx-location` | `Json.Object`, built from path/target/swap |
49
+
50
+ `HxTriggerId` (request) and `HxTriggerHeader` (response) share the wire name `hx-trigger` but read in opposite directions—one reports which element fired the request, the other tells the client which events to dispatch after the response arrives.
51
+
52
+ ## Reading Request Headers
53
+
54
+ These headers describe the HTMX request itself: whether it came from HTMX at all, which element and value triggered it, and what the browser's current URL was. All of them parse from plain strings with no structured payload.
55
+
56
+ ### Presence Flags
57
+
58
+ `HxRequest`, `HxBoosted`, and `HxHistoryRestoreRequest` are boolean headers—present with value `"true"` or `"false"`, parsed case-insensitively. Checking whether a request came from HTMX at all is the most common read:
59
+
60
+ ```scala
61
+ import zio.http.{Headers, Request, URL}
62
+ import zio.http.htmx.headers._
63
+
64
+ val boosted = Request.get(URL.root).addHeaders(Headers(HxRequest.name -> "true", HxBoosted.name -> "true"))
65
+ ```
66
+
67
+ Reading each flag back through `Request#header` parses the stored string into the typed value:
68
+
69
+ ```scala
70
+ boosted.header(HxRequest)
71
+ // res1: Option[HxRequest] = Some(HxRequest(true))
72
+ boosted.header(HxBoosted)
73
+ // res2: Option[HxBoosted] = Some(HxBoosted(true))
74
+ ```
75
+
76
+ ### Identifiers and Text Values
77
+
78
+ `HxTargetId`, `HxTriggerId`, and `HxTriggerName` carry the id or name of the element involved in the request; `HxCurrentUrl` carries the browser's current URL. All four trim their value and reject blank input except `HxPrompt`, which passes through any trimmed string including an empty one:
79
+
80
+ ```scala
81
+ import zio.http.{Headers, Request, URL}
82
+ import zio.http.htmx.headers._
83
+
84
+ val request = Request
85
+ .get(URL.root)
86
+ .addHeaders(Headers(HxTriggerName.name -> "search", HxCurrentUrl.name -> "https://zio.dev/blocks"))
87
+ ```
88
+
89
+ Reading them back gives the trimmed values as typed headers:
90
+
91
+ ```scala
92
+ request.header(HxTriggerName)
93
+ // res3: Option[HxTriggerName] = Some(HxTriggerName("search"))
94
+ request.header(HxCurrentUrl)
95
+ // res4: Option[HxCurrentUrl] = Some(HxCurrentUrl("https://zio.dev/blocks"))
96
+ ```
97
+
98
+ `HxCurrentUrl` also accepts a `zio.http.URL` directly at construction time, encoding it to a string: `HxCurrentUrl(URL.parse("https://zio.dev/htmx").toOption.get)`.
99
+
100
+ ## Setting Response Headers
101
+
102
+ Response headers tell HTMX what to do once the response body has been swapped in—redirect, refresh, change what gets swapped or where, fire client-side events, or update the URL bar. Several reuse types already documented for the attribute DSL, so the same modifiers and constructors apply on both sides of the exchange.
103
+
104
+ ### Redirecting and Refreshing
105
+
106
+ `HxRedirect` sends the browser to a new URL with a full page load, and `HxRefresh` forces a full page reload of the current URL:
107
+
108
+ ```scala
109
+ import zio.http.{Headers, Response, URL}
110
+ import zio.http.htmx.headers._
111
+
112
+ val redirect = Response.ok.addHeaders(Headers(HxRedirect.name -> "/login", HxRefresh.name -> "true"))
113
+ ```
114
+
115
+ Reading them back through `Response#header` gives the parsed values:
116
+
117
+ ```scala
118
+ redirect.header(HxRedirect)
119
+ // res6: Option[HxRedirect] = Some(HxRedirect("/login"))
120
+ redirect.header(HxRefresh)
121
+ // res7: Option[HxRefresh] = Some(HxRefresh(true))
122
+ ```
123
+
124
+ `HxRedirect` also has a `URL` constructor—`HxRedirect(URL.parse("https://zio.dev/login").toOption.get)`—that encodes the URL before storing it.
125
+
126
+ ### Controlling the URL Bar
127
+
128
+ `HxPushUrl` and `HxReplaceUrl` decide whether the browser's URL bar updates after a swap, using the same `HxUrlUpdate` type as the `hx-push-url` attribute: `HxUrlUpdate.Enabled` or `HxUrlUpdate.Disabled` for a plain boolean, or a `String`/`Path`/`URL` to push a specific address:
129
+
130
+ ```scala
131
+ import zio.http.Path
132
+ import zio.http.htmx.HxUrlUpdate
133
+ import zio.http.htmx.headers.HxPushUrl
134
+
135
+ HxPushUrl(HxUrlUpdate.Enabled)
136
+ HxPushUrl(HxUrlUpdate(Path("/orders/42")))
137
+ ```
138
+
139
+ ### Overriding the Swap Strategy
140
+
141
+ `HxReswap` lets a response override the `hx-swap` strategy the requesting element declared, using the identical `HxSwap` DSL—including its timing and animation modifiers—documented in [HxSwap](./hx-swap.md):
142
+
143
+ ```scala
144
+ import scala.concurrent.duration._
145
+ import zio.http.htmx.HxSwap
146
+ import zio.http.htmx.headers.HxReswap
147
+
148
+ val header = HxReswap(HxSwap.InnerHTML.swap(1.second).settle(250.millis))
149
+ ```
150
+
151
+ Rendering reproduces the raw `hx-swap` syntax, and parsing that string round-trips it back to the same header:
152
+
153
+ ```scala
154
+ HxReswap.render(header)
155
+ // res10: String = "innerHTML swap:1s settle:250ms"
156
+ HxReswap.parse(HxReswap.render(header)) == Right(header)
157
+ // res11: Boolean = true
158
+ ```
159
+
160
+ ### Retargeting and Reselecting
161
+
162
+ `HxRetarget` overrides where the response swaps in, and `HxReselect` overrides which part of the response fragment the client applies—both take a `CssSelector` from `zio.blocks.html`, the same type `hxTarget` and `hxSelect` accept:
163
+
164
+ ```scala
165
+ import zio.blocks.html.CssSelector
166
+ import zio.http.htmx.headers.{HxReselect, HxRetarget}
167
+
168
+ HxRetarget(CssSelector.id("result"))
169
+ HxReselect(CssSelector.raw(".items > li"))
170
+ ```
171
+
172
+ ### Triggering Client-Side Events
173
+
174
+ `HxTriggerHeader`, `HxTriggerAfterSettle`, and `HxTriggerAfterSwap` fire HTMX events on the client—before, after settle, and after swap respectively. Each carries an `HxEventPayload`: either a plain event name or a JSON value forwarded to listeners as `event.detail`:
175
+
176
+ ```scala
177
+ import zio.blocks.schema.json.Json
178
+ import zio.http.htmx.headers.{HxEventPayload, HxTriggerAfterSwap}
179
+
180
+ val plain = HxTriggerAfterSwap(HxEventPayload.Event("orderPlaced"))
181
+ val withDetail = HxTriggerAfterSwap(HxEventPayload.JsonValue(Json.Object("orderId" -> Json.Number(42))))
182
+ ```
183
+
184
+ Rendering shows the two payload shapes side by side—a bare event name and a JSON object:
185
+
186
+ ```scala
187
+ HxTriggerAfterSwap.render(plain)
188
+ // res14: String = "orderPlaced"
189
+ HxTriggerAfterSwap.render(withDetail)
190
+ // res15: String = "{\"orderId\":42}"
191
+ ```
192
+
193
+ `HxEventPayload.parse` decides which shape it saw by inspecting the value: a leading `{` or `[` parses as JSON, anything else is treated as a plain event name, and a blank value is rejected.
194
+
195
+ :::note[Why `HxTriggerHeader`, not `HxTrigger`]
196
+ The response header is named `HxTriggerHeader` rather than `HxTrigger` to avoid colliding with the attribute-DSL type documented in [HxTrigger](./hx-trigger.md)—`zio.http.htmx.HxTrigger` declares which client event fires a request, while `zio.http.htmx.headers.HxTriggerHeader` tells the client which events to dispatch after a response. Both share the wire name `hx-trigger` but never appear in the same import.
197
+ :::
198
+
199
+ ### Redirecting Without a Full Navigation
200
+
201
+ `HxLocation` triggers a client-side navigation to a new path without a full page load, optionally specifying where to swap the result and how—reusing `HxTarget` and `HxSwap` from the attribute DSL:
202
+
203
+ ```scala
204
+ import zio.http.htmx.{HxSwap, HxTarget}
205
+ import zio.http.htmx.headers.HxLocation
206
+
207
+ val location = HxLocation("/next", target = Some(HxTarget.closest("section")), swap = Some(HxSwap.AfterEnd))
208
+ ```
209
+
210
+ Rendering it produces the JSON object HTMX expects on the wire:
211
+
212
+ ```scala
213
+ HxLocation.render(location)
214
+ // res17: String = "{\"path\":\"/next\",\"target\":\"closest section\",\"swap\":\"afterend\"}"
215
+ ```
216
+
217
+ `HxLocation` also has overloads accepting a `zio.http.Path` or `zio.http.URL` for the first argument, encoding it the same way before building the JSON object. Parsing rejects anything that isn't a JSON object, since the wire format is always `{"path": ..., "target": ..., "swap": ...}` with `target` and `swap` omitted when absent.
218
+
219
+ ## Reading and Writing Through Request and Response
220
+
221
+ Every header in this module is a `Header.Typed[H]`, so it works with the same `Request#header` / `Response#header` / `addHeader` / `addHeaders` methods `zio.http` provides everywhere else—there is no HTMX-specific accessor. Combining several response headers in one call is the common case, for example after processing a form submission:
222
+
223
+ ```scala
224
+ import zio.http.{Response, URL}
225
+ import zio.http.htmx.headers.{HxRedirect, HxRefresh, HxTriggerAfterSettle, HxEventPayload}
226
+
227
+ val afterSubmit = Response.ok
228
+ .addHeader(HxRedirect(URL.parse("/orders").toOption.get))
229
+ .addHeader(HxTriggerAfterSettle(HxEventPayload.Event("orderPlaced")))
230
+ ```
231
+
232
+ Because parsing failures return `Left` rather than throwing, `Request#header`/`Response#header` return `None` for a header that is present but malformed, exactly as they do for any other typed header in `zio.http`—see [Header](../http-model/headers.md) for the full read/write surface these types plug into.
233
+
234
+ ## Integration Points
235
+
236
+ **With the attribute DSL:** `HxReswap`, `HxLocation`, `HxRetarget`, and `HxReselect` accept the exact same `HxSwap`, `HxTarget`, and `CssSelector` values that `hxSwap`, `hxTarget`, and `hxSelect` attributes accept, so a value built for one side works unchanged on the other.
237
+
238
+ **With `zio.blocks.schema.json`:** `HxEventPayload.JsonValue` wraps a `zio.blocks.schema.json.Json` value, letting event payloads carry structured data without a separate serialization step.
239
+
240
+ **With `zio.http`:** every type here is a `Header`/`Header.Typed[H]`, the same type class the built-in HTTP headers use, so `Headers`, `Request`, and `Response` treat HTMX headers no differently than `Content-Length` or `Cache-Control`.