fix: rc.10 follow-ups — live server-function address in dev, event-stream preview passthrough, attribution/perf-tracks pre-bundling - #374
Merged
Conversation
…sthrough, attribution/perf-tracks pre-bundling Four findings from the rc.9 → rc.10 audit. The server-function dev middleware now reads the id out of the runtime's third address shape, `<endpoint>/live/<id>` (a `live` loop's connection, @solidjs/web 2.0.0-rc.10), the way it already did for `data/<id>` — mirroring `parseServerFunctionAddress`: one kind segment at most, an id is exactly one segment. Before, `live/<id>` kept its slash, the id parsed to null, the on-demand SSR import was skipped, and a live function whose module nothing had loaded server-side yet 404'd (`Unknown server function`). The comments enumerating the two old shapes follow. `vite preview` passes `text/event-stream` responses and everything under the server-function mount through @polka/compression as `content-encoding: identity`, as it already did for `text/html`. The middleware sizes a response on its first write and, at ≥1KiB, pipes the rest through zlib, which holds small writes — a live event stream's events (and the streaming codec's chunks) would sit undelivered while the connection stays open. The mount reaches the start plugin through its internal wiring (`serverFunctionsEndpoint`), normalized by the shared `normalizeServerFunctionsEndpoint`. Under `serve`, `solid-js/attribution` and `@solidjs/web/performance-tracks` join `optimizeDeps.include`, so a consumer the scanner never crawls (a linked package, a `solid`-condition package vitefu excluded) importing one mid-session no longer triggers a late discovery → re-optimize → a second @solidjs/signals core. Both subpaths exist across the peer range. Stale strings: the `dev` option docs no longer name a `solid-js/dev` entry (it is the `development` export condition); `componentNames` → `sourceNames` in the start-ssr example's config comment and observe-mode labels. Tests: start-ssr dev mode dispatches a live address cold (module imported on demand, event-stream answer) and asserts the address grammar's misses; preview mode asserts live and data-address answers big enough to trip the threshold come back uncompressed while static assets still compress; components-warning asserts the two new include entries under serve and their absence under build. Co-authored-by: Claude via Cursor <noreply@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
🦋 Changeset detectedLatest commit: e40e2c4 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 |
commit: |
This was referenced Sep 27, 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.
Four follow-ups found by the rc.9 → rc.10 audit of the plugin against Solid 2.0.0-rc.10. No plugin option added, removed or renamed.
1.
live/server-function address in the dev middlewareWhat. The dev middleware's id parser strips a leading
live/segment the way it stripsdata/, mirroring the runtime'sparseServerFunctionAddress(one kind segment at most; an id is exactly one segment, solive/,live/a/banddata/live/<id>stay misses).Why. rc.10 added a third address shape,
<endpoint>/live/<id>, for aliveloop's connection (answered astext/event-stream). The parser only knewdata/, solive/<id>kept its slash →functionId = null→ the on-demand SSR import was skipped → a live function whose module nothing had imported server-side yet came back404 Unknown server function(reproduced before the fix; 200 event-stream after).Where.
src/server-functions/index.ts:649(the strip), comments atsrc/server-functions/index.ts:611,:639andsrc/ssr/index.ts:1324now enumerate all three shapes.2. Preview compression vs event streams
What.
vite preview's handler middleware setscontent-encoding: identityfortext/event-streamresponses and for everything under the server-function mount, in addition totext/html.Why.
@polka/compressionsizes a response on its first write and, at ≥1KiB, pipes the rest through zlib, which holds small writes until its buffer fills — a live event stream's events would sit undelivered while the connection stays open; the streaming codec's chunks likewise arrive in bursts. Rule chosen and documented in the code: content type fortext/htmlandtext/event-stream(SSE from an app middleware route is a stream too), plus the server-function mount, because the runtime's other streamed shape — the codec stream — istext/plain, too generic to key on, and keying on the mount keeps a future answer shape from silently regressing to buffered. The mount reaches the start plugin throughstartServe's existing internal wiring (serverFunctionsEndpoint;startServeis not part of the package's exports), normalized by a sharednormalizeServerFunctionsEndpoint(same logic the server-functions plugin already used inline).Where.
src/ssr/index.ts:1824–1885(mount + rule),src/ssr/index.ts:630(internal field),src/index.ts:2143(threading),src/server-functions/index.ts:182(normalizer, used at:382).3.
optimizeDeps.include:solid-js/attribution,@solidjs/web/performance-tracksWhat. Both subpaths join
optimizeDeps.includeunderserve— the same gate the refresh runtime and the frames/server-functions entries already use; not gated on the dev/observe posture (the surrounding entries aren't, and the subpaths exist in every posture).Why. A consumer the scanner never crawls (a linked package, a
solid-condition package vitefu excluded) importing one mid-session triggers late discovery → re-optimize → a second@solidjs/signalscore beside the onesolid-jswas bundled with. Verified both subpaths exist inpackages/solid/package.json/packages/web/package.jsononorigin/nextand at tagsolid-js@2.0.0-rc.10(./attributionsince rc.8,./performance-trackssince rc.10; peer range is^2.0.0-rc.10).Where.
src/index.ts:1382–1394.4. Stale strings
README.md:124andsrc/index.ts:265no longer say thedevoption "injectssolid-js/dev" (no such entry); it resolves thedevelopmentexport condition.examples/start-ssr/vite.config.ts:35,examples/start-ssr/test/run.mjs:4420,:4453:componentNames→sourceNames.Tests
examples/start-ssr/test/run.mjs:1001–1051(dev mode): cold dispatch at/_server/live/<id>forincrementCounterinsrc/frames/data.tsx— a module App.tsx never imports and the bare cold dispatch didn't load — expects 200text/event-streamwith adata:event; plus the three grammar misses. Fails onorigin/next(404), passes here.examples/start-ssr/test/run.mjs:3376–3468(preview mode):greetat the live address (201 event-stream, first chunk >1KiB) andgetServerMessageat the data address (text/plain) come back withoutgzip/br, while the hashed client asset still compresses. With the oldtext/html-only rule both come backgzip(verified).examples/start-ssr/test/components-warning.mjs:120–140: the two entries present underserve, absent underbuild.Results (all local, macOS):
pnpm build(rollup +tsc --emitDeclarationOnly)pnpm checkpnpm test(vite-8 Cypress)examples/start-ssrpnpm test(run.mjs all modes + http-bridge + components-warning)examples/start-clientexamples/start-envexamples/ssrexamples/css-matrixexamples/vite-8vitest (browser)Prettier: the touched files carry pre-existing drift on lines this PR doesn't touch; every line this PR adds or changes is prettier-clean.
Public API changes: none
startServe'sinternalparameter gainedserverFunctionsEndpoint, andnormalizeServerFunctionsEndpointis a new module-level export ofsrc/server-functions/index.ts; neither is reachable from the package's export map (.re-exportsserverFunctionsand types only).