@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.
- package/adr/2026-07-18-data-migration.md +123 -0
- package/guides/async-getting-started.md +687 -0
- package/guides/compile-time-resource-safety-with-scope.md +6 -0
- package/guides/getting-started-with-mux.md +0 -112
- package/guides/query-dsl-extending.md +1 -1
- package/guides/query-dsl-fluent-builder.md +1 -1
- package/guides/query-dsl-reified-optics.md +1 -1
- package/guides/query-dsl-sql.md +395 -1
- package/guides/sql-checked-interpolation.md +173 -0
- package/guides/sql-transactions.md +286 -0
- package/guides/telemetry-guide.md +131 -70
- package/guides/zio-schema-migration.md +6 -6
- package/index.md +200 -583
- package/package.json +1 -1
- package/reference/async.md +1379 -531
- package/reference/chunk.md +3 -3
- package/reference/codegen/index.md +1 -1
- package/reference/combinators.md +4 -4
- package/reference/config/config-decoder.md +460 -0
- package/reference/config/config-source.md +489 -0
- package/reference/config/errors.md +278 -0
- package/reference/config/flags.md +369 -0
- package/reference/config/formats.md +314 -0
- package/reference/config/index.md +304 -0
- package/reference/config/rollout.md +336 -0
- package/reference/context.md +6 -49
- package/reference/data-migration.md +269 -0
- package/reference/datastar/attributes.md +302 -0
- package/reference/datastar/events.md +234 -0
- package/reference/datastar/index.md +256 -0
- package/reference/datastar/signals.md +230 -0
- package/reference/datastar/sse.md +295 -0
- package/reference/datastar.md +2 -2
- package/reference/docs.md +2 -2
- package/reference/endpoint/bulk-creation.md +96 -0
- package/reference/endpoint/index.md +9 -89
- package/reference/endpoint/path-codec.md +12 -24
- package/reference/endpoint/route-pattern.md +4 -6
- package/reference/endpoint/segment-codec.md +19 -32
- package/reference/html.md +313 -9
- package/reference/htmx/index.md +4 -52
- package/reference/htmx/response-headers.md +240 -0
- package/reference/http-model/headers.md +735 -0
- package/reference/http-model/index.md +3 -1
- package/reference/http-model/model.md +107 -71
- package/reference/http-model/schema-codecs.md +522 -0
- package/reference/http-model/schema.md +6 -3
- package/reference/http-model/server-sent-event.md +341 -0
- package/reference/jwt.md +195 -0
- package/reference/maybe.md +128 -11
- package/reference/media-type.md +2 -2
- package/reference/mux.md +254 -0
- package/reference/mux.mdx +7 -2
- package/reference/openapi.md +3 -3
- package/reference/projection.md +654 -0
- package/reference/resource-management/resource.md +2 -98
- package/reference/resource-management/scope.md +1 -209
- package/reference/resource-management/wire.md +4 -50
- package/reference/ringbuffer/advanced.mdx +1 -1
- package/reference/ringbuffer/index.mdx +3 -3
- package/reference/ringbuffer/mpmc.mdx +38 -4
- package/reference/ringbuffer/mpsc.mdx +36 -4
- package/reference/ringbuffer/spmc.mdx +1 -1
- package/reference/ringbuffer/spsc.mdx +87 -15
- package/reference/schema/allows.md +0 -96
- package/reference/schema/binding.md +2 -2
- package/reference/schema/built-in-codecs/avro.md +2 -2
- package/reference/schema/built-in-codecs/bson.md +50 -20
- package/reference/schema/built-in-codecs/csv.md +2 -2
- package/reference/schema/built-in-codecs/index.md +3 -3
- package/reference/schema/built-in-codecs/json/index.md +2 -2
- package/reference/schema/built-in-codecs/messagepack.md +3 -3
- package/reference/schema/built-in-codecs/thrift.md +2 -2
- package/reference/schema/built-in-codecs/toon.md +3 -3
- package/reference/schema/built-in-codecs/yaml.md +2 -2
- package/reference/schema/codec.md +11 -11
- package/reference/schema/dynamic-optic.md +48 -3
- package/reference/schema/dynamic-schema.md +3 -3
- package/reference/schema/index.md +2 -0
- package/reference/schema/path-interpolator.md +2 -0
- package/reference/schema/reflect-transformer.md +140 -0
- package/reference/schema/schema-evolution/as.md +4 -4
- package/reference/schema/schema-evolution/into.md +2 -2
- package/reference/schema/schema-expr.md +2 -2
- package/reference/schema/schema-search.md +263 -0
- package/reference/schema/schema.md +10 -2
- package/reference/schema/type-class-derivation.md +1 -1
- package/reference/smithy.md +502 -3
- package/reference/sql/db-codec-deriver.md +3 -3
- package/reference/sql/db-codec.md +22 -22
- package/reference/sql/db-con.md +4 -4
- package/reference/sql/db-connection.md +1 -1
- package/reference/sql/db-param.md +1 -1
- package/reference/sql/db-result-reader.md +4 -2
- package/reference/sql/db-tx.md +46 -14
- package/reference/sql/ddl.md +1 -1
- package/reference/sql/frag.md +44 -10
- package/reference/sql/index.md +7 -7
- package/reference/sql/repo.md +15 -15
- package/reference/sql/sql-dialect.md +1 -1
- package/reference/sql/sql-logger.md +1 -1
- package/reference/sql/sql-name-mapper.md +3 -3
- package/reference/sql/table-metadata.md +3 -3
- package/reference/sql/table.md +10 -10
- package/reference/sql/transactor-zio.md +1 -1
- package/reference/sql/transactor.md +21 -11
- package/reference/sql-zio.md +1 -1
- package/reference/streams/core/index.md +32 -0
- package/reference/streams/{pipeline.md → core/pipeline.md} +210 -74
- package/reference/streams/{sink.md → core/sink.md} +331 -353
- package/reference/streams/{stream.md → core/stream.md} +919 -209
- package/reference/streams/execution-and-compatibility/async-execution.md +822 -0
- package/reference/streams/execution-and-compatibility/index.md +35 -0
- package/reference/streams/execution-and-compatibility/platform-differences.md +297 -0
- package/reference/streams/execution-and-compatibility/scala-2-compatibility.md +88 -0
- package/reference/streams/execution-and-compatibility/zero-boxing.md +393 -0
- package/reference/streams/index.md +140 -67
- package/reference/streams/primitives/index.md +30 -0
- package/reference/streams/primitives/reader.md +1992 -0
- package/reference/streams/{writer.md → primitives/writer.md} +254 -98
- package/reference/telemetry/common/any-value.md +90 -0
- package/reference/telemetry/common/attribute-key.md +87 -0
- package/reference/telemetry/common/attributes.md +118 -0
- package/reference/telemetry/common/index.md +39 -0
- package/reference/telemetry/common/instrumentation-scope.md +24 -0
- package/reference/telemetry/common/resource.md +34 -0
- package/reference/telemetry/index.md +311 -0
- package/reference/telemetry/logging/index.md +197 -0
- package/reference/telemetry/logging/log-enrichment.md +72 -0
- package/reference/telemetry/logging/log-formatter.md +100 -0
- package/reference/telemetry/logging/log-record-processor.md +56 -0
- package/reference/telemetry/logging/log-record.md +44 -0
- package/reference/telemetry/logging/log-writer.md +64 -0
- package/reference/telemetry/logging/logger-provider.md +142 -0
- package/reference/telemetry/logging/logger.md +83 -0
- package/reference/telemetry/logging/severity.md +62 -0
- package/reference/telemetry/metrics/index.md +150 -0
- package/reference/telemetry/metrics/instruments.md +183 -0
- package/reference/telemetry/metrics/labeled-instruments.md +74 -0
- package/reference/telemetry/metrics/meter-provider.md +76 -0
- package/reference/telemetry/metrics/meter.md +98 -0
- package/reference/telemetry/metrics/metric-data.md +57 -0
- package/reference/telemetry/otel/custom-exporter.md +216 -0
- package/reference/telemetry/otel/index.md +212 -0
- package/reference/telemetry/tracing/index.md +155 -0
- package/reference/telemetry/tracing/sampler.md +89 -0
- package/reference/telemetry/tracing/span-builder.md +57 -0
- package/reference/telemetry/tracing/span-context.md +39 -0
- package/reference/telemetry/tracing/span-data.md +32 -0
- package/reference/telemetry/tracing/span-kind.md +55 -0
- package/reference/telemetry/tracing/span-processor.md +53 -0
- package/reference/telemetry/tracing/span-status.md +47 -0
- package/reference/telemetry/tracing/span.md +117 -0
- package/reference/telemetry/tracing/tracer-provider.md +91 -0
- package/reference/telemetry/tracing/tracer.md +52 -0
- package/reference/typeid.md +0 -64
- package/sidebars.js +150 -12
- package/undocumented-report.md +528 -270
- package/reference/config.md +0 -158
- package/reference/streams/concurrent-operators.md +0 -106
- package/reference/streams/reader.md +0 -1284
- package/reference/streams/scala-2-compatibility.md +0 -55
- package/reference/streams/zero-boxing.md +0 -275
- 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`.
|