Require the async (encrypted) flash decoder in the submissions seed (solidjs/solid#3239) - #597
Draft
ryansolid wants to merge 1 commit into
Draft
Require the async (encrypted) flash decoder in the submissions seed (solidjs/solid#3239)#597ryansolid wants to merge 1 commit into
ryansolid wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: 8edac15 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
…eed (solidjs/solid#3239) The flash cookie is now AES-GCM encrypted, so the runtime's decodeFlashCookie is async (WebCrypto has no sync API). The provideFlashDecoder slot takes exactly that shape — no sync compatibility path to forget about later — and the submissions seed absorbs the Promise through the not-ready protocol: - The decode is cached at router scope: at most one per request, and a parked reader's rerun finds the settled outcome rather than restarting it. - The seeding read lives in a memo, so NotReadyError surfaces from a reactive node the graph can park and retry — never from router setup, which no boundary guards — bounding the recompute to the memo plus the readers that actually consumed it. - lazy: server memos compute eagerly by default; deferred to first read, a request whose submissions are never read never decodes, and a request without a flash cookie never creates the memo at all. - transparent: the memo exists on the server only (the client seeds submissions as [] without it), so its owner must not consume a hydration-id slot the client would miss — sibling ids stay aligned. The provide site wraps decodeFlashCookie in an async arrow only because rc.6 still types it synchronous; the wrapper is marked for removal with the rc.7 dep bump. Co-authored-by: Cursor <cursoragent@cursor.com>
ryansolid
force-pushed
the
flash-async-decoder
branch
from
September 4, 2026 05:17
f8ea017 to
8edac15
Compare
This was referenced Sep 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Companion to the encrypted no-JS flash cookie in
@solidjs/web(solidjs/solid#3239, commit solidjs/solid@fbe5bef4): the flash payload carries the submitted form input, so it is now AES-GCM encrypted anddecodeFlashCookieis async (WebCrypto has no sync API). TheprovideFlashDecoderslot now takes exactly that shape — async only, no sync compatibility path to forget about later — and the submissions seed absorbs the Promise.How the server handles it
The seeding read moves into a memo created only when a flash cookie actually arrived, and the in-flight decode rides
NotReadyError— the same SSR spelling the router already uses for unresolved lazy route matches:useSubmissionresumes into the settled result.lazy: truedefers to the first submissions read, so a request that renders without touchinguseSubmissionnever decodes — and a request without a flash cookie never creates the memo at all. (The eager half — detection + one-shot clear — is unchanged.)[]without ever creating it.transparent: truekeeps its owner out of the hydration-id chain, so sibling ids don't shift (the #3012 class of bug).The one temporary line
The provide site wraps the runtime export in an async arrow (
provideFlashDecoder(async h => decodeFlashCookie(h))) only because the installed rc.6 still types it synchronous; it carries aTODO(@solidjs/web >= 2.0.0-rc.7)to passdecodeFlashCookiedirectly with the dep bump in this PR.Tests
The flash-seeding server spec now runs the async shape throughout: the parking round-trip (first read throws
NotReadyError, resumed read seeds from a decode that ran exactly once), the laziness guarantee (a rendered request that never reads submissions never decodes, while the one-shot clear still lands), and the existing seeding/pre-seed/no-cookie contracts through a parked read helper. Full suite: 395 client + 35 server + type tests pass.Draft until
@solidjs/web2.0.0-rc.7 ships the encrypted flash runtime; lands in unison with solidjs/solid-vite-plugin#343 (deployment-secret injection).