Phase 6: Streaming & Suspense — chunked HTML with suspense resolution

Server streams HTML shell with ~suspense placeholders immediately,
then sends resolution <script> chunks as async IO completes. Browser
renders loading skeletons instantly, replacing them with real content
as data arrives via __sxResolve().

- defpage :stream true opts pages into streaming response
- ~suspense component renders fallback with data-suspense attr
- resolve-suspense in boot.sx (spec) + bootstrapped to sx-browser.js
- __sxPending queue handles resolution before sx-browser.js loads
- execute_page_streaming() async generator with concurrent IO tasks
- Streaming demo page at /isomorphism/streaming with 1.5s simulated delay

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-07 17:34:10 +00:00
parent 85083a0fff
commit a05d642461
15 changed files with 586 additions and 38 deletions

View File

@@ -120,7 +120,8 @@
(dict :label "Bundle Analyzer" :href "/isomorphism/bundle-analyzer")
(dict :label "Routing Analyzer" :href "/isomorphism/routing-analyzer")
(dict :label "Data Test" :href "/isomorphism/data-test")
(dict :label "Async IO" :href "/isomorphism/async-io")))
(dict :label "Async IO" :href "/isomorphism/async-io")
(dict :label "Streaming" :href "/isomorphism/streaming")))
(define plans-nav-items (list
(dict :label "Status" :href "/plans/status"