dream: flash messages — single-request cookie store + 14 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m14s

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 14:38:26 +00:00
parent 55ec0b8f64
commit edff7735e7
4 changed files with 232 additions and 1 deletions

View File

@@ -60,7 +60,7 @@ The five types: `request`, `response`, `handler = request -> response`, `middlew
- Cookie-backed session middleware.
- `dream-session-field req key`, `dream-set-session-field req key val`.
- `dream-invalidate-session req`.
- [ ] **Flash messages** in `lib/dream/flash.sx`:
- [x] **Flash messages** in `lib/dream/flash.sx`:
- `dream-flash-middleware` — single-request cookie store.
- `dream-add-flash-message req category msg`.
- `dream-flash-messages req` — returns list of `(category, msg)`.
@@ -142,6 +142,15 @@ Confirm scope before starting; some of these may be addable as Dream-internal he
`dream-resp-cookies`, `dream-drop-cookie`) — outgoing cookies accumulate in a
`:set-cookies` list on the response so multiple Set-Cookie headers don't collide;
reused by flash + CSRF. Full counter round-trip verified across three requests.
- **2026-06-07 — Flash** (`lib/dream/flash.sx`, 14 tests). `dream-flash` middleware:
decodes the incoming `dream.flash` cookie into the request, gives the handler a
mutable outbox cell (`dr/flash-box`, the same `set!`-captured-`let` trick), then on
response writes the outbox as a fresh flash cookie, or drops the cookie (Max-Age=0)
when there were incoming messages but no new ones — so messages show exactly once.
Handler API: `dream-add-flash-message` / `dream-flash-messages` (returns the
PREVIOUS request's messages) / `dream-flash-of` (by category) / accessors. Cookie
codec percent-escapes the `|`/`~`/`%` separators so categories/messages round-trip.
Read-after-write verified across request boundaries incl. multi-category.
## Blockers