Fix spread serialization in aser/async-aser wire format

Spread values from make-spread were crashing the wire format serializer:
- serialize() had no "spread" case, fell through to (str val) producing
  Python repr "<shared.sx.ref.sx_ref._Spread...>" which was treated as
  an undefined symbol
- aser-call/async-aser-call didn't handle spread children — now merges
  spread attrs as keyword args into the parent element
- aser-fragment/async-aser-fragment didn't filter spreads — now filters
  them (fragments have no parent element to merge into)
- serialize() now handles spread type: (make-spread {:key "val"})

Added 3 aser-spreads tests. All 562 tests pass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 12:20:16 +00:00
parent 427dee13f0
commit 859aad4333
6 changed files with 88 additions and 33 deletions

View File

@@ -775,6 +775,7 @@
(define-async async-aser-fragment :effects [render io]
(fn ((children :as list) (env :as dict) ctx)
;; Spreads are filtered — fragments have no parent element to merge into
(let ((parts (list)))
(for-each
(fn (c)
@@ -782,10 +783,10 @@
(if (= (type-of result) "list")
(for-each
(fn (item)
(when (not (nil? item))
(when (and (not (nil? item)) (not (spread? item)))
(append! parts (serialize item))))
result)
(when (not (nil? result))
(when (and (not (nil? result)) (not (spread? result)))
(append! parts (serialize result))))))
children)
(if (empty? parts)
@@ -885,13 +886,21 @@
(set! i (inc i)))
(let ((result (async-aser arg env ctx)))
(when (not (nil? result))
(if (= (type-of result) "list")
(if (spread? result)
;; Spread child — merge attrs as keyword args into parent element
(for-each
(fn (item)
(when (not (nil? item))
(append! parts (serialize item))))
result)
(append! parts (serialize result))))
(fn (k)
(let ((v (dict-get (spread-attrs result) k)))
(append! parts (str ":" k))
(append! parts (serialize v))))
(keys (spread-attrs result)))
(if (= (type-of result) "list")
(for-each
(fn (item)
(when (not (nil? item))
(append! parts (serialize item))))
result)
(append! parts (serialize result)))))
(set! i (inc i))))))
args)
(when token (svg-context-reset! token))