summary#
snarl should enable for explicit chunk flushing, particularly for custom jsx runtimes that require fine-grained control over response streaming semantics. despite implicitly enabling support for streaming responses via native Response objects, it’s not designed with a stream-aware architecture in mind
shortcoming#
the current design assumes a static request-response model:
- handlers return a fully materialised
Response - jsx rendering resolves to
string | Promise<string> - response helpers (
ctx.json,ctx.html, etc.) eagerly construct buffered responses
frameworks like cobweb that implement custom jsx runtimes with asynchronous rendering and incremental html emission over chunked transfer encoding lack a standardized mechanism to participate in the response streaming lifecycle while remaining bound to the request context. this makes incremental html emission cumbersome and prevents fine-grained chunk flushing from integrating cleanly with the router and middleware stack.
while manually constructed streams are technically possible via the Streams API, there still ain’t no framework-level abstraction that:
- binds the writable stream lifecycle to context
- allows jsx runtimes to flush html chunks incrementally
- keeps stream state within the request lifecycle
- preserves middleware composability
proposed solution#
introduce a router-managed streaming session that can be lazily attached to context, enabling explicit chunk flushing while preserving existing Response semantics. this would heavily eliminate the need of out-of-band stream construction that disconnects the renderer from the request context and weakens architectural cohesion
implementation notes:
- backward compatibility must be preserved
contextshould be kept transport-agnostic at the type level- middlewares should be allowed to observe and modify headers before finalization
i guess an optimal approach would be to defer Response materialisation to the router itself and expose an extensible controlled writer interface
proof of concept#
// tbd