Repository navigation
@solidjs/web@2.0.0-rc.21
Pre-release
Pre-release
·
48 commits
to main
since this release
Patch Changes
- 32163a9: A stylesheet released while it is still loading no longer hangs a gate that warmed it again inside the removal grace. The release schedules the element's removal 100 ms later; a mount in between (a
useHeadstylesheet under<Loading>) warmed the same registry entry and waited on that element's load, and the removal took the element out before it loaded. A removed link fires neither load nor error, so the boundary stayed on its fallback. The removal now settles a pending load the way an error does, and the gate warms the sheet again on a new element and waits on that one. - bb51da6:
AssetManifestadmits a manifest that sets_base(#4502). It wasRecord<string, Entry> & { _base?: string }, and since_basealso falls under the string index signature it had to be an entry too, so a manifest literal with_base: "/"did not type-check. The index signature now carries entries, metadata strings (_base, and any an integration stamps, such as the vite plugin's_entry) andundefined, so a read by key is an entry once narrowed (typeof entry === "object"). The server renderer narrows the same way: a metadata key enumerated while registering entry assets, or asked for byresolveAssets, is skipped instead of throwing. - 3c47d06: A broadcast live read with a plain form query (
?room=a, no?args=) is now keyed by that query, so viewers of different queries no longer share one source. - 61bb177:
createOwnerleaves solid-js's public types: it is typed only throughsolid-js/internal, like the boundary primitives behindErrored,LoadingandReveal(#3709). It stays a runtime export for the renderers. Solid 1.x had nocreateOwner, and application code that used it in an RC should host a scope withcreateRoot()(itsdisposeargument can be passed around as a plain function) and re-enter one withrunWithOwner(). A detachedowner.disposekeeps throwing, since it is a method and not part of the public API (#4444). - 62745f6: Shrink the compiled and hand-written floors: the dependent walks, dependency clearing, status writes, effect-run queueing, flatten's thunk walk and the delegated-event parent hop share their code (no behavior change).
- 551ef0d: An awaited
renderToStream()that re-pulls root holes — as happens when alazy()component's first load is shared across concurrent renders — now restores the render'ssharedConfig.contextfirst, the same restore the streamed path already performs indoShell. Without it the resumed render body runs under whichever concurrent render set the global last, so an async memo created there records into (and adopts from) another render's slot store and concurrent requests can read each other's values (#4595). - 6b6b4da: Server-rendered
<link rel="modulepreload">hints for modules outside the entry's static import closure (lazy and route chunks, and modules registered later throughregisterAsset("module"), streamed hints included) now carryfetchpriority="low", so they yield bandwidth to the modules hydration waits on. The entry's static imports and modulepreload links written through the head API keep their default priority.renderToStringandrenderToStreamtakelowPriorityPreloads: falseto turn the hint off. In an rc.15 app (Tailwind, five entry imports, four route chunks) patched the same way, Chrome under Lighthouse's devtools throttling hydrated about 310 ms sooner with an unchanged first paint. - 3c47d06: A no-JS form post answered by
respond(value, { headers }), returned or thrown, now keeps the envelope'sSet-Cookieheaders on the redirect. - b656418: A direct server-function call no longer enters the request scope or copies property descriptors for each plain object and array in its result. The walk that binds deferred bodies now skips
bindDeferredBody's scoped promise probe for a plain object or array that has no own iterator orSymbol.toStringTaghook, reads each slot's descriptor on its own, and allocates a frame only for a container whose slots hold an object. Descriptors are still snapshotted before any authored code can run. A call returning 1,000 plain rows walks in 0.11 ms instead of 0.55 ms. - 6262453: The server
ssrElementjoins a compiled dynamic child in place. The compiler emits a spread element's dynamic child as() => scope(() => expr), andssrScopereturns a function in both modes, so afterssrElement's one call the child was still a function and every such element fell toresolveSSRNodeplusssr()'s hole loop. Outside a live-hole render,ssrElementnow calls the scope's evaluator once more, asresolveSSRNodewould, and joins a string or number result directly. Other values resolve nested as before, and a suspension becomes the same async hole through a sharedpushSSRAsyncHole. Server output is byte-identical. On a prod build,spread-static-tailrenders 7–14% faster (500 rows). - 5ae39fc: Fail
renderToStreamwhen an asynchronous value cannot be serialized after its key was handed to the default serializer, if that happens before the first flush (an awaited render, or before the shell went out). The render tears down without callingonCompleteAlland nothing is sent (#4647). Synchronous serialization failures and custom serializers keep their existing behavior. - ccfc7ea: Aborting
renderToStream'ssignalnow settles and ends every streaming consumer. Before, the promise frompipeTocould stay pending forever after an abort, thereadableview and acreateSSRResponsebody never closed, and apipesink was never ended, which kept the request alive. Now nothing more is written and each surface ends cleanly, as a close and not an error, since the bytes already sent stay sent:pipeends its sink,pipeTocloses its writable and resolves without rejecting, andreadablecloses.createSSRResponseends its200body after the shell and still resolves with a bodyless500before it.onErrorandonCompleteAllare not called. The awaited form rejects withsignal.reason(see the companion changeset) (#4646). - ccfc7ea: Reject
renderToStreamthenable consumers withsignal.reasonwhen itssignalaborts, including consumers registered after cancellation. Render failures still resolve with the available HTML. - 5ae39fc:
renderToStream: an async value that resolves to something the serializer cannot handle after the first flush (midstream) now rejects its key on the client instead of leaving it pending forever (#4647) — and with it every promise or async iterable inside the value that already went out (a nested promise, an async iterable's later items), and every other key on the same value. The failure is still reported as{ kind: "render", handling: "serialize" }and the render completes; the payload settles the key's promise with an error that says it is a serialization failure and names the key (the failure's own text stays on the server). The hydrating read throws into the nearest<Errored>, whose fallback replaces the server-rendered content untilreset()or an input change reruns the computation as a client fetch. With no<Errored>above, it is uncaught like any rejected key. Before the first flush the render fails instead (see the other changeset). - b7e4f16: Keep the metadata of files and blobs sent to server functions with
enableRichArguments(). A blob arrives as aBlobinstead of aFilenamedblob, an empty type stays empty instead ofapplication/octet-stream, and a file keeps its exact name and itslastModified. The server still reads uploads from clients that send only the part index. - Updated dependencies [46ab2dd]
- Updated dependencies [61bb177]
- Updated dependencies [25fb7be]
- Updated dependencies [0d4c5e0]
- Updated dependencies [84353de]
- Updated dependencies [99d9821]
- solid-js@2.0.0-rc.21