Commite83a7801Recorded4 Jul 2026Repositorysigil-http
http-response/sse-broadcast: default handler to identity
Message
Make the transform handler an optional leading positional defaulting to identity, so a hub that already carries pre-formatted SSE strings (the common case) needs no handler: (http-response/sse-broadcast hub on-connect: ...). Kept it positional (not a keyword) so existing positional-handler callers (vigil, sigil-web dev, sigil-web-demo) keep working unchanged.
Changed
src/sigil/http/response.sgl | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)Diff
src/sigil/http/response.sglmodified
@@ -531,29 +531,48 @@
531
;; close function 532
close)))) 533
+534
;; Look up a keyword's value in a flat keyword/value plist, else default.+535
(define (sse-broadcast-kw-ref plist key default)+536
(let loop ((p plist))+537
(cond+538
((or (null? p) (null? (cdr p))) default)+539
((eq? (car p) key) (car (cdr p)))+540
(else (loop (cdr (cdr p)))))))+541
542
;;; Create an SSE response that broadcasts from a channel. 543
;;; 544
;;; Subscribes to a broadcast channel and sends events for each message.−537
;;; The handler transforms messages into SSE event strings.+545
;;; The handler transforms messages into SSE event strings; it is+546
;;; optional and defaults to the identity function, so a hub that already+547
;;; carries pre-formatted SSE strings (the common case) needs no handler. 548
;;; 549
;;; Parameters: 550
;;; broadcast: The broadcast channel to subscribe to−541
;;; handler: (lambda (msg) ...) -> string or #f−542
;;; Returns SSE event string to send, or #f to skip+551
;;; handler: Optional (lambda (msg) ...) -> string or #f.+552
;;; Returns SSE event string to send, or #f to skip.+553
;;; Defaults to identity (send each message as-is). 554
;;; buffer-size: Subscriber buffer size (default: 32)−544
;;; on-connect: Optional (lambda () ...) called on connect−545
;;; Returns initial event string or #f+555
;;; on-connect: Optional (lambda () ...) called on connect.+556
;;; Returns initial event string or #f. 557
;;; 558
;;; Example: 559
;;; ```scheme+560
;;; ;; Hub carries pre-formatted event strings — no handler needed:+561
;;; (http-response/sse-broadcast hub on-connect: (lambda () (snapshot)))+562
;;;+563
;;; ;; Transform raw messages into SSE strings: 564
;;; (http-response/sse-broadcast chat-broadcast−550
;;; (lambda (msg)−551
;;; (sse-event "message" (json-encode msg))))+565
;;; (lambda (msg) (sse-event "message" (json-encode msg)))) 566
;;; ```−553
(define (http-response/sse-broadcast broadcast handler−554
(keys: (buffer-size 32)−555
(on-connect #f)))−556
(: any? procedure? (buffer-size: integer?) (on-connect: (maybe procedure?)) -> http-response?)+567
(define (http-response/sse-broadcast broadcast . opts)+568
;; `handler` is an optional leading positional (a procedure); anything+569
;; after it (or all of `opts`, if the first isn't a procedure) is treated+570
;; as buffer-size:/on-connect: keyword arguments.+571
(let* ((has-handler (and (pair? opts) (procedure? (car opts))))+572
(handler (if has-handler (car opts) (lambda (msg) msg)))+573
(kwargs (if has-handler (cdr opts) opts))+574
(buffer-size (sse-broadcast-kw-ref kwargs buffer-size: 32))+575
(on-connect (sse-broadcast-kw-ref kwargs on-connect: #f))) 576
(http-response 577
status: HTTP-OK 578
headers: (dict@@ -591,7 +610,7 @@
610
;; Write failed, clean up 611
(broadcast-unsubscribe broadcast sub) 612
;; Handler returned #f, skip and continue−594
(loop))))))))))))+613
(loop))))))))))))) 614
615
;;; Format a Server-Sent Event with event type and data. 616
;;;