diff --git a/src/routes/(1)getting-started/(1)project-shapes.mdx b/src/routes/(1)getting-started/(1)project-shapes.mdx index 000911a37..eee1ea743 100644 --- a/src/routes/(1)getting-started/(1)project-shapes.mdx +++ b/src/routes/(1)getting-started/(1)project-shapes.mdx @@ -60,7 +60,7 @@ import { handleRequest } from "./dist/server/server.js"; const response = await handleRequest(request); ``` -The template's `server.js` is the Node version of that. +The `fullstack` template sets `start: { node: true }`, so the build also writes `dist/server/node.js`, the Node version of that: it serves `dist/client`, passes the rest to `handleRequest`, and listens on `PORT`. On a fetch-native platform, map `handleRequest` to the host's request entry point and point its static asset service at `dist/client`. Workers, Deno, and Bun each have their own module, asset, and environment configuration; [Deployment](/building-apps/deployment) covers them. diff --git a/src/routes/(3)building-apps/(7)deployment.mdx b/src/routes/(3)building-apps/(7)deployment.mdx index 4c7cfef93..73b59c69d 100644 --- a/src/routes/(3)building-apps/(7)deployment.mdx +++ b/src/routes/(3)building-apps/(7)deployment.mdx @@ -13,7 +13,7 @@ A `bare` or `basic` project builds to `dist/client` alone, and any static host s This page is about a project with `ssr: true` or server functions, which builds to static assets plus a server handler. [Project shapes](/getting-started/project-shapes) says which shape produces which output; [App structure](/building-apps/app-structure) explains the entries the handler runs. -Most apps need the request handler section and one of the host sections after it: Node with the template's `server.js`, or one provider plugin. +Most apps need the request handler section and one of the host sections after it: Node with the emitted `dist/server/node.js`, or one provider plugin. The rest is for checking a detail or wiring a host that is not listed. ## What the build produces @@ -80,41 +80,122 @@ const server = createServer(async (req, res) => { ``` With the `Avoid` version, a request for `/assets/app-BpJ2g.js` renders the HTML page, because in production every request that reaches the end of the middleware chain renders; the browser receives a document where it expected a script. +With `start.node`, the emitted Node entry is the `Prefer` version; the rest of this section is for a bridge you write. When adapting a host request, preserve the URL, method, headers, and the body of any request that is not `GET` or `HEAD`. When adapting the result, preserve the status, the headers, each `Set-Cookie` value separately, and the streamed body. :::caution[Set-Cookie must not be comma-joined] A response can carry several `Set-Cookie` headers, and joining them into one comma-separated value corrupts every cookie in it. -The template's `server.js` reads them with `headers.getSetCookie()` and passes the array to Node; a bridge for another server needs the same care. +The emitted Node entry reads them with `headers.getSetCookie()` and passes the array to Node; a bridge for another server needs the same care. ::: ## Node -The fullstack templates include `server.js`, the verified Node adapter. -It converts `node:http` requests to web `Request` objects, serves `dist/client`, calls `handleRequest`, and streams the response back. -The template's start script runs that file: +Node has no server API that accepts a Fetchable module, so the plugin emits the Node server. +Set `start.node` and the build writes `dist/server/node.js` next to `dist/server/server.js`: + +```ts title="vite.config.ts" +import { defineConfig } from "vite"; +import solid from "@solidjs/vite-plugin"; + +export default defineConfig({ + plugins: [ + solid({ + start: { node: true }, + ssr: true, + }), + ], +}); +``` + +`server.js` does not change: `handleRequest` and the default `{ fetch }` export are the same as without the option, so a provider integration or a Fetch runtime keeps working from that file. + +Build, then run the emitted file: + +```bash +pnpm build +node dist/server/node.js +``` + +The server listens on `PORT`, defaulting to `3000`, and binds to `HOST` when it is set. +Those two variables are the only runtime configuration. +The fullstack templates point their start script at the file: ```json { "scripts": { - "start": "node --env-file-if-exists=.env server.js" + "start": "node --env-file-if-exists=.env dist/server/node.js" } } ``` -Run `pnpm build` and then `pnpm start`, and the server listens on `PORT` or `3000`. Any Node host that runs that command with `PORT` and the server environment set is done. -Use the template adapter as the reference when integrating another Node server. -The bridge must stream the request body for methods other than `GET` and `HEAD`, and it must forward multiple `Set-Cookie` headers as separate values. +The emitted entry is the `Prefer` version from [the request handler section](#the-request-handler), with the details a production bridge needs: + +- It serves `dist/client` first. + Hashed files under `assets/` get `Cache-Control: public, max-age=31536000, immutable`; other files get `public, max-age=0, must-revalidate` and a `Last-Modified` header. + A path containing `..` cannot leave the directory, and a path with a dot segment such as `.vite/manifest.json` is never served. +- It passes every request that matched no file to `handleRequest(request, { event: { nativeEvent: req } })` through the same Node-to-web bridge that `vite dev` and `vite preview` use. + The bridge streams the request body for methods other than `GET` and `HEAD`, forwards each `Set-Cookie` header separately, answers `HEAD` without a body, aborts the render when the client disconnects, and waits for the socket to drain before writing more. +- In client start mode with server functions, it serves `dist/client/index.html` for HTML-accepting `GET` requests that match no file, and routes the server-function endpoint to the handler. +- It speaks plain HTTP. + Terminate TLS and compress at a reverse proxy or CDN in front of it, or mount it in Express behind `compression()` as shown below. :::tip[The raw request is one option away] -`server.js` passes the Node request into the event with `handleRequest(request, { event: { nativeEvent: req } })`. -Middleware and server functions then read `getRequestEvent().nativeEvent` for platform details such as the socket's remote address. +The emitted entry passes the Node request into the event with `handleRequest(request, { event: { nativeEvent: req } })`, so `getRequestEvent().nativeEvent` is the Node `IncomingMessage`. +Middleware and server functions read it for platform details such as the socket's remote address. Behind a proxy, read the forwarding headers off `getRequestEvent().request` instead, and only when the proxy is trusted. ::: +### Your own Node server + +Keep a hand-written entry when the app needs compression, a custom `http` server, or a place inside an existing Express or Fastify app. +`dist/server/node.js` exports three things for that: `listener`, the `(req, res)` function the emitted server runs; `createListener(options)`, which builds a listener with options; and `serve(options)`, which creates and starts an `http.Server` on `PORT` and `HOST` and returns it. +Importing the file does not start a server; only running it directly does. + +```js +// server.js +import { createServer } from "node:http"; +import { listener } from "./dist/server/node.js"; + +createServer(listener).listen(process.env.PORT || 3000); +``` + +With Express, either put compression in front and let the listener serve everything: + +```js +// server.js +import express from "express"; +import compression from "compression"; +import { listener } from "./dist/server/node.js"; + +const app = express(); +app.use(compression()); +app.use(listener); // static files, pages, server functions +app.listen(process.env.PORT || 3000); +``` + +Or let Express own the static files and keep only the bridge: + +```js +// server.js +import express from "express"; +import { createListener } from "./dist/server/node.js"; + +const app = express(); +app.use(express.static("dist/client", { immutable: true, maxAge: "1y" })); +app.use(createListener({ static: false })); +app.listen(process.env.PORT || 3000); +``` + +`static: false` skips the file lookup and, in client start mode, the `index.html` history fallback; Express owns both. +`createListener({ event: (req) => ({ ...fields }) })` merges extra fields next to `nativeEvent` in the request event, and `serve()` accepts `static` and `event` alongside `port` and `host`. + +A bridge written against `handleRequest` from `dist/server/server.js` is the last resort, for a server that cannot mount a Node request listener. +It must meet the requirements in [the request handler section](#the-request-handler): stream the request body for methods other than `GET` and `HEAD`, forward multiple `Set-Cookie` headers as separate values, and pass the Node request as `event.nativeEvent`. + ## Preview the production artifact The start-mode integration configures `vite preview` to serve `dist/client` and dispatch the remaining requests through the built handler: @@ -124,7 +205,7 @@ pnpm build pnpm exec vite preview ``` -The official fullstack templates name the Vite preview script `serve` and reserve `start` for the included Node server. +The official fullstack templates name the Vite preview script `serve` and reserve `start` for the emitted Node server. Preview verifies the built handler and static assets together; it does not replace a test on the target host. ## Provider integrations @@ -286,6 +367,12 @@ Under `ssr: true`, requests for pages are not reaching `handleRequest`; the host Route every request that is not a file to the handler. For a static-shell project, there is no handler: configure the host to serve `dist/client/index.html` for paths that are not files, as any single-page app needs. +### `Cannot find module 'dist/server/node.js'` + +The build writes `dist/server/node.js` only when `start.node` is `true`. +Set `start: { node: true }` in `vite.config.ts` and run the build again; `server.js` alone is the handler, not a server. +If `dist/server` is missing altogether, see the next problem. + ### `Cannot find module './dist/server/server.js'` The build did not produce a server directory. @@ -301,14 +388,14 @@ Client `VITE_` values are the opposite: set them on the machine that runs `vite ### Sign-in works locally but the session is missing in production The bridge joined several `Set-Cookie` headers into one comma-separated value, which corrupts them. -Forward them as separate headers, the way `server.js` does with `getSetCookie()`. +Forward them as separate headers, the way the emitted Node entry does with `getSetCookie()`. ## Recap - Serve `dist/client` as static files first and pass every other request to `handleRequest`. - `handleRequest(request)` and the default `{ fetch }` export are the same handler; the default export ignores host arguments after the request. - Preserve the method, headers, and streamed body on the way in, and the status, headers, separate `Set-Cookie` values, and streamed body on the way out. -- Run the template's `server.js` on any Node host; `pnpm build` then `pnpm start`. +- Set `start.node` and run `node dist/server/node.js` on any Node host; `PORT` and `HOST` are its only configuration. - Set `server` environment variables on the host, because they are read at boot; `VITE_` values are fixed at build time. - A provider plugin adopts the `ssr` environment; reach for `start.external` only when the host names or configures its server environment differently. - `vite preview` runs the built handler and assets together, and does not replace a test on the target host. diff --git a/src/routes/(6)migration/(2)from-solid-start.mdx b/src/routes/(6)migration/(2)from-solid-start.mdx index 3b9094a30..b6956fb24 100644 --- a/src/routes/(6)migration/(2)from-solid-start.mdx +++ b/src/routes/(6)migration/(2)from-solid-start.mdx @@ -504,7 +504,7 @@ Preserve the request URL, method, headers, and body. Preserve the response status, headers, separate `Set-Cookie` values, and streamed body. Do not deploy the old Nitro output or reuse a SolidStart provider preset. -The pinned templates include a verified Node adapter. +For Node, set `start: { node: true }`; the build then writes `dist/server/node.js`, a server that implements this boundary and runs with `node dist/server/node.js`. Other hosts need an adapter or Vite integration that implements this exact asset and handler boundary. Set `start.external: true` only when a host integration owns both server build wiring and HTTP serving. diff --git a/src/routes/reference/(1)solid-js/(1)reactivity/create-effect.mdx b/src/routes/reference/(1)solid-js/(1)reactivity/create-effect.mdx index 8012f2ff4..ff8f79fca 100644 --- a/src/routes/reference/(1)solid-js/(1)reactivity/create-effect.mdx +++ b/src/routes/reference/(1)solid-js/(1)reactivity/create-effect.mdx @@ -20,15 +20,15 @@ source_path: "packages/solid/src/client/hydration.ts" Creates a reactive effect with **separate compute and effect phases**. -- `compute(prev)` runs reactively — *put all reactive reads here*. +- `compute(prev)` runs reactively — _put all reactive reads here_. The returned value is passed to `effect` and is also the new "previous" value for the next run. - `effect(next, prev?)` runs imperatively (untracked) after the - queue flushes. *Put DOM writes / fetch / logging / subscriptions - here.* It may return a cleanup function which runs before the + queue flushes. _Put DOM writes / fetch / logging / subscriptions + here._ It may return a cleanup function which runs before the next effect or on disposal. -Reactive reads inside `effect` will *not* re-trigger this effect — +Reactive reads inside `effect` will _not_ re-trigger this effect — that's intentional. If you need a single-phase tracked effect, use `createTrackedEffect` (with the tradeoffs noted there). @@ -50,9 +50,9 @@ import { createEffect } from "solid-js"; ```ts function createEffect( - compute: ComputeFunction, T>, - effectFn: EffectFunction, T> | EffectBundle, T>, - options?: EffectOptions + compute: ComputeFunction, T>, + effectFn: EffectFunction, T> | EffectBundle, T>, + options?: EffectOptions ): void; ``` @@ -87,8 +87,8 @@ Nothing. The effect is owned by the surrounding scope and disposed with it. const [count, setCount] = createSignal(0); createEffect( - () => count(), // compute: tracks `count` - value => console.log(value) // effect: side effect + () => count(), // compute: tracks `count` + (value) => console.log(value) // effect: side effect ); setCount(1); // logs 1 after the next flush @@ -96,12 +96,12 @@ setCount(1); // logs 1 after the next flush ```ts createEffect( - () => userId(), - id => { - const ctrl = new AbortController(); - fetch(`/users/${id}`, { signal: ctrl.signal }); - return () => ctrl.abort(); // cleanup before next run / disposal - } + () => userId(), + (id) => { + const ctrl = new AbortController(); + fetch(`/users/${id}`, { signal: ctrl.signal }); + return () => ctrl.abort(); // cleanup before next run / disposal + } ); ``` @@ -140,7 +140,7 @@ server never created. ```ts type ComputeFunction = ( - v: Prev + v: Prev ) => PromiseLike | AsyncIterable | Next; ``` @@ -148,8 +148,8 @@ type ComputeFunction = ( ```ts type EffectBundle = { - effect: EffectFunction; - error: (err: unknown, cleanup: () => void) => void; + effect: EffectFunction; + error: (err: unknown, cleanup: () => void) => void; }; ``` @@ -175,8 +175,8 @@ outcomes — an error that recovers before the effect phase runs the ```ts type EffectFunction = ( - v: Next, - p?: Prev + v: Next, + p?: Prev ) => (() => void) | void; ``` @@ -186,13 +186,13 @@ Options for effect primitives that support deferring/scheduling their initial ru ```ts interface EffectOptions extends BaseEffectOptions { - defer?: boolean; - schedule?: boolean; - sync?: boolean; - transparent?: boolean; - deferStream?: boolean; - ssrSource?: "server" | "hybrid" | "client"; -}; + defer?: boolean; + schedule?: boolean; + sync?: boolean; + transparent?: boolean; + deferStream?: boolean; + ssrSource?: "server" | "hybrid" | "client"; +} ``` #### `defer` @@ -265,7 +265,7 @@ its fallback into the HTML. Server-only; ignored on the client. Hydration policy. Decides what initial value the client uses and whether the compute re-runs. -- `"server"` *(default)*: client uses the serialized server value +- `"server"` _(default)_: client uses the serialized server value as initial state. Compute does **not** re-run for the initial value — the serialized result is authoritative. Choose this when the compute is deterministic from server-available inputs. diff --git a/src/routes/reference/(1)solid-js/(1)reactivity/create-memo.mdx b/src/routes/reference/(1)solid-js/(1)reactivity/create-memo.mdx index eec89a65f..f7b3b8dce 100644 --- a/src/routes/reference/(1)solid-js/(1)reactivity/create-memo.mdx +++ b/src/routes/reference/(1)solid-js/(1)reactivity/create-memo.mdx @@ -39,12 +39,12 @@ import { createMemo } from "solid-js"; ```ts function createMemo( - compute: ComputeFunction, T>, - options: MemoOptions & { loadingValue: T } + compute: ComputeFunction, T>, + options: MemoOptions & { loadingValue: T } ): SourceAccessor; function createMemo( - compute: ComputeFunction, T>, - options?: MemoOptions + compute: ComputeFunction, T>, + options?: MemoOptions ): SourceAccessor; ``` @@ -81,8 +81,8 @@ fullName(); // "Ada Lovelace" ```ts // Async memo — reads suspend inside const user = createMemo(async () => { - const res = await fetch(`/users/${id()}`); - return res.json(); + const res = await fetch(`/users/${id()}`); + return res.json(); }); ``` @@ -127,17 +127,17 @@ Also used in combination with `SignalOptions` for writable memos ```ts interface MemoOptions { - id?: string; - name?: string; - transparent?: boolean; - equals?: false | ((prev: T, next: T) => boolean); - unobserved?: () => void; - lazy?: boolean; - sync?: boolean; - loadingValue?: T; - deferStream?: boolean; - ssrSource?: "server" | "hybrid" | "client"; -}; + id?: string; + name?: string; + transparent?: boolean; + equals?: false | ((prev: T, next: T) => boolean); + unobserved?: () => void; + lazy?: boolean; + sync?: boolean; + loadingValue?: T; + deferStream?: boolean; + ssrSource?: "server" | "hybrid" | "client"; +} ``` **`id`** — `string` @@ -223,7 +223,7 @@ its fallback into the HTML. Server-only; ignored on the client. Hydration policy. Decides what initial value the client uses and whether the compute re-runs. -- `"server"` *(default)*: client uses the serialized server value +- `"server"` _(default)_: client uses the serialized server value as initial state. Compute does **not** re-run for the initial value — the serialized result is authoritative. Choose this when the compute is deterministic from server-available inputs. @@ -242,7 +242,7 @@ whether the compute re-runs. sources (`loadingValue: undefined` is a valid declaration), `seedLoadingValue: true` on store-family sources — which renders provisional data with no boundary involvement. -::: + ::: ### `SignalOptions` @@ -251,13 +251,13 @@ Options for plain signals created with `createSignal(value)` or `createOptimisti ```ts interface SignalOptions { - name?: string; - equals?: false | ((prev: T, next: T) => boolean); - ownedWrite?: boolean; - unobserved?: () => void; - deferStream?: boolean; - ssrSource?: "server" | "hybrid" | "client"; -}; + name?: string; + equals?: false | ((prev: T, next: T) => boolean); + ownedWrite?: boolean; + unobserved?: () => void; + deferStream?: boolean; + ssrSource?: "server" | "hybrid" | "client"; +} ``` **`name`** — `string` @@ -291,7 +291,7 @@ its fallback into the HTML. Server-only; ignored on the client. Hydration policy. Decides what initial value the client uses and whether the compute re-runs. -- `"server"` *(default)*: client uses the serialized server value +- `"server"` _(default)_: client uses the serialized server value as initial state. Compute does **not** re-run for the initial value — the serialized result is authoritative. Choose this when the compute is deterministic from server-available inputs. @@ -310,4 +310,4 @@ whether the compute re-runs. sources (`loadingValue: undefined` is a valid declaration), `seedLoadingValue: true` on store-family sources — which renders provisional data with no boundary involvement. -::: + ::: diff --git a/src/routes/reference/(1)solid-js/(1)reactivity/create-optimistic.mdx b/src/routes/reference/(1)solid-js/(1)reactivity/create-optimistic.mdx index 5b60a0486..8633a56d0 100644 --- a/src/routes/reference/(1)solid-js/(1)reactivity/create-optimistic.mdx +++ b/src/routes/reference/(1)solid-js/(1)reactivity/create-optimistic.mdx @@ -41,14 +41,17 @@ import { createOptimistic } from "solid-js"; ```ts function createOptimistic(): Signal; -function createOptimistic(value: Exclude, options?: SignalOptions): Signal; function createOptimistic( - fn: ComputeFunction, T>, - options: SignalOptions & MemoOptions & { loadingValue: T } + value: Exclude, + options?: SignalOptions ): Signal; function createOptimistic( - fn: ComputeFunction, T>, - options?: SignalOptions & MemoOptions + fn: ComputeFunction, T>, + options: SignalOptions & MemoOptions & { loadingValue: T } +): Signal; +function createOptimistic( + fn: ComputeFunction, T>, + options?: SignalOptions & MemoOptions ): Signal; ``` @@ -85,8 +88,8 @@ A tuple with the same shape as `createSignal`. Writes made inside an action are const [name, setName] = createOptimistic("Ada"); const rename = action(function* (next: string) { - setName(next); // optimistic - yield api.rename(next); // commits or reverts on settle + setName(next); // optimistic + yield api.rename(next); // commits or reverts on settle }); ``` diff --git a/src/routes/reference/(1)solid-js/(1)reactivity/create-signal.mdx b/src/routes/reference/(1)solid-js/(1)reactivity/create-signal.mdx index 83999ece9..ad88f1273 100644 --- a/src/routes/reference/(1)solid-js/(1)reactivity/create-signal.mdx +++ b/src/routes/reference/(1)solid-js/(1)reactivity/create-signal.mdx @@ -33,9 +33,9 @@ Creates a simple reactive state with a getter and setter. // Plain const [count, setCount] = createSignal(0); -count(); // 0 -setCount(1); // explicit value -setCount(c => c + 1); // updater +count(); // 0 +setCount(1); // explicit value +setCount((c) => c + 1); // updater // Writable memo: starts as `fn()`, can be locally overwritten. const [user, setUser] = createSignal(() => fetchUser(userId())); @@ -56,14 +56,17 @@ import { createSignal } from "solid-js"; ```ts function createSignal(): Signal; -function createSignal(value: Exclude, options?: SignalOptions): Signal; function createSignal( - fn: ComputeFunction, T>, - options: SignalOptions & MemoOptions & { loadingValue: T } + value: Exclude, + options?: SignalOptions ): Signal; function createSignal( - fn: ComputeFunction, T>, - options?: SignalOptions & MemoOptions + fn: ComputeFunction, T>, + options: SignalOptions & MemoOptions & { loadingValue: T } +): Signal; +function createSignal( + fn: ComputeFunction, T>, + options?: SignalOptions & MemoOptions ): Signal; ``` @@ -99,9 +102,9 @@ A tuple. The accessor reads the value and tracks it in the surrounding scope; th ```ts const [count, setCount] = createSignal(0); -count(); // 0 -setCount(1); // explicit value -setCount(c => c + 1); // updater +count(); // 0 +setCount(1); // explicit value +setCount((c) => c + 1); // updater ``` ```ts @@ -147,17 +150,17 @@ Also used in combination with `SignalOptions` for writable memos ```ts interface MemoOptions { - id?: string; - name?: string; - transparent?: boolean; - equals?: false | ((prev: T, next: T) => boolean); - unobserved?: () => void; - lazy?: boolean; - sync?: boolean; - loadingValue?: T; - deferStream?: boolean; - ssrSource?: "server" | "hybrid" | "client"; -}; + id?: string; + name?: string; + transparent?: boolean; + equals?: false | ((prev: T, next: T) => boolean); + unobserved?: () => void; + lazy?: boolean; + sync?: boolean; + loadingValue?: T; + deferStream?: boolean; + ssrSource?: "server" | "hybrid" | "client"; +} ``` **`id`** — `string` @@ -243,7 +246,7 @@ its fallback into the HTML. Server-only; ignored on the client. Hydration policy. Decides what initial value the client uses and whether the compute re-runs. -- `"server"` *(default)*: client uses the serialized server value +- `"server"` _(default)_: client uses the serialized server value as initial state. Compute does **not** re-run for the initial value — the serialized result is authoritative. Choose this when the compute is deterministic from server-available inputs. @@ -262,7 +265,7 @@ whether the compute re-runs. sources (`loadingValue: undefined` is a valid declaration), `seedLoadingValue: true` on store-family sources — which renders provisional data with no boundary involvement. -::: + ::: ### `SignalOptions` @@ -271,13 +274,13 @@ Options for plain signals created with `createSignal(value)` or `createOptimisti ```ts interface SignalOptions { - name?: string; - equals?: false | ((prev: T, next: T) => boolean); - ownedWrite?: boolean; - unobserved?: () => void; - deferStream?: boolean; - ssrSource?: "server" | "hybrid" | "client"; -}; + name?: string; + equals?: false | ((prev: T, next: T) => boolean); + ownedWrite?: boolean; + unobserved?: () => void; + deferStream?: boolean; + ssrSource?: "server" | "hybrid" | "client"; +} ``` **`name`** — `string` @@ -311,7 +314,7 @@ its fallback into the HTML. Server-only; ignored on the client. Hydration policy. Decides what initial value the client uses and whether the compute re-runs. -- `"server"` *(default)*: client uses the serialized server value +- `"server"` _(default)_: client uses the serialized server value as initial state. Compute does **not** re-run for the initial value — the serialized result is authoritative. Choose this when the compute is deterministic from server-available inputs. @@ -330,4 +333,4 @@ whether the compute re-runs. sources (`loadingValue: undefined` is a valid declaration), `seedLoadingValue: true` on store-family sources — which renders provisional data with no boundary involvement. -::: + ::: diff --git a/src/routes/reference/(1)solid-js/(1)reactivity/flush.mdx b/src/routes/reference/(1)solid-js/(1)reactivity/flush.mdx index 3859067af..41c965c67 100644 --- a/src/routes/reference/(1)solid-js/(1)reactivity/flush.mdx +++ b/src/routes/reference/(1)solid-js/(1)reactivity/flush.mdx @@ -22,7 +22,7 @@ flush scope before draining the queue. Reactive updates are normally batched onto the microtask queue, so multiple writes in a row collapse into a single update pass. Call `flush()` when you -need to *observe* the result of those writes synchronously — most commonly +need to _observe_ the result of those writes synchronously — most commonly in tests, but also at the boundary of imperative integration code. Pass a callback when the writes themselves should bypass microtask scheduling and drain synchronously when the callback returns. @@ -67,9 +67,9 @@ expect(doubled()).toBe(12); // Nested flushes drain at each level: flush(() => { - setCount(7); - flush(() => setCount(8)); // inner drain — effects fire here - // outer continues with up-to-date state + setCount(7); + flush(() => setCount(8)); // inner drain — effects fire here + // outer continues with up-to-date state }); ``` diff --git a/src/routes/reference/(1)solid-js/(1)reactivity/is-pending.mdx b/src/routes/reference/(1)solid-js/(1)reactivity/is-pending.mdx index 24b296862..e170e90e6 100644 --- a/src/routes/reference/(1)solid-js/(1)reactivity/is-pending.mdx +++ b/src/routes/reference/(1)solid-js/(1)reactivity/is-pending.mdx @@ -54,7 +54,7 @@ const results = createMemo(() => searchProducts(query()));
    {(product) =>
  • {product.name}
  • }
    -
+; ``` ## Caveats diff --git a/src/routes/reference/(1)solid-js/(1)reactivity/untrack.mdx b/src/routes/reference/(1)solid-js/(1)reactivity/untrack.mdx index 84f76ed55..36738e69f 100644 --- a/src/routes/reference/(1)solid-js/(1)reactivity/untrack.mdx +++ b/src/routes/reference/(1)solid-js/(1)reactivity/untrack.mdx @@ -62,11 +62,11 @@ The value `fn` returns. ```ts createEffect( - () => trigger(), // tracks `trigger` only - () => { - const snapshot = untrack(() => state); // read once, untracked - log(snapshot); - } + () => trigger(), // tracks `trigger` only + () => { + const snapshot = untrack(() => state); // read once, untracked + log(snapshot); + } ); ``` diff --git a/src/routes/reference/(1)solid-js/(2)stores/create-optimistic-store.mdx b/src/routes/reference/(1)solid-js/(2)stores/create-optimistic-store.mdx index 06ba53043..f667a975d 100644 --- a/src/routes/reference/(1)solid-js/(2)stores/create-optimistic-store.mdx +++ b/src/routes/reference/(1)solid-js/(2)stores/create-optimistic-store.mdx @@ -46,13 +46,13 @@ import { createOptimisticStore } from "solid-js"; ```ts function createOptimisticStore( - initialValue: T | Store, - options?: StoreOptions + initialValue: T | Store, + options?: StoreOptions ): [get: Store, set: StoreSetter]; function createOptimisticStore( - fn: (draft: T) => void | T | Promise | AsyncIterable, - seed: Partial | Store, - options?: ProjectionOptions + fn: (draft: T) => void | T | Promise | AsyncIterable, + seed: Partial | Store, + options?: ProjectionOptions ): [get: Store, set: StoreSetter]; ``` @@ -96,19 +96,21 @@ const [todos, setTodos] = createOptimisticStore([]); // Mutation: optimistic add, then in-place reconcile to the saved row. const addTodo = action(function* (text: string) { - const tempId = crypto.randomUUID(); - setTodos(t => { t.push({ id: tempId, text, pending: true }); }); - const saved = yield api.createTodo(text); - setTodos(t => { - const i = t.findIndex(x => x.id === tempId); - if (i >= 0) t[i] = saved; - }); + const tempId = crypto.randomUUID(); + setTodos((t) => { + t.push({ id: tempId, text, pending: true }); + }); + const saved = yield api.createTodo(text); + setTodos((t) => { + const i = t.findIndex((x) => x.id === tempId); + if (i >= 0) t[i] = saved; + }); }); // Return form: filter is the natural shape for removal. const removeTodo = action(function* (id: string) { - setTodos(t => t.filter(x => x.id !== id)); - yield api.removeTodo(id); + setTodos((t) => t.filter((x) => x.id !== id)); + yield api.removeTodo(id); }); ``` diff --git a/src/routes/reference/(1)solid-js/(2)stores/create-projection.mdx b/src/routes/reference/(1)solid-js/(2)stores/create-projection.mdx index df53937ec..2803cd15e 100644 --- a/src/routes/reference/(1)solid-js/(2)stores/create-projection.mdx +++ b/src/routes/reference/(1)solid-js/(2)stores/create-projection.mdx @@ -41,9 +41,9 @@ import { createProjection } from "solid-js"; ```ts function createProjection( - fn: (draft: T) => void | T | Promise | AsyncIterable, - seed: Partial | Store, - options?: ProjectionOptions + fn: (draft: T) => void | T | Promise | AsyncIterable, + seed: Partial | Store, + options?: ProjectionOptions ): Store; ``` @@ -77,18 +77,18 @@ The projected store. There is no setter; write through the derive function's inp ```ts // Mutation form — update individual fields on the draft. const summary = createProjection<{ total: number; active: number }>( - draft => { - draft.total = users().length; - draft.active = users().filter(u => u.active).length; - }, - { total: 0, active: 0 } + (draft) => { + draft.total = users().length; + draft.active = users().filter((u) => u.active).length; + }, + { total: 0, active: 0 } ); // Return form — produce a derived collection. Reconciled by `id` // so each surviving user keeps the same store identity. const activeUsers = createProjection( - () => allUsers().filter(u => u.active), - [] + () => allUsers().filter((u) => u.active), + [] ); ``` @@ -121,11 +121,11 @@ or `createOptimisticStore(fn, seed, options?)`. ```ts interface ProjectionOptions extends StoreOptions { - key?: string | ((item: NonNullable) => any) | null; - seedLoadingValue?: boolean; - deferStream?: boolean; - ssrSource?: "server" | "hybrid" | "client"; -}; + key?: string | ((item: NonNullable) => any) | null; + seedLoadingValue?: boolean; + deferStream?: boolean; + ssrSource?: "server" | "hybrid" | "client"; +} ``` #### `key` @@ -166,7 +166,7 @@ its fallback into the HTML. Server-only; ignored on the client. Hydration policy. Decides what initial value the client uses and whether the compute re-runs. -- `"server"` *(default)*: client uses the serialized server value +- `"server"` _(default)_: client uses the serialized server value as initial state. Compute does **not** re-run for the initial value — the serialized result is authoritative. Choose this when the compute is deterministic from server-available inputs. diff --git a/src/routes/reference/(1)solid-js/(2)stores/create-store.mdx b/src/routes/reference/(1)solid-js/(2)stores/create-store.mdx index ea09bd8ff..814649f7a 100644 --- a/src/routes/reference/(1)solid-js/(2)stores/create-store.mdx +++ b/src/routes/reference/(1)solid-js/(2)stores/create-store.mdx @@ -23,7 +23,7 @@ property accessed; only the parts that change trigger updates. Store properties hold **plain values**, not accessors. The proxy already tracks reads per-property — wrapping a value in -`() => state.foo` produces a getter that *won't* track when called, +`() => state.foo` produces a getter that _won't_ track when called, which looks like a reactivity bug but is a category error. If you have a signal-shaped piece of state, make it a property of the store (`{ foo: 1 }`) rather than nesting an accessor inside @@ -41,7 +41,7 @@ that, use the derived/projection form (or `createProjection`). - **Plain form** — `createStore(initialValue, options?)`: wraps a value in a reactive proxy. - **Derived form** — `createStore(fn, seed, options?)`: a - *projection store* whose contents are computed by `fn(draft)`. + _projection store_ whose contents are computed by `fn(draft)`. `fn` may be sync, async, or an `AsyncIterable`; the projection's result reconciles against the existing store by `options.key` (default `"id"`) for stable identity. @@ -56,13 +56,13 @@ import { createStore } from "solid-js"; ```ts function createStore( - initialValue: T | Store, - options?: StoreOptions + initialValue: T | Store, + options?: StoreOptions ): [get: Store, set: StoreSetter]; function createStore( - fn: (draft: T) => void | T | Promise | AsyncIterable, - seed: Partial | Store, - options?: ProjectionOptions + fn: (draft: T) => void | T | Promise | AsyncIterable, + seed: Partial | Store, + options?: ProjectionOptions ): [get: Store, set: StoreSetter]; ``` @@ -103,24 +103,28 @@ A tuple. The store is a read-only proxy that tracks each property you read; the ```ts const [state, setState] = createStore({ - user: { name: "Ada", age: 36 }, - todos: [] as { id: string; text: string; done: boolean }[] + user: { name: "Ada", age: 36 }, + todos: [] as { id: string; text: string; done: boolean }[], }); // Canonical: mutate the draft in place. -setState(s => { s.user.age = 37; }); -setState(s => { s.todos.push({ id: "1", text: "x", done: false }); }); +setState((s) => { + s.user.age = 37; +}); +setState((s) => { + s.todos.push({ id: "1", text: "x", done: false }); +}); // Return form: reach for it when mutation is awkward. -setState(s => s.todos.filter(t => !t.done)); // remove items -setState(s => ({ ...s, user: { name: "Grace", age: 85 } })); // shallow replace +setState((s) => s.todos.filter((t) => !t.done)); // remove items +setState((s) => ({ ...s, user: { name: "Grace", age: 85 } })); // shallow replace ``` ```ts // Derived store — auto-fetches & reconciles by `id`. const [users] = createStore( - async () => fetch("/users").then(r => r.json()), - [] as User[] + async () => fetch("/users").then((r) => r.json()), + [] as User[] ); ``` @@ -158,11 +162,11 @@ or `createOptimisticStore(fn, seed, options?)`. ```ts interface ProjectionOptions extends StoreOptions { - key?: string | ((item: NonNullable) => any) | null; - seedLoadingValue?: boolean; - deferStream?: boolean; - ssrSource?: "server" | "hybrid" | "client"; -}; + key?: string | ((item: NonNullable) => any) | null; + seedLoadingValue?: boolean; + deferStream?: boolean; + ssrSource?: "server" | "hybrid" | "client"; +} ``` #### `key` @@ -203,7 +207,7 @@ its fallback into the HTML. Server-only; ignored on the client. Hydration policy. Decides what initial value the client uses and whether the compute re-runs. -- `"server"` *(default)*: client uses the serialized server value +- `"server"` _(default)_: client uses the serialized server value as initial state. Compute does **not** re-run for the initial value — the serialized result is authoritative. Choose this when the compute is deterministic from server-available inputs. @@ -237,9 +241,9 @@ Options shared by all store primitives. ```ts interface StoreOptions { - name?: string; - shallow?: boolean; -}; + name?: string; + shallow?: boolean; +} ``` #### `name` diff --git a/src/routes/reference/(1)solid-js/(2)stores/merge.mdx b/src/routes/reference/(1)solid-js/(2)stores/merge.mdx index 072a2a631..cf885567a 100644 --- a/src/routes/reference/(1)solid-js/(2)stores/merge.mdx +++ b/src/routes/reference/(1)solid-js/(2)stores/merge.mdx @@ -17,8 +17,8 @@ source_path: "packages/signals/src/store/utils.ts" {/* Generated by scripts/extract-solid-ref.mjs. Edit the source JSDoc or disposition map, then regenerate. */} -Merges multiple props-like objects into a single proxy that *preserves -reactivity*. Reads are forwarded to the right-most source that defines the +Merges multiple props-like objects into a single proxy that _preserves +reactivity_. Reads are forwarded to the right-most source that defines the property, so later sources override earlier ones (like `Object.assign`). Function arguments are treated as memo-backed sources — useful for passing @@ -55,9 +55,13 @@ A reactive proxy over the merged sources. Property reads track the source that s ```tsx function Button(_props: { label: string; type?: string; disabled?: boolean }) { - const props = merge({ type: "button", disabled: false }, _props); + const props = merge({ type: "button", disabled: false }, _props); - return ; + return ( + + ); } ``` diff --git a/src/routes/reference/(1)solid-js/(2)stores/omit.mdx b/src/routes/reference/(1)solid-js/(2)stores/omit.mdx index 81b862d88..6d51d078b 100644 --- a/src/routes/reference/(1)solid-js/(2)stores/omit.mdx +++ b/src/routes/reference/(1)solid-js/(2)stores/omit.mdx @@ -33,8 +33,8 @@ import { omit } from "solid-js"; ```ts function omit, K extends readonly (keyof T)[]>( - props: T, - ...keys: K + props: T, + ...keys: K ): Omit; ``` @@ -59,19 +59,25 @@ A reactive proxy of `props` without the listed keys. ## Examples ```tsx -function Input(props: { label: string; value: string; onInput: (v: string) => void } & JSX.HTMLAttributes) { - const rest = omit(props, "label", "value", "onInput"); - - return ( - - ); +function Input( + props: { + label: string; + value: string; + onInput: (v: string) => void; + } & JSX.HTMLAttributes +) { + const rest = omit(props, "label", "value", "onInput"); + + return ( + + ); } ``` @@ -96,6 +102,6 @@ function Input(props: { label: string; value: string; onInput: (v: string) => vo ```ts type Omit = { - [P in keyof T as Exclude]: T[P]; + [P in keyof T as Exclude]: T[P]; }; ``` diff --git a/src/routes/reference/(1)solid-js/(2)stores/reconcile.mdx b/src/routes/reference/(1)solid-js/(2)stores/reconcile.mdx index 731972606..63d795115 100644 --- a/src/routes/reference/(1)solid-js/(2)stores/reconcile.mdx +++ b/src/routes/reference/(1)solid-js/(2)stores/reconcile.mdx @@ -29,8 +29,8 @@ import { reconcile } from "solid-js"; ```ts function reconcile( - value: T, - key: string | ((item: NonNullable) => any) | null = "id" + value: T, + key: string | ((item: NonNullable) => any) | null = "id" ): (state: U) => T; ``` diff --git a/src/routes/reference/(1)solid-js/(3)lifecycle-actions/action.mdx b/src/routes/reference/(1)solid-js/(3)lifecycle-actions/action.mdx index bcfbdc357..9d543d4eb 100644 --- a/src/routes/reference/(1)solid-js/(3)lifecycle-actions/action.mdx +++ b/src/routes/reference/(1)solid-js/(3)lifecycle-actions/action.mdx @@ -18,8 +18,8 @@ source_path: "packages/signals/src/core/action.ts" {/* Generated by scripts/extract-solid-ref.mjs. Edit the source JSDoc or disposition map, then regenerate. */} -The primitive for mutations: imperative async workflows whose *writes span -an async gap* — optimistic write, server round-trip, reconciling write — +The primitive for mutations: imperative async workflows whose _writes span +an async gap_ — optimistic write, server round-trip, reconciling write — where intermediate state must not leak and failure must revert cleanly (pair with `createOptimistic` / `createOptimisticStore`). @@ -27,7 +27,7 @@ Navigation-shaped updates do not need an action. A plain setter call is enough: reads pull the async, and downstream async computeds hold their previous values per-node until the new ones are ready (`isPending` / `latest` expose the in-flight state). Reach for `action` only when writes -happen *after* async work, not merely upstream of it. +happen _after_ async work, not merely upstream of it. Framework-level actions (router form actions, server actions) are specializations of this primitive: they are actions in exactly this sense — @@ -35,7 +35,7 @@ the same transactional semantics — with form binding, serialization, and submission tracking layered on top. The shared name is deliberate. Wraps a generator function so each invocation runs as a single transaction - that batches every signal/store write between yields. The +that batches every signal/store write between yields. The surrounding UI sees one atomic update per yielded step; nothing is committed until the action either completes or the next `yield` resolves. @@ -71,7 +71,7 @@ import { action } from "solid-js"; ```ts function action( - genFn: (...args: Args) => Generator | AsyncGenerator + genFn: (...args: Args) => Generator | AsyncGenerator ): (...args: Args) => Promise; ``` @@ -93,15 +93,17 @@ A function with the generator's parameters that returns a promise for its return const [todos, setTodos] = createOptimisticStore([]); const addTodo = action(async function* (text: string) { - const tempId = crypto.randomUUID(); - setTodos(t => { t.push({ id: tempId, text, pending: true }); }); // optimistic - const saved = await api.createTodo(text); // network round-trip, typed - yield; // re-enter the transaction - setTodos(t => { - const i = t.findIndex(x => x.id === tempId); - if (i >= 0) t[i] = saved; - }); - return saved; + const tempId = crypto.randomUUID(); + setTodos((t) => { + t.push({ id: tempId, text, pending: true }); + }); // optimistic + const saved = await api.createTodo(text); // network round-trip, typed + yield; // re-enter the transaction + setTodos((t) => { + const i = t.findIndex((x) => x.id === tempId); + if (i >= 0) t[i] = saved; + }); + return saved; }); await addTodo("buy milk"); diff --git a/src/routes/reference/(1)solid-js/(3)lifecycle-actions/affects.mdx b/src/routes/reference/(1)solid-js/(3)lifecycle-actions/affects.mdx index a4dc46cc4..3db37a7d6 100644 --- a/src/routes/reference/(1)solid-js/(3)lifecycle-actions/affects.mdx +++ b/src/routes/reference/(1)solid-js/(3)lifecycle-actions/affects.mdx @@ -51,15 +51,17 @@ When `target` is a store, the property to mark instead of the whole store. ```ts const send = action(function* (text: string) { - setState(s => { s.messages.push({ text, status: "sending" }); }); - affects(state.messages.at(-1)!, "status"); // this slot pends until settle - yield api.send(text); + setState((s) => { + s.messages.push({ text, status: "sending" }); + }); + affects(state.messages.at(-1)!, "status"); // this slot pends until settle + yield api.send(text); }); const reload = action(function* () { - affects(thing); // the whole store pends… - refresh(thing); // …over this otherwise-quiet re-ask - yield api.done(); + affects(thing); // the whole store pends… + refresh(thing); // …over this otherwise-quiet re-ask + yield api.done(); }); ``` diff --git a/src/routes/reference/(1)solid-js/(3)lifecycle-actions/on-settled.mdx b/src/routes/reference/(1)solid-js/(3)lifecycle-actions/on-settled.mdx index b526d154a..4acc801ba 100644 --- a/src/routes/reference/(1)solid-js/(3)lifecycle-actions/on-settled.mdx +++ b/src/routes/reference/(1)solid-js/(3)lifecycle-actions/on-settled.mdx @@ -26,7 +26,7 @@ does not create an ongoing subscription. The canonical lifecycle primitive in 2.0. Three main usages: -- **Component-level setup-and-teardown** *(the most common shape)*: run +- **Component-level setup-and-teardown** _(the most common shape)_: run setup after the component's first stable render and **return a cleanup function** to dispose it on owner disposal. This is the replacement for the 1.x `onMount` + `onCleanup` pairing — setup and teardown live in one @@ -36,7 +36,7 @@ The canonical lifecycle primitive in 2.0. Three main usages: render — analytics ping, focus, scroll-into-view, etc. No cleanup needed. - **Inside an event handler:** schedule work to run after the action or held update triggered by the event has completed. -Reactive reads inside the callback are *not* tracked — to react to +Reactive reads inside the callback are _not_ tracked — to react to subsequent settles, register a new `onSettled` each time. The callback runs during the settle flush itself, which gives it the same @@ -56,7 +56,7 @@ write semantics as every other effect-phase scope (the effect half of function instead. The returned cleanup runs on owner disposal. A cleanup return is only honored when `onSettled` is called from an **owned** -scope (e.g. a component body). When it fires out of band from an *unowned* +scope (e.g. a component body). When it fires out of band from an _unowned_ scope — an event handler, a tracked effect, or another `onSettled` — there is no owner lifecycle to bind a cleanup to; returning one is a dev-mode error (and is dropped in production). Use the post-settle/event-handler forms below @@ -89,42 +89,46 @@ on owner disposal // Component-level setup + teardown — replaces onMount + onCleanup. // Subscribe to an external source on mount, unsubscribe on dispose. function useViewportWidth() { - const [width, setWidth] = createSignal(window.innerWidth); - onSettled(() => { - const onResize = () => setWidth(window.innerWidth); - window.addEventListener("resize", onResize); - return () => window.removeEventListener("resize", onResize); - }); - return width; + const [width, setWidth] = createSignal(window.innerWidth); + onSettled(() => { + const onResize = () => setWidth(window.innerWidth); + window.addEventListener("resize", onResize); + return () => window.removeEventListener("resize", onResize); + }); + return width; } ``` ```tsx // Post-settle "ready" hook — no cleanup needed. function Dashboard() { - const data = createMemo(async () => fetchData()); + const data = createMemo(async () => fetchData()); - onSettled(() => { - analytics.track("dashboard.ready"); - }); + onSettled(() => { + analytics.track("dashboard.ready"); + }); - return }>
{data()}
; + return ( + }> +
{data()}
+
+ ); } ``` ```tsx // Event-handler — runs after the action settles. function SaveButton() { - const save = action(function* () { - yield api.save(); - }); + const save = action(function* () { + yield api.save(); + }); - const handleClick = () => { - save(); - onSettled(() => toast("Saved!")); - }; + const handleClick = () => { + save(); + onSettled(() => toast("Saved!")); + }; - return ; + return ; } ``` diff --git a/src/routes/reference/(1)solid-js/(3)lifecycle-actions/refresh.mdx b/src/routes/reference/(1)solid-js/(3)lifecycle-actions/refresh.mdx index 7b25ac55d..c50a26bb6 100644 --- a/src/routes/reference/(1)solid-js/(3)lifecycle-actions/refresh.mdx +++ b/src/routes/reference/(1)solid-js/(3)lifecycle-actions/refresh.mdx @@ -30,6 +30,7 @@ The returned promise is safe to ignore (fire-and-forget refresh is unchanged, and a failed refetch will not surface an unhandled rejection). Awaiting it gives imperative flows the settle point without a reactive read: + - Accessor targets resolve with the settled value; store targets resolve with the store node passed (reads through it are fresh after the await). - A failed re-ask rejects with the error (inside an action's generator, @@ -56,7 +57,7 @@ import { refresh } from "solid-js"; ```ts function refresh( - target: Refreshable + target: Refreshable ): Promise infer V ? V : T>; ``` diff --git a/src/routes/reference/(1)solid-js/(3)lifecycle-actions/until.mdx b/src/routes/reference/(1)solid-js/(3)lifecycle-actions/until.mdx index 14ada7a8c..e1e8b0508 100644 --- a/src/routes/reference/(1)solid-js/(3)lifecycle-actions/until.mdx +++ b/src/routes/reference/(1)solid-js/(3)lifecycle-actions/until.mdx @@ -55,12 +55,16 @@ A promise that resolves with the first truthy result of `fn`, narrowed by `Truth ```ts const send = action(async function* (text: string) { - const clientId = crypto.randomUUID(); - setMessages(m => { m.push({ clientId, text, pending: true }); }); // optimistic - await socket.send({ clientId, text }); // fire-and-forget transport - // Hold until the live source echoes the write (authoritative view — - // the optimistic row above cannot satisfy this): - yield until(() => messages.some(m => m.clientId === clientId), { timeout: 10_000 }); + const clientId = crypto.randomUUID(); + setMessages((m) => { + m.push({ clientId, text, pending: true }); + }); // optimistic + await socket.send({ clientId, text }); // fire-and-forget transport + // Hold until the live source echoes the write (authoritative view — + // the optimistic row above cannot satisfy this): + yield until(() => messages.some((m) => m.clientId === clientId), { + timeout: 10_000, + }); }); ``` @@ -97,11 +101,11 @@ optimistic state reverts. ```ts class TimeoutError extends Error { - constructor(message = "Timed out waiting for condition") { - super(message); - this.name = "TimeoutError"; - } -}; + constructor(message = "Timed out waiting for condition") { + super(message); + this.name = "TimeoutError"; + } +} ``` ### `Truthy` @@ -116,9 +120,9 @@ type Truthy = Exclude; ```ts interface UntilOptions { - timeout?: number; - signal?: AbortSignal; -}; + timeout?: number; + signal?: AbortSignal; +} ``` #### `timeout` diff --git a/src/routes/reference/(1)solid-js/(4)components-context/children.mdx b/src/routes/reference/(1)solid-js/(4)components-context/children.mdx index c8ce4b5b4..0e8178d3e 100644 --- a/src/routes/reference/(1)solid-js/(4)components-context/children.mdx +++ b/src/routes/reference/(1)solid-js/(4)components-context/children.mdx @@ -50,8 +50,14 @@ An accessor of the resolved children, with `.toArray()` for iteration ```tsx function List(props: { children: Element }) { - const items = children(() => props.children); - return
    {items.toArray().map(item =>
  • {item}
  • )}
; + const items = children(() => props.children); + return ( +
    + {items.toArray().map((item) => ( +
  • {item}
  • + ))} +
+ ); } ``` @@ -74,7 +80,9 @@ function List(props: { children: Element }) { ### `ChildrenReturn` ```ts -type ChildrenReturn = Accessor & { toArray: () => ResolvedElement[] }; +type ChildrenReturn = Accessor & { + toArray: () => ResolvedElement[]; +}; ``` ### `ResolvedChildren` diff --git a/src/routes/reference/(1)solid-js/(4)components-context/create-context.mdx b/src/routes/reference/(1)solid-js/(4)components-context/create-context.mdx index dca4d5eaf..8006f0847 100644 --- a/src/routes/reference/(1)solid-js/(4)components-context/create-context.mdx +++ b/src/routes/reference/(1)solid-js/(4)components-context/create-context.mdx @@ -54,7 +54,10 @@ import { createContext } from "solid-js"; ## Type signature ```ts -function createContext(defaultValue?: T, options?: EffectOptions): Context; +function createContext( + defaultValue?: T, + options?: EffectOptions +): Context; ``` ## Parameters @@ -85,17 +88,17 @@ type TodosCtx = readonly [Store, TodoActions]; const TodosContext = createContext(); function App() { - return ( - - - - ); + return ( + + + + ); } function TodoList() { - const [todos, { addTodo }] = useContext(TodosContext); // typed as TodosCtx - // ... - return null; + const [todos, { addTodo }] = useContext(TodosContext); // typed as TodosCtx + // ... + return null; } ``` @@ -104,8 +107,8 @@ function TodoList() { const ThemeContext = createContext<"light" | "dark">("light"); function Button() { - const theme = useContext(ThemeContext); // "light" | "dark" - return ; + const theme = useContext(ThemeContext); // "light" | "dark" + return ; } ``` diff --git a/src/routes/reference/(1)solid-js/(4)components-context/create-unique-id.mdx b/src/routes/reference/(1)solid-js/(4)components-context/create-unique-id.mdx index dd131b9ea..09bcd5a87 100644 --- a/src/routes/reference/(1)solid-js/(4)components-context/create-unique-id.mdx +++ b/src/routes/reference/(1)solid-js/(4)components-context/create-unique-id.mdx @@ -44,13 +44,13 @@ A string id that matches between the server-rendered and hydrated trees. ```tsx function Field(props: { label: string }) { - const id = createUniqueId(); - return ( - <> - - - - ); + const id = createUniqueId(); + return ( + <> + + + + ); } ``` diff --git a/src/routes/reference/(1)solid-js/(4)components-context/lazy.mdx b/src/routes/reference/(1)solid-js/(4)components-context/lazy.mdx index 8a9849baf..f2f486fc1 100644 --- a/src/routes/reference/(1)solid-js/(4)components-context/lazy.mdx +++ b/src/routes/reference/(1)solid-js/(4)components-context/lazy.mdx @@ -33,14 +33,14 @@ import { lazy } from "solid-js"; ```ts function lazy, K extends keyof M & string>( - fn: () => Promise, - options: { export: K }, - moduleUrl?: string + fn: () => Promise, + options: { export: K }, + moduleUrl?: string ): M[K] & { preload: () => Promise; moduleUrl?: string }; function lazy>( - fn: () => Promise<{ default: T }>, - options?: { export?: string }, - moduleUrl?: string + fn: () => Promise<{ default: T }>, + options?: { export?: string }, + moduleUrl?: string ): T & { preload: () => Promise<{ default: T }>; moduleUrl?: string }; ``` @@ -77,15 +77,15 @@ const Profile = lazy(() => import("./Profile")); const About = lazy(() => import("./pages"), { export: "About" }); function App() { - return ( - }> - - - ); + return ( + }> + + + ); } // Preload before the user clicks - +; ``` ## Caveats diff --git a/src/routes/reference/(1)solid-js/(4)components-context/use-context.mdx b/src/routes/reference/(1)solid-js/(4)components-context/use-context.mdx index 51bda5c95..af8602430 100644 --- a/src/routes/reference/(1)solid-js/(4)components-context/use-context.mdx +++ b/src/routes/reference/(1)solid-js/(4)components-context/use-context.mdx @@ -61,9 +61,9 @@ default if one was supplied to `createContext` const TodosContext = createContext(); function TodoList() { - const [todos, { addTodo }] = useContext(TodosContext); // throws if no Provider - // ... - return null; + const [todos, { addTodo }] = useContext(TodosContext); // throws if no Provider + // ... + return null; } ``` @@ -83,12 +83,12 @@ function TodoList() { ```ts class ContextNotFoundError extends Error { - constructor() { - super( - __DEV__ - ? "Context must either be created with a default value or a value must be provided before accessing it." - : "" - ); - } -}; + constructor() { + super( + __DEV__ + ? "Context must either be created with a default value or a value must be provided before accessing it." + : "" + ); + } +} ``` diff --git a/src/routes/reference/(1)solid-js/(5)components-jsx/errored.mdx b/src/routes/reference/(1)solid-js/(5)components-jsx/errored.mdx index 17adb3f8f..f4edad008 100644 --- a/src/routes/reference/(1)solid-js/(5)components-jsx/errored.mdx +++ b/src/routes/reference/(1)solid-js/(5)components-jsx/errored.mdx @@ -35,8 +35,9 @@ import { Errored } from "solid-js"; ```ts function Errored(props: { - fallback: JSX.Element | ((err: ErrorAccessor, reset: () => void) => JSX.Element); - children: JSX.Element; + fallback: + JSX.Element | ((err: ErrorAccessor, reset: () => void) => JSX.Element); + children: JSX.Element; }): JSX.Element; ``` @@ -57,10 +58,12 @@ The subtree to guard. ## Examples ```tsx - ( -
Error: {err().toString()}
-)}> - + ( +
Error: {err().toString()}
+ )} +> +
``` diff --git a/src/routes/reference/(1)solid-js/(5)components-jsx/for.mdx b/src/routes/reference/(1)solid-js/(5)components-jsx/for.mdx index fbdbbdcdc..b8365151d 100644 --- a/src/routes/reference/(1)solid-js/(5)components-jsx/for.mdx +++ b/src/routes/reference/(1)solid-js/(5)components-jsx/for.mdx @@ -24,6 +24,7 @@ Receives a map function as its child and returns a JSX element for each list item; if the list is empty, an optional `fallback` is rendered instead. The child callback shape follows the keying mode: + - Default / `keyed={true}` receives `(item, index)` where `item` is the raw row value and `index` is an accessor. - `keyed={false}` receives `(item, index)` where `item` is an accessor and @@ -91,7 +92,7 @@ Row renderer. The argument shapes follow `keyed`; see above. ```tsx No items}> - {(item, index) =>
{item.label}
} + {(item, index) =>
{item.label}
}
``` diff --git a/src/routes/reference/(1)solid-js/(5)components-jsx/loading.mdx b/src/routes/reference/(1)solid-js/(5)components-jsx/loading.mdx index 69a7e41e7..370ae5e66 100644 --- a/src/routes/reference/(1)solid-js/(5)components-jsx/loading.mdx +++ b/src/routes/reference/(1)solid-js/(5)components-jsx/loading.mdx @@ -45,9 +45,9 @@ import { Loading } from "solid-js"; ```ts function Loading(props: { - fallback?: JSX.Element; - on?: any; - children: JSX.Element; + fallback?: JSX.Element; + on?: any; + children: JSX.Element; }): JSX.Element; ``` @@ -79,14 +79,14 @@ The subtree whose async reads this boundary handles. const Profile = lazy(() => import("./Profile")); }> - - + +
; ``` ```tsx // Only show the fallback for updates caused by writes to `route`. } on={route}> - + ``` diff --git a/src/routes/reference/(1)solid-js/(5)components-jsx/repeat.mdx b/src/routes/reference/(1)solid-js/(5)components-jsx/repeat.mdx index 1a6ef8ba7..09ff6b930 100644 --- a/src/routes/reference/(1)solid-js/(5)components-jsx/repeat.mdx +++ b/src/routes/reference/(1)solid-js/(5)components-jsx/repeat.mdx @@ -35,10 +35,10 @@ import { Repeat } from "solid-js"; ```ts function Repeat(props: { - count: number; - from?: number | undefined; - fallback?: JSX.Element; - children: ((index: number) => T) | T; + count: number; + from?: number | undefined; + fallback?: JSX.Element; + children: ((index: number) => T) | T; }): JSX.Element; ``` @@ -74,7 +74,7 @@ A function from index to content, or static content repeated per index. ```tsx No items}> - {(index) =>
{items[index]}
} + {(index) =>
{items[index]}
}
``` diff --git a/src/routes/reference/(1)solid-js/(5)components-jsx/reveal.mdx b/src/routes/reference/(1)solid-js/(5)components-jsx/reveal.mdx index 12f3780c4..2538d9da5 100644 --- a/src/routes/reference/(1)solid-js/(5)components-jsx/reveal.mdx +++ b/src/routes/reference/(1)solid-js/(5)components-jsx/reveal.mdx @@ -21,6 +21,7 @@ source_path: "packages/solid/src/client/flow.ts" Coordinates the reveal timing of sibling `` boundaries. The `order` prop picks the reveal policy: + - `"sequential"` (default) — boundaries reveal in registration order; later boundaries stay on their fallback until earlier ones resolve. - `"together"` — every direct slot stays on its fallback until the whole group is @@ -79,12 +80,20 @@ The `Loading` boundaries (or nested `Reveal` groups) to coordinate. // Default order is "sequential"; the inner group composes as one slot // and runs its own "natural" order locally once the outer releases it. - }> - - }> - }> - - }> + }> + + + + }> + + + }> + + + + }> + + ``` @@ -111,9 +120,9 @@ type RevealOrder = "sequential" | "together" | "natural"; ```ts type RevealProps = { - order?: RevealOrder; - collapsed?: boolean; - children: JSX.Element; + order?: RevealOrder; + collapsed?: boolean; + children: JSX.Element; }; ``` diff --git a/src/routes/reference/(1)solid-js/(5)components-jsx/show.mdx b/src/routes/reference/(1)solid-js/(5)components-jsx/show.mdx index c0e881a81..83a274d03 100644 --- a/src/routes/reference/(1)solid-js/(5)components-jsx/show.mdx +++ b/src/routes/reference/(1)solid-js/(5)components-jsx/show.mdx @@ -81,7 +81,7 @@ Static content, or a function that receives the narrowed value (an `Accessor}> - {u => } + {(u) => } ``` diff --git a/src/routes/reference/(1)solid-js/(5)components-jsx/switch-and-match.mdx b/src/routes/reference/(1)solid-js/(5)components-jsx/switch-and-match.mdx index c4bbb0bc8..2c13d554e 100644 --- a/src/routes/reference/(1)solid-js/(5)components-jsx/switch-and-match.mdx +++ b/src/routes/reference/(1)solid-js/(5)components-jsx/switch-and-match.mdx @@ -34,7 +34,10 @@ import { Switch, Match } from "solid-js"; ### Type signature ```ts -function Switch(props: { fallback?: JSX.Element; children: JSX.Element }): JSX.Element; +function Switch(props: { + fallback?: JSX.Element; + children: JSX.Element; +}): JSX.Element; ``` ### Props @@ -56,12 +59,12 @@ One or more `Match` elements. ```tsx }> - - - - - - + + + + + + ``` @@ -128,12 +131,10 @@ Static content, or a function that receives the narrowed value. ```tsx }> - - {u => } - - - - + {(u) => } + + + ``` @@ -153,25 +154,26 @@ Static content, or a function that receives the narrowed value. ```ts type AnyMatchProps = - | MatchProps - | KeyedMatchProps - | { - when: T | undefined | null | false; - keyed?: boolean; - children: JSX.Element; - }; + | MatchProps + | KeyedMatchProps + | { + when: T | undefined | null | false; + keyed?: boolean; + children: JSX.Element; + }; ``` ### `KeyedMatchProps` ```ts type KeyedMatchProps< - T, - F extends KeyedConditionalRenderCallback = KeyedConditionalRenderCallback + T, + F extends KeyedConditionalRenderCallback = + KeyedConditionalRenderCallback, > = { - when: T | undefined | null | false; - keyed: true; - children: KeyedConditionalRenderChildren; + when: T | undefined | null | false; + keyed: true; + children: KeyedConditionalRenderChildren; }; ``` @@ -190,10 +192,13 @@ type KeyedMatchProps< ### `MatchProps` ```ts -type MatchProps = ConditionalRenderCallback> = { - when: T | undefined | null | false; - keyed?: false; - children: ConditionalRenderChildren; +type MatchProps< + T, + F extends ConditionalRenderCallback = ConditionalRenderCallback, +> = { + when: T | undefined | null | false; + keyed?: false; + children: ConditionalRenderChildren; }; ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/create-root.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/create-root.mdx index 365c52ef5..a7fa9144a 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/create-root.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/create-root.mdx @@ -40,8 +40,8 @@ import { createRoot } from "solid-js"; ```ts function createRoot( - init: ((dispose: () => void) => T) | (() => T), - options?: { id?: string; transparent?: boolean } + init: ((dispose: () => void) => T) | (() => T), + options?: { id?: string; transparent?: boolean } ): T; ``` @@ -59,11 +59,14 @@ function createRoot( ## Examples ```ts -const dispose = createRoot(dispose => { - const [n, setN] = createSignal(0); - createEffect(() => n(), value => console.log(value)); - setInterval(() => setN(x => x + 1), 1000); - return dispose; +const dispose = createRoot((dispose) => { + const [n, setN] = createSignal(0); + createEffect( + () => n(), + (value) => console.log(value) + ); + setInterval(() => setN((x) => x + 1), 1000); + return dispose; }); // Later, to tear everything down: diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/get-observer.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/get-observer.mdx index 69a7fde0c..f5a104191 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/get-observer.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/get-observer.mdx @@ -44,7 +44,7 @@ function getObserver(): Owner | null; // Library predicate: only register a hot-path subscription when the // caller is inside a tracking scope (memo / effect compute / JSX). function trackIfTracked(source: () => unknown) { - if (getObserver()) source(); + if (getObserver()) source(); } ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/get-owner.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/get-owner.mdx index 6db1c24dc..9b249845c 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/get-owner.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/get-owner.mdx @@ -43,8 +43,8 @@ function getOwner(): Owner | null; ```ts function defer(fn: () => T) { - const owner = getOwner(); - queueMicrotask(() => runWithOwner(owner, fn)); + const owner = getOwner(); + queueMicrotask(() => runWithOwner(owner, fn)); } ``` @@ -60,8 +60,8 @@ function defer(fn: () => T) { ```ts class NoOwnerError extends Error { - constructor() { - super(__DEV__ ? "Context can only be accessed under a reactive root." : ""); - } -}; + constructor() { + super(__DEV__ ? "Context can only be accessed under a reactive root." : ""); + } +} ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/is-disposed.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/is-disposed.mdx index 44843eb2b..ea37f06a1 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/is-disposed.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/is-disposed.mdx @@ -44,11 +44,11 @@ function isDisposed(node: Owner): boolean; ```ts function onSettleSafe(fn: () => void) { - const owner = getOwner(); - queueMicrotask(() => { - if (owner && isDisposed(owner)) return; // component unmounted; skip - runWithOwner(owner, fn); - }); + const owner = getOwner(); + queueMicrotask(() => { + if (owner && isDisposed(owner)) return; // component unmounted; skip + runWithOwner(owner, fn); + }); } ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/run-with-owner.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/run-with-owner.mdx index e9cee6741..8aed75006 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/run-with-owner.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(1)owner-introspection/run-with-owner.mdx @@ -56,8 +56,8 @@ function runWithOwner(owner: Owner | null, fn: () => T): T; ```ts function delayed(ms: number, fn: () => T) { - const owner = getOwner(); - setTimeout(() => runWithOwner(owner, fn), ms); + const owner = getOwner(); + setTimeout(() => runWithOwner(owner, fn), ms); } ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-reaction.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-reaction.mdx index 0d1f1578a..b40c516da 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-reaction.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-reaction.mdx @@ -38,8 +38,8 @@ import { createReaction } from "solid-js"; ```ts function createReaction( - effectFn: EffectFunction | EffectBundle, - options?: EffectOptions + effectFn: EffectFunction | EffectBundle, + options?: EffectOptions ): (tracking: () => void) => void; ``` @@ -64,8 +64,8 @@ A function (or `EffectBundle`) that is called when tracked function is invalidat const [count, setCount] = createSignal(0); const track = createReaction(() => { - console.log("count changed once, re-arm to listen again"); - track(() => count()); // re-arm + console.log("count changed once, re-arm to listen again"); + track(() => count()); // re-arm }); track(() => count()); // initial arm diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-render-effect.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-render-effect.mdx index 28f726d9e..7c0b918d2 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-render-effect.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-render-effect.mdx @@ -51,9 +51,9 @@ import { createRenderEffect } from "solid-js"; ```ts function createRenderEffect( - compute: ComputeFunction, T>, - effectFn: EffectFunction, T>, - options?: EffectOptions + compute: ComputeFunction, T>, + effectFn: EffectFunction, T>, + options?: EffectOptions ): void; ``` @@ -85,10 +85,12 @@ A function that receives the new value and is used to perform side effects // synchronously during render. App code should use `createEffect` for // post-render side effects. function bindText(el: HTMLElement, source: () => string) { - createRenderEffect( - () => source(), - value => { el.textContent = value; } - ); + createRenderEffect( + () => source(), + (value) => { + el.textContent = value; + } + ); } ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-tracked-effect.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-tracked-effect.mdx index def20d34d..005de06a5 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-tracked-effect.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/create-tracked-effect.mdx @@ -26,14 +26,14 @@ Creates a tracked reactive effect where dependency tracking and side effects hap in the same scope. > Deprecated: Do not use in new code. For a side effect that follows reactive -state, use `createEffect(compute, effect)` — it separates tracking from the -side effect, knows its dependencies before it runs, and participates in -async and transitions. For one-time DOM work after render (measuring, -attaching third-party widgets to a ref), use `onSettled`. Tracking from -inside the effect phase — the only thing this primitive adds — is retained -solely to ease 1.x migration: it runs beside user-effect callbacks after -values commit, never holds a transition, and cannot observe a write staged -earlier in the same flush by a signal it has not read yet. +> state, use `createEffect(compute, effect)` — it separates tracking from the +> side effect, knows its dependencies before it runs, and participates in +> async and transitions. For one-time DOM work after render (measuring, +> attaching third-party widgets to a ref), use `onSettled`. Tracking from +> inside the effect phase — the only thing this primitive adds — is retained +> solely to ease 1.x migration: it runs beside user-effect callbacks after +> values commit, never holds a transition, and cannot observe a write staged +> earlier in the same flush by a signal it has not read yet. Because tracking and effects happen in the same scope, this primitive may run multiple times for a single change or show tearing (reading inconsistent @@ -59,8 +59,8 @@ import { createTrackedEffect } from "solid-js"; ```ts function createTrackedEffect( - compute: () => void | (() => void), - options?: BaseEffectOptions + compute: () => void | (() => void), + options?: BaseEffectOptions ): void; ``` @@ -83,13 +83,13 @@ A function that contains reactive reads to track and returns an optional cleanup ```ts createTrackedEffect(() => { - const target = focusedNode(); - if (!target) return; + const target = focusedNode(); + if (!target) return; - const handler = () => log(target.value()); - target.on("change", handler); + const handler = () => log(target.value()); + target.on("change", handler); - return () => target.off("change", handler); + return () => target.off("change", handler); }); ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/on-cleanup.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/on-cleanup.mdx index 355a8239b..795a05dcc 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/on-cleanup.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(2)specialized-reactivity/on-cleanup.mdx @@ -74,9 +74,12 @@ function onCleanup(fn: Disposable): Disposable; // from a factory that has no settle-phase setup of its own. `onSettled` // would queue a callback we don't need; `onCleanup` is the leaner // primitive when the only job is "register disposal on this owner". -function bindToOwner(owner: Owner, resource: T): T { - runWithOwner(owner, () => onCleanup(() => resource.dispose())); - return resource; +function bindToOwner( + owner: Owner, + resource: T +): T { + runWithOwner(owner, () => onCleanup(() => resource.dispose())); + return resource; } ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(3)store-advanced/is-wrappable.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(3)store-advanced/is-wrappable.mdx index 03bd65c88..4f12b3acf 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(3)store-advanced/is-wrappable.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(3)store-advanced/is-wrappable.mdx @@ -49,13 +49,13 @@ function isWrappable(obj: T | NotWrappable): obj is T; ```ts type NotWrappable = - | string - | number - | bigint - | symbol - | boolean - | Function - | null - | undefined - | SolidStore.Unwrappable[keyof SolidStore.Unwrappable]; + | string + | number + | bigint + | symbol + | boolean + | Function + | null + | undefined + | SolidStore.Unwrappable[keyof SolidStore.Unwrappable]; ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(3)store-advanced/store-path.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(3)store-advanced/store-path.mdx index d36f1a3a0..ea97fea8f 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(3)store-advanced/store-path.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(3)store-advanced/store-path.mdx @@ -87,13 +87,13 @@ const storePath: StorePath; const [state, setState] = createStore({ user: { name: "Ada" }, todos: [] }); setState(storePath("user", "name", "Grace")); -setState(storePath("todos", t => !t.done, "done", true)); // mark all undone as done +setState(storePath("todos", (t) => !t.done, "done", true)); // mark all undone as done setState(storePath("user", "nickname", storePath.DELETE)); ``` ```ts setState(storePath("user", "name", "Grace")); -setState(storePath("todos", todo => !todo.done, "done", true)); +setState(storePath("todos", (todo) => !todo.done, "done", true)); setState(storePath("user", "nickname", storePath.DELETE)); ``` @@ -113,29 +113,28 @@ type ArrayFilterFn = (item: T, index: number) => boolean; ```ts type CustomPartial = T extends readonly unknown[] - ? "0" extends keyof T - ? { [K in Extract]?: T[K] } - : { [x: number]: T[number] } - : Partial; + ? "0" extends keyof T + ? { [K in Extract]?: T[K] } + : { [x: number]: T[number] } + : Partial; ``` ### `Part` ```ts type Part = KeyOf> = - | K - | ([K] extends [never] ? never : readonly K[]) - | ([T] extends [readonly unknown[]] ? ArrayFilterFn | StorePathRange : never); + | K + | ([K] extends [never] ? never : readonly K[]) + | ([T] extends [readonly unknown[]] + ? ArrayFilterFn | StorePathRange + : never); ``` ### `PathSetter` ```ts type PathSetter = - | T - | CustomPartial - | ((prev: T) => T | CustomPartial) - | typeof DELETE; + T | CustomPartial | ((prev: T) => T | CustomPartial) | typeof DELETE; ``` ### `StorePathRange` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-error-boundary.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-error-boundary.mdx index 4c5a6216c..4aadd6dec 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-error-boundary.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-error-boundary.mdx @@ -40,8 +40,8 @@ import { createErrorBoundary } from "@solidjs/signals"; ```ts function createErrorBoundary( - fn: () => T, - fallback: (error: Accessor, reset: () => void) => U + fn: () => T, + fallback: (error: Accessor, reset: () => void) => U ): Accessor; ``` @@ -59,14 +59,17 @@ function createErrorBoundary( ```tsx // Custom boundary that wraps the primitive and adds telemetry. -function TracedErrored(props: { fallback: (e: () => unknown) => JSX.Element; children: JSX.Element }) { - return createErrorBoundary( - () => props.children, - (err, reset) => { - reportError(err()); - return props.fallback(err); - } - ) as unknown as JSX.Element; +function TracedErrored(props: { + fallback: (e: () => unknown) => JSX.Element; + children: JSX.Element; +}) { + return createErrorBoundary( + () => props.children, + (err, reset) => { + reportError(err()); + return props.fallback(err); + } + ) as unknown as JSX.Element; } ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-loading-boundary.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-loading-boundary.mdx index 763b7a078..8b95a79be 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-loading-boundary.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-loading-boundary.mdx @@ -38,9 +38,9 @@ import { createLoadingBoundary } from "@solidjs/signals"; ```ts function createLoadingBoundary( - fn: () => T, - fallback: () => U, - options?: { on?: () => any } + fn: () => T, + fallback: () => U, + options?: { on?: () => any } ): Accessor; ``` @@ -64,17 +64,17 @@ The fallback shown while async reads in `fn` are unresolved - Optional `on` — accessor whose value scopes the boundary; when set, -updates caused by writes to other reactive sources are *not* caught +updates caused by writes to other reactive sources are _not_ caught ## Examples ```tsx // Custom boundary component built on top of the primitive. function MyLoading(props: { fallback: JSX.Element; children: JSX.Element }) { - return createLoadingBoundary( - () => props.children, - () => props.fallback - ) as unknown as JSX.Element; + return createLoadingBoundary( + () => props.children, + () => props.fallback + ) as unknown as JSX.Element; } ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-reveal-order.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-reveal-order.mdx index 370b37e20..e23fcfc3a 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-reveal-order.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/create-reveal-order.mdx @@ -25,6 +25,7 @@ source_path: "packages/signals/src/boundaries.ts" Coordinate the reveal timing of sibling loading boundaries. Accepts reactive accessors: + - `order`: `"sequential"` (default) | `"together"` | `"natural"`. - `"sequential"` — classic frontier reveal: siblings reveal in registration order as each resolves; later siblings stay hidden until earlier ones complete. @@ -45,6 +46,7 @@ releases that slot. Once released, the inner controller runs its own order local over anything still pending. There is no opt-out from an outer hold. "Minimally ready" is what an order considers its first visible content: + - `sequential` — frontier-0 is minimally ready (leaf: on resolve; nested: via its own minimal signal). - `together` — every direct slot is minimally ready. @@ -61,8 +63,8 @@ import { createRevealOrder } from "@solidjs/signals"; ```ts function createRevealOrder( - fn: () => T, - options?: { order?: OrderAccessor; collapsed?: BoolAccessor } + fn: () => T, + options?: { order?: OrderAccessor; collapsed?: BoolAccessor } ): T; ``` @@ -83,10 +85,10 @@ function createRevealOrder( // Primitive form of `` — coordinate sibling loading boundaries // programmatically. App code uses the JSX `` component instead. // Both options are accessors so they can react to state changes. -createRevealOrder( - () => renderSiblings(), - { order: () => mode(), collapsed: () => true } -); +createRevealOrder(() => renderSiblings(), { + order: () => mode(), + collapsed: () => true, +}); ``` ## Learn more diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/map-array.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/map-array.mdx index 9fb282ae4..3d69d3c84 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/map-array.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/map-array.mdx @@ -25,6 +25,7 @@ Reactively maps an array, reusing the previously-mapped value for unchanged items. The callback shape follows the keying mode: + - Default / `keyed: true` receives `(item, index)` where `item` is the raw row value and `index` is an accessor. - `keyed: false` receives `(item, index)` where `item` is an accessor and @@ -51,19 +52,23 @@ import { mapArray } from "solid-js"; ```ts function mapArray( - list: Accessor>, - map: (value: Item, index: Accessor) => MappedItem, - options?: { keyed?: true; fallback?: Accessor; name?: string } + list: Accessor>, + map: (value: Item, index: Accessor) => MappedItem, + options?: { keyed?: true; fallback?: Accessor; name?: string } ): Accessor; function mapArray( - list: Accessor>, - map: (value: Accessor, index: number) => MappedItem, - options: { keyed: false; fallback?: Accessor; name?: string } + list: Accessor>, + map: (value: Accessor, index: number) => MappedItem, + options: { keyed: false; fallback?: Accessor; name?: string } ): Accessor; function mapArray( - list: Accessor>, - map: (value: Accessor, index: Accessor) => MappedItem, - options: { keyed: (item: Item) => any; fallback?: Accessor; name?: string } + list: Accessor>, + map: (value: Accessor, index: Accessor) => MappedItem, + options: { + keyed: (item: Item) => any; + fallback?: Accessor; + name?: string; + } ): Accessor; ``` @@ -85,11 +90,9 @@ function mapArray( ## Examples ```ts -const view = mapArray( - items, - (item, index) => `${index()}: ${item.label}`, - { fallback: () => "no items" } -); +const view = mapArray(items, (item, index) => `${index()}: ${item.label}`, { + fallback: () => "no items", +}); ``` ## Learn more diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/repeat.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/repeat.mdx index f3532a1ec..1b01eba11 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/repeat.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(4)jsx-component-primitives/repeat.mdx @@ -37,13 +37,13 @@ import { repeat } from "solid-js"; ```ts function repeat( - count: Accessor, - map: (index: number) => any, - options?: { - from?: Accessor; - fallback?: Accessor; - name?: string; - } + count: Accessor, + map: (index: number) => any, + options?: { + from?: Accessor; + fallback?: Accessor; + name?: string; + } ): Accessor; ``` @@ -65,7 +65,7 @@ function repeat( ## Examples ```ts -const view = repeat(count, i => `Item ${i}`, { fallback: () => "empty" }); +const view = repeat(count, (i) => `Item ${i}`, { fallback: () => "empty" }); ``` ## Learn more diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(5)manual-hydration/hydration.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(5)manual-hydration/hydration.mdx index e64aaa5fa..1bb8e2b86 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(5)manual-hydration/hydration.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(5)manual-hydration/hydration.mdx @@ -51,11 +51,11 @@ function Hydration(props: { id?: string; children: JSX.Element }): JSX.Element; // Inside a `` region, re-enable hydration for one inner // subtree that does need to match a server-rendered fragment. - - - - - + + + + + ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(5)manual-hydration/no-hydration.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(5)manual-hydration/no-hydration.mdx index 005df6b54..ecce2f231 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(5)manual-hydration/no-hydration.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(5)manual-hydration/no-hydration.mdx @@ -47,7 +47,7 @@ function NoHydration(props: { children: JSX.Element }): JSX.Element; // Mount a client-only widget that the server didn't render. The subtree // is left empty during hydration, then renders fresh once hydration ends. - + ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/enable-external-source.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/enable-external-source.mdx index 8af4934aa..b748311f1 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/enable-external-source.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/enable-external-source.mdx @@ -53,9 +53,9 @@ function enableExternalSource(config: ExternalSourceConfig): void; ```ts interface ExternalSource { - track: (prev: any) => any; - dispose: () => void; -}; + track: (prev: any) => any; + dispose: () => void; +} ``` #### `track` @@ -70,9 +70,9 @@ interface ExternalSource { ```ts interface ExternalSourceConfig { - factory: ExternalSourceFactory; - untrack?: (fn: () => T) => T; -}; + factory: ExternalSourceFactory; + untrack?: (fn: () => T) => T; +} ``` #### `factory` @@ -86,5 +86,8 @@ interface ExternalSourceConfig { ### `ExternalSourceFactory` ```ts -type ExternalSourceFactory = (fn: (prev: any) => any, trigger: () => void) => ExternalSource; +type ExternalSourceFactory = ( + fn: (prev: any) => any, + trigger: () => void +) => ExternalSource; ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/flatten.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/flatten.mdx index d1c4244d3..ac6b1716b 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/flatten.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/flatten.mdx @@ -11,7 +11,7 @@ tags: - "api" - "v2" version: "2.0" -description: "Resolves a children value to its renderable form: unwraps zero-arg functions (accessors), recursively flattens arrays, and optionally skips non-rendering values (`null`, `undefined`, `true`, `false`, `\"\"`)." +description: 'Resolves a children value to its renderable form: unwraps zero-arg functions (accessors), recursively flattens arrays, and optionally skips non-rendering values (`null`, `undefined`, `true`, `false`, `""`).' source_repo: "solidjs/solid" source_ref: "next" source_path: "packages/signals/src/boundaries.ts" @@ -37,8 +37,8 @@ import { flatten } from "solid-js"; ```ts function flatten( - children: any, - options?: { skipNonRendered?: boolean; doNotUnwrap?: boolean } + children: any, + options?: { skipNonRendered?: boolean; doNotUnwrap?: boolean } ): any; ``` @@ -64,7 +64,7 @@ Value or array of values to flatten // Custom renderer walking a children tree manually. Most authors should // use `children()` from solid-js, which memoizes the resolved value. function renderChildren(value: unknown): unknown { - return flatten(value, { skipNonRendered: true }); + return flatten(value, { skipNonRendered: true }); } ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/not-ready-error.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/not-ready-error.mdx index b4d8fb8ce..591cb82f6 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/not-ready-error.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/not-ready-error.mdx @@ -43,10 +43,10 @@ class NotReadyError extends Error { // Advanced: distinguish "not ready yet" from a real error in custom // boundary plumbing. App code should rely on `` / ``. try { - const value = readReactiveSource(); + const value = readReactiveSource(); } catch (err) { - if (err instanceof NotReadyError) throw err; // re-throw to suspend - reportError(err); + if (err instanceof NotReadyError) throw err; // re-throw to suspend + reportError(err); } ``` diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/resolve.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/resolve.mdx index 4b7d51fcb..fa07d0d5b 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/resolve.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(6)interop-async/resolve.mdx @@ -26,7 +26,7 @@ the promise resolves with that value. If the expression settles with an error instead — including an async source that rejects — the promise rejects with it. -Must be called *outside* a tracking scope — it doesn't subscribe, it only +Must be called _outside_ a tracking scope — it doesn't subscribe, it only resolves the current value once. ## Import @@ -52,7 +52,7 @@ A reactive expression to resolve ## Examples ```ts -const user = createMemo(() => fetch(`/users/${id()}`).then(r => r.json())); +const user = createMemo(() => fetch(`/users/${id()}`).then((r) => r.json())); // outside any reactive scope const initial = await resolve(() => user()); diff --git a/src/routes/reference/(1)solid-js/(6)advanced/(7)diagnostics-dev-hooks/dev.mdx b/src/routes/reference/(1)solid-js/(6)advanced/(7)diagnostics-dev-hooks/dev.mdx index a06b19e9a..461f42cff 100644 --- a/src/routes/reference/(1)solid-js/(6)advanced/(7)diagnostics-dev-hooks/dev.mdx +++ b/src/routes/reference/(1)solid-js/(6)advanced/(7)diagnostics-dev-hooks/dev.mdx @@ -51,10 +51,10 @@ acknowledgements by `kind:source` (`isPending:posts`). ```ts interface Acknowledgement { - kind: "isPending" | "latest" | "optimistic" | "affects"; - source: string; - reader?: string[]; -}; + kind: "isPending" | "latest" | "optimistic" | "affects"; + source: string; + reader?: string[]; +} ``` #### `kind` @@ -79,62 +79,71 @@ Core's obligation is to call these with true facts at the moments they happen; all attribution semantics (stamps, cause chains, timings, warnings) live in the engine that installs them — `@solidjs/signals/attribution`, a separate entry so an observe build that never enables it never ships it -(same pattern as the GlobalQueue._* feature slots). `attrHooks` is null +(same pattern as the GlobalQueue.\_\* feature slots). `attrHooks` is null unless an engine is installed, so the disabled cost is one null check per -site, and prod builds fold every site out behind __OBSERVE__. +site, and prod builds fold every site out behind **OBSERVE**. Important for implementers of call sites: a hook call must never sit inside a `try` block — rollup's tryCatchDeoptimization retains functions referenced -inside `try` even behind a folded __OBSERVE__ guard, which re-couples the +inside `try` even behind a folded **OBSERVE** guard, which re-couples the engine into prod bundles (#2883 harness). Set a local flag inside the try and call the hook after the catch. ```ts interface AttributionHooks { - interactionStart(ref: InteractionRef): void; - interactionEnd(): void; - originStart(ref: OriginRef): void; - originEnd(): void; - flushEnd(): void; - recomputeStart(el: Computed, create: boolean): void; - recomputeEnd( - el: Computed, - create: boolean, - changed: boolean, - optimistic: boolean, - transition: boolean, - held: boolean - ): void; - derivedChanged(el: Computed): void; - write(el: Signal | Computed, prev: unknown, value: unknown): void; - refreshed(el: Computed): void; - flightStart(el: Computed, flight: object): void; - asyncStart(el: Computed): void; - asyncEnd(el: Computed, prev: unknown, value: unknown, direct: boolean): void; - effectRunStart(el: Computed): void; - effectRunEnd(el: Computed): void; - actionStepStart(it: object, name: string | undefined): void; - actionStepEnd(it: object): void; - holdStart(t: Transition): void; - holdEnd(): void; - transitionSettled(t: Transition): void; - transitionMerged(target: Transition, outgoing: Transition): void; - storeReplaced( - path: string, - isArray: boolean, - total: number, - unchanged: number, - prevTotal: number - ): void; - listChurn( - el: Computed, - removed: unknown[], - created: unknown[], - newLen: number, - keyed: boolean - ): void; - boundaryFallback(boundary: object, tree: Computed | undefined, shown: boolean): void; -}; + interactionStart(ref: InteractionRef): void; + interactionEnd(): void; + originStart(ref: OriginRef): void; + originEnd(): void; + flushEnd(): void; + recomputeStart(el: Computed, create: boolean): void; + recomputeEnd( + el: Computed, + create: boolean, + changed: boolean, + optimistic: boolean, + transition: boolean, + held: boolean + ): void; + derivedChanged(el: Computed): void; + write(el: Signal | Computed, prev: unknown, value: unknown): void; + refreshed(el: Computed): void; + flightStart(el: Computed, flight: object): void; + asyncStart(el: Computed): void; + asyncEnd( + el: Computed, + prev: unknown, + value: unknown, + direct: boolean + ): void; + effectRunStart(el: Computed): void; + effectRunEnd(el: Computed): void; + actionStepStart(it: object, name: string | undefined): void; + actionStepEnd(it: object): void; + holdStart(t: Transition): void; + holdEnd(): void; + transitionSettled(t: Transition): void; + transitionMerged(target: Transition, outgoing: Transition): void; + storeReplaced( + path: string, + isArray: boolean, + total: number, + unchanged: number, + prevTotal: number + ): void; + listChurn( + el: Computed, + removed: unknown[], + created: unknown[], + newLen: number, + keyed: boolean + ): void; + boundaryFallback( + boundary: object, + tree: Computed | undefined, + shown: boolean + ): void; +} ``` #### `interactionStart` @@ -273,7 +282,7 @@ writes stay staged and its queues are about to be parked. Fired before this flush's lane effects (the visible acknowledgers — isPending companions, optimistic values) run; `holdEnd` fires from the root stashQueues call after them, so effect runs between the two are runs that -painted *during* the hold. +painted _during_ the hold. #### `holdEnd` @@ -338,11 +347,11 @@ consumer never polls the ring buffers to learn that something finished. ```ts interface AttributionRecords { - rerun: RerunEvent; - interaction: InteractionEvent; - hold: HoldEvent; - navigation: NavigationEvent; -}; + rerun: RerunEvent; + interaction: InteractionEvent; + hold: HoldEvent; + navigation: NavigationEvent; +} ``` #### `rerun` @@ -377,11 +386,11 @@ for it only when something imports it. ```ts interface AttributionSlot { - install(hooks: AttributionHooks | null): void; - readonly installed: AttributionHooks | null; - withInteraction(ref: InteractionRef, fn: () => T): T; - withOrigin(ref: OriginRef, fn: () => T): T; -}; + install(hooks: AttributionHooks | null): void; + readonly installed: AttributionHooks | null; + withInteraction(ref: InteractionRef, fn: () => T): T; + withOrigin(ref: OriginRef, fn: () => T): T; +} ``` #### `install` @@ -449,16 +458,17 @@ interaction that paid for it. ```ts interface ChangeOrigin { - kind: "interaction" | "effect" | "action" | "async" | "navigation" | "external"; - name?: string; - target?: string; - at?: number; - interaction?: ChangeOrigin; - run?: number; - to?: string; - from?: string; - params?: Readonly>; -}; + kind: + "interaction" | "effect" | "action" | "async" | "navigation" | "external"; + name?: string; + target?: string; + at?: number; + interaction?: ChangeOrigin; + run?: number; + to?: string; + from?: string; + params?: Readonly>; +} ``` #### `kind` @@ -505,16 +515,16 @@ interface ChangeOrigin { ```ts interface ChangeRecord { - seq: number; - kind: ChangeKind; - name: string; - prev?: string; - value?: string; - stack?: string[]; - causes?: ChangeRecord[]; - origin?: ChangeOrigin; - at?: number; -}; + seq: number; + kind: ChangeKind; + name: string; + prev?: string; + value?: string; + stack?: string[]; + causes?: ChangeRecord[]; + origin?: ChangeOrigin; + at?: number; +} ``` #### `seq` @@ -572,15 +582,17 @@ diagnostics channel. Present only in dev builds (`__DEV__`). ```ts interface Dev { - hooks: DevHooks; - getChildren: typeof getChildren; - getSignals: typeof getSignals; - getParent: typeof getParent; - getSources: typeof getSources; - getObservers: typeof getObservers; - report(entry: DiagnosticEvent): void; - setConsoleFooter(footer: ((event: DiagnosticEvent) => string | undefined) | undefined): void; -}; + hooks: DevHooks; + getChildren: typeof getChildren; + getSignals: typeof getSignals; + getParent: typeof getParent; + getSources: typeof getSources; + getObservers: typeof getObservers; + report(entry: DiagnosticEvent): void; + setConsoleFooter( + footer: ((event: DiagnosticEvent) => string | undefined) | undefined + ): void; +} ``` #### `hooks` @@ -629,11 +641,16 @@ resets the once-per-code memory. ```ts interface DevHooks { - onOwner?: (owner: Owner) => void; - onGraph?: (value: any, owner: Owner | null) => void; - onUpdate?: () => void; - onStoreNodeUpdate?: (state: any, property: PropertyKey, value: any, prev: any) => void; -}; + onOwner?: (owner: Owner) => void; + onGraph?: (value: any, owner: Owner | null) => void; + onUpdate?: () => void; + onStoreNodeUpdate?: ( + state: any, + property: PropertyKey, + value: any, + prev: any + ) => void; +} ``` #### `onOwner` @@ -656,10 +673,10 @@ interface DevHooks { ```ts interface DiagnosticCapture { - readonly events: readonly DiagnosticEvent[]; - clear(): void; - stop(): DiagnosticEvent[]; -}; + readonly events: readonly DiagnosticEvent[]; + clear(): void; + stop(): DiagnosticEvent[]; +} ``` #### `events` @@ -678,74 +695,74 @@ interface DiagnosticCapture { ```ts type DiagnosticCode = - | "STRICT_READ_UNTRACKED" - | "PENDING_ASYNC_UNTRACKED_READ" - | "PENDING_ASYNC_FORBIDDEN_SCOPE" - | "REACTIVE_WRITE_IN_OWNED_SCOPE" - | "ACTION_CALLED_IN_OWNED_SCOPE" - | "RUN_WITH_DISPOSED_OWNER" - | "NO_OWNER_CLEANUP" - | "CLEANUP_IN_FORBIDDEN_SCOPE" - | "SETTLED_CLEANUP_UNOWNED" - | "SETTLE_WALK_UNINITIALIZED_SOURCE" - | "FLUSH_IN_EFFECT_CALLBACK" - | "PRIMITIVE_IN_FORBIDDEN_SCOPE" - | "NO_OWNER_EFFECT" - | "NO_OWNER_BOUNDARY" - | "ASYNC_OUTSIDE_LOADING_BOUNDARY" - | "INVALID_REFRESH_TARGET" - | "INVALID_AFFECTS_TARGET" - | "MISSING_EFFECT_FN" - | "SYNC_NODE_RECEIVED_ASYNC" - | "REACTIVITY_HALTED" - | "INVARIANT_VIOLATION" - | "HUGE_FAN_OUT" - | "HUGE_FAN_IN" - | "HOT_SCOPE_RERUNS" - | "HOT_SCOPE_TIME" - | "WIDE_SCOPE_DEPS" - | "UNSTABLE_MEMO_OUTPUT" - | "WIDE_WRITE" - | "ASYNC_WATERFALL" - | "HOT_SCOPE_FANOUT" - | "SILENT_HOLD" - | "LONG_HOLD" - | "EFFECT_WRITES_OWN_SOURCE" - | "EFFECT_RELAY_TEAR" - | "IMMUTABLE_UPDATE_IN_STORE" - | "UNSTABLE_LIST_IDENTITY" - // Server / SSR — emitted by the server runtimes (`solid-js`'s server - // facade, `@solidjs/web`'s server entries) through `OBSERVE.diagnostics.emit`. - | "SSR_RENDER_ERROR_CONTAINED" - | "SSR_SUBTREE_ABANDONED" - | "SSR_STREAM_ABANDONED" - | "LATE_HEADER_WRITE" - | "SERVER_FN_ERROR_SANITIZED" - | "SERVER_WRITE" - | "REVEAL_IN_RENDER_TO_STRING" - | "LAZY_ASSET_UNMAPPED" - | "PRELOAD_DESCRIPTOR_INVALID" - | "HEAD_TAG_INVALID" - | "UNRECOGNIZED_INSERT_VALUE" - | "BEHAVIOR_CLAIM_DROPPED" - | "FRAME_MARKER_CORRUPTED"; + | "STRICT_READ_UNTRACKED" + | "PENDING_ASYNC_UNTRACKED_READ" + | "PENDING_ASYNC_FORBIDDEN_SCOPE" + | "REACTIVE_WRITE_IN_OWNED_SCOPE" + | "ACTION_CALLED_IN_OWNED_SCOPE" + | "RUN_WITH_DISPOSED_OWNER" + | "NO_OWNER_CLEANUP" + | "CLEANUP_IN_FORBIDDEN_SCOPE" + | "SETTLED_CLEANUP_UNOWNED" + | "SETTLE_WALK_UNINITIALIZED_SOURCE" + | "FLUSH_IN_EFFECT_CALLBACK" + | "PRIMITIVE_IN_FORBIDDEN_SCOPE" + | "NO_OWNER_EFFECT" + | "NO_OWNER_BOUNDARY" + | "ASYNC_OUTSIDE_LOADING_BOUNDARY" + | "INVALID_REFRESH_TARGET" + | "INVALID_AFFECTS_TARGET" + | "MISSING_EFFECT_FN" + | "SYNC_NODE_RECEIVED_ASYNC" + | "REACTIVITY_HALTED" + | "INVARIANT_VIOLATION" + | "HUGE_FAN_OUT" + | "HUGE_FAN_IN" + | "HOT_SCOPE_RERUNS" + | "HOT_SCOPE_TIME" + | "WIDE_SCOPE_DEPS" + | "UNSTABLE_MEMO_OUTPUT" + | "WIDE_WRITE" + | "ASYNC_WATERFALL" + | "HOT_SCOPE_FANOUT" + | "SILENT_HOLD" + | "LONG_HOLD" + | "EFFECT_WRITES_OWN_SOURCE" + | "EFFECT_RELAY_TEAR" + | "IMMUTABLE_UPDATE_IN_STORE" + | "UNSTABLE_LIST_IDENTITY" + // Server / SSR — emitted by the server runtimes (`solid-js`'s server + // facade, `@solidjs/web`'s server entries) through `OBSERVE.diagnostics.emit`. + | "SSR_RENDER_ERROR_CONTAINED" + | "SSR_SUBTREE_ABANDONED" + | "SSR_STREAM_ABANDONED" + | "LATE_HEADER_WRITE" + | "SERVER_FN_ERROR_SANITIZED" + | "SERVER_WRITE" + | "REVEAL_IN_RENDER_TO_STRING" + | "LAZY_ASSET_UNMAPPED" + | "PRELOAD_DESCRIPTOR_INVALID" + | "HEAD_TAG_INVALID" + | "UNRECOGNIZED_INSERT_VALUE" + | "BEHAVIOR_CLAIM_DROPPED" + | "FRAME_MARKER_CORRUPTED"; ``` ### `DiagnosticEvent` ```ts interface DiagnosticEvent { - sequence: number; - code: DiagnosticCode; - kind: DiagnosticKind; - severity: DiagnosticSeverity; - message: string; - ownerId?: string; - ownerName?: string; - nodeName?: string; - ownerPath?: string[]; - data?: Record; -}; + sequence: number; + code: DiagnosticCode; + kind: DiagnosticKind; + severity: DiagnosticSeverity; + message: string; + ownerId?: string; + ownerName?: string; + nodeName?: string; + ownerPath?: string[]; + data?: Record; +} ``` #### `sequence` @@ -799,18 +816,18 @@ is usually the finding itself). ```ts type DiagnosticKind = - | "strict-read" - | "async" - | "write" - | "lifecycle" - | "owner" - | "error" - | "perf" - | "graph" - | "responsiveness" - | "ssr" - | "head" - | "render"; + | "strict-read" + | "async" + | "write" + | "lifecycle" + | "owner" + | "error" + | "perf" + | "graph" + | "responsiveness" + | "ssr" + | "head" + | "render"; ``` ### `DiagnosticListener` @@ -823,13 +840,13 @@ type DiagnosticListener = (event: DiagnosticEvent) => void; ```ts interface Diagnostics { - subscribe(listener: DiagnosticListener): () => void; - capture(): DiagnosticCapture; - emit( - event: Omit, - subject?: DiagnosticSubject | null - ): DiagnosticEvent; -}; + subscribe(listener: DiagnosticListener): () => void; + capture(): DiagnosticCapture; + emit( + event: Omit, + subject?: DiagnosticSubject | null + ): DiagnosticEvent; +} ``` #### `subscribe` @@ -873,11 +890,11 @@ type DiagnosticSubject = Owner | Signal | Computed; ```ts interface HeldWrite { - name: string; - prev?: string; - value?: string; - origin?: ChangeOrigin; -}; + name: string; + prev?: string; + value?: string; + origin?: ChangeOrigin; +} ``` #### `name` @@ -900,18 +917,18 @@ interface HeldWrite { ```ts interface HoldEvent { - at: number; - holdMs: number; - tailMs: number; - interaction?: ChangeOrigin; - origin?: ChangeOrigin; - flushes: number; - heldWrites: HeldWrite[]; - blockers: string[]; - acknowledgements: Acknowledgement[]; - paintedDuringHold: number; - action: boolean; -}; + at: number; + holdMs: number; + tailMs: number; + interaction?: ChangeOrigin; + origin?: ChangeOrigin; + flushes: number; + heldWrites: HeldWrite[]; + blockers: string[]; + acknowledgements: Acknowledgement[]; + paintedDuringHold: number; + action: boolean; +} ``` #### `at` @@ -999,20 +1016,20 @@ The hold was opened (or joined) by an `action()`. ```ts interface InteractionEvent { - name: string; - target?: string; - at: number; - handlerMs: number; - writes: number; - runs: number; - created: number; - runMs: number; - holds: HoldEvent[]; - navigations: NavigationEvent[]; - settledMs?: number; - outcome?: "idle" | "committed" | "held"; - origin: ChangeOrigin; -}; + name: string; + target?: string; + at: number; + handlerMs: number; + writes: number; + runs: number; + created: number; + runMs: number; + holds: HoldEvent[]; + navigations: NavigationEvent[]; + settledMs?: number; + outcome?: "idle" | "committed" | "held"; + origin: ChangeOrigin; +} ``` #### `name` @@ -1101,10 +1118,10 @@ A user interaction, as a rendering runtime describes it to `withInteraction`. ```ts interface InteractionRef { - type: string; - target?: string; - at?: number; -}; + type: string; + target?: string; + at?: number; +} ``` #### `type` @@ -1135,8 +1152,8 @@ that throws is reported and the call is unaffected. ```ts interface InvocationChannel { - subscribe(type: "invocation", listener: InvocationListener): () => void; -}; + subscribe(type: "invocation", listener: InvocationListener): () => void; +} ``` #### `subscribe` @@ -1151,13 +1168,13 @@ thrown error) travel beside it in `InvocationLive`, not on it. ```ts interface InvocationEvent { - id: string; - direct: boolean; - at: number; - durationMs: number; - outcome: "ok" | "error"; - deferred?: true; -}; + id: string; + direct: boolean; + at: number; + durationMs: number; + outcome: "ok" | "error"; + deferred?: true; +} ``` #### `id` @@ -1202,7 +1219,10 @@ not its consumption. ### `InvocationListener` ```ts -type InvocationListener = (event: InvocationEvent, live: InvocationLive) => void; +type InvocationListener = ( + event: InvocationEvent, + live: InvocationLive +) => void; ``` ### `InvocationLive` @@ -1216,12 +1236,12 @@ direct calls). ```ts interface InvocationLive { - event: RequestEvent; - request?: Request; - args: unknown[]; - result?: unknown; - error?: unknown; -}; + event: RequestEvent; + request?: Request; + args: unknown[]; + result?: unknown; + error?: unknown; +} ``` #### `event` @@ -1254,19 +1274,19 @@ The thrown value, when `outcome` is `"error"`. ```ts interface NavigationEvent { - name?: string; - to?: string; - from?: string; - params?: Readonly>; - at: number; - interaction?: ChangeOrigin; - writes: number; - redirects?: NavigationHop[]; - settledMs?: number; - outcome?: "committed" | "held" | "superseded"; - hold?: HoldEvent; - origin: ChangeOrigin; -}; + name?: string; + to?: string; + from?: string; + params?: Readonly>; + at: number; + interaction?: ChangeOrigin; + writes: number; + redirects?: NavigationHop[]; + settledMs?: number; + outcome?: "committed" | "held" | "superseded"; + hold?: HoldEvent; + origin: ChangeOrigin; +} ``` #### `name` @@ -1342,11 +1362,11 @@ A destination a navigation abandoned when a redirect sent it elsewhere. ```ts interface NavigationHop { - name?: string; - to?: string; - params?: Readonly>; - at: number; -}; + name?: string; + to?: string; + params?: Readonly>; + at: number; +} ``` #### `name` @@ -1384,14 +1404,14 @@ read once, when the frame opens. ```ts interface NavigationRef { - kind: "navigation"; - name?: string; - to?: string; - from?: string; - params?: Readonly>; - at?: number; - redirect?: number; -}; + kind: "navigation"; + name?: string; + to?: string; + from?: string; + params?: Readonly>; + at?: number; + redirect?: number; +} ``` #### `kind` @@ -1450,13 +1470,13 @@ assumes a developer at a console. Present in dev and observe builds ```ts interface Observe { - diagnostics: Diagnostics; - attribution: AttributionSlot; - server: ServerObserve; - subjectOf(event: DiagnosticEvent): DiagnosticSubject | undefined; - exclude(owner: Owner): void; - isExcluded(subject: DiagnosticSubject | null | undefined): boolean; -}; + diagnostics: Diagnostics; + attribution: AttributionSlot; + server: ServerObserve; + subjectOf(event: DiagnosticEvent): DiagnosticSubject | undefined; + exclude(owner: Owner): void; + isExcluded(subject: DiagnosticSubject | null | undefined): boolean; +} ``` #### `diagnostics` @@ -1529,23 +1549,23 @@ type OriginRef = NavigationRef; ```ts interface RerunEvent { - run: number; - at: number; - nodeRuns: number; - nodeKind: "effect" | "memo"; - nodeName: string; - node: Computed; - causes: ChangeRecord[]; - depCount: number; - depsAdded: string[]; - depsRemoved: string[]; - selfMs: number; - totalMs: number; - changed: boolean; - phase: "plain" | "held" | "optimistic"; - held: boolean; - interaction?: ChangeOrigin; -}; + run: number; + at: number; + nodeRuns: number; + nodeKind: "effect" | "memo"; + nodeName: string; + node: Computed; + causes: ChangeRecord[]; + depCount: number; + depsAdded: string[]; + depsRemoved: string[]; + selfMs: number; + totalMs: number; + changed: boolean; + phase: "plain" | "held" | "optimistic"; + held: boolean; + interaction?: ChangeOrigin; +} ``` #### `run` @@ -1676,5 +1696,5 @@ into them has loaded, and from a second copy when a host bundles one. On the client this stays `{}`. ```ts -interface ServerObserve {}; +interface ServerObserve {} ``` diff --git a/src/routes/reference/(1)solid-js/(7)types/component-types.mdx b/src/routes/reference/(1)solid-js/(7)types/component-types.mdx index 74a399690..bd8e686ee 100644 --- a/src/routes/reference/(1)solid-js/(7)types/component-types.mdx +++ b/src/routes/reference/(1)solid-js/(7)types/component-types.mdx @@ -29,7 +29,18 @@ one explicitly, e.g. `Component<{ name: string; children: Element }>`. ## Import ```ts -import type { Component, ComponentProps, FlowComponent, FlowProps, ParentComponent, ParentProps, Ref, ValidComponent, VoidComponent, VoidProps } from "solid-js"; +import type { + Component, + ComponentProps, + FlowComponent, + FlowProps, + ParentComponent, + ParentProps, + Ref, + ValidComponent, + VoidComponent, + VoidProps, +} from "solid-js"; ``` ## `Component` @@ -50,7 +61,8 @@ packages such as `@solidjs/web`. ### Type signature ```ts -type ComponentProps = T extends Component ? P : never; +type ComponentProps = + T extends Component ? P : never; ``` ## `FlowComponent` @@ -62,9 +74,10 @@ typically a function that receives specific argument types. ### Type signature ```ts -type FlowComponent

= {}, C = JSX.Element> = Component< - FlowProps ->; +type FlowComponent< + P extends Record = {}, + C = JSX.Element, +> = Component>; ``` ## `FlowProps` @@ -76,7 +89,9 @@ typically a function that receives specific argument types. ### Type signature ```ts -type FlowProps

= {}, C = JSX.Element> = P & { children: C }; +type FlowProps

= {}, C = JSX.Element> = P & { + children: C; +}; ``` ## `ParentComponent` @@ -87,7 +102,9 @@ Use this for components that you want to accept children. ### Type signature ```ts -type ParentComponent

= {}> = Component>; +type ParentComponent

= {}> = Component< + ParentProps

+>; ``` ## `ParentProps` @@ -98,7 +115,9 @@ Use this for components that you want to accept children. ### Type signature ```ts -type ParentProps

= {}> = P & { children?: JSX.Element }; +type ParentProps

= {}> = P & { + children?: JSX.Element; +}; ``` ## `Ref` @@ -114,7 +133,7 @@ type Ref = T | ((val: T) => void) | undefined | Ref[]; ### Examples ```ts -Component<{ref: Ref}> +Component<{ ref: Ref }>; ``` ## `ValidComponent` @@ -136,7 +155,9 @@ would silently throw them away. ### Type signature ```ts -type VoidComponent

= {}> = Component>; +type VoidComponent

= {}> = Component< + VoidProps

+>; ``` ## `VoidProps` diff --git a/src/routes/reference/(1)solid-js/(7)types/context-types.mdx b/src/routes/reference/(1)solid-js/(7)types/context-types.mdx index 286224e52..7533f719e 100644 --- a/src/routes/reference/(1)solid-js/(7)types/context-types.mdx +++ b/src/routes/reference/(1)solid-js/(7)types/context-types.mdx @@ -33,9 +33,9 @@ import type { Context, ContextProviderComponent } from "solid-js"; ```ts interface Context extends ContextProviderComponent { - id: symbol; - defaultValue: T | undefined; -}; + id: symbol; + defaultValue: T | undefined; +} ``` ### Properties diff --git a/src/routes/reference/(1)solid-js/(7)types/jsx-types.mdx b/src/routes/reference/(1)solid-js/(7)types/jsx-types.mdx index 60d7c60df..be45a9bec 100644 --- a/src/routes/reference/(1)solid-js/(7)types/jsx-types.mdx +++ b/src/routes/reference/(1)solid-js/(7)types/jsx-types.mdx @@ -44,7 +44,8 @@ namespace JSX { [key: `-${string}`]: string | number | undefined; } interface IntrinsicElements - extends HTMLElementTags, + extends + HTMLElementTags, HTMLElementDeprecatedTags, SVGElementTags, MathMLElementTags {} @@ -60,20 +61,20 @@ namespace JSX { ### `ArrayElement` ```ts -interface ArrayElement extends Array {}; +interface ArrayElement extends Array {} ``` ### `Element` ```ts type Element = - | RenderedElement - | ArrayElement - | (string & {}) - | number - | boolean - | null - | undefined; + | RenderedElement + | ArrayElement + | (string & {}) + | number + | boolean + | null + | undefined; ``` ### `IntrinsicElement` diff --git a/src/routes/reference/(1)solid-js/(7)types/reactive-types.mdx b/src/routes/reference/(1)solid-js/(7)types/reactive-types.mdx index c06f1a224..2290db834 100644 --- a/src/routes/reference/(1)solid-js/(7)types/reactive-types.mdx +++ b/src/routes/reference/(1)solid-js/(7)types/reactive-types.mdx @@ -53,12 +53,14 @@ with an updater: `setHandler(() => myHandler)`. ```ts type Setter = { - ( - ...args: undefined extends T ? [] : [value: Exclude | ((prev: T) => U)] - ): undefined extends T ? undefined : U; - (value: (prev: T) => U): U; - (value: Exclude): U; - (value: Exclude | ((prev: T) => U)): U; + ( + ...args: undefined extends T + ? [] + : [value: Exclude | ((prev: T) => U)] + ): undefined extends T ? undefined : U; + (value: (prev: T) => U): U; + (value: Exclude): U; + (value: Exclude | ((prev: T) => U)): U; }; ``` diff --git a/src/routes/reference/(1)solid-js/(7)types/store-types.mdx b/src/routes/reference/(1)solid-js/(7)types/store-types.mdx index 01cea7492..2afdfdc49 100644 --- a/src/routes/reference/(1)solid-js/(7)types/store-types.mdx +++ b/src/routes/reference/(1)solid-js/(7)types/store-types.mdx @@ -42,8 +42,8 @@ SolidStore API reference. ```ts namespace SolidStore { - export interface Unwrappable {} -}; + export interface Unwrappable {} +} ``` ## Learn more diff --git a/src/routes/reference/(2)solid-web/(1)rendering-ssr/http-header.mdx b/src/routes/reference/(2)solid-web/(1)rendering-ssr/http-header.mdx index 4f55dcfe7..d6072d355 100644 --- a/src/routes/reference/(2)solid-web/(1)rendering-ssr/http-header.mdx +++ b/src/routes/reference/(2)solid-web/(1)rendering-ssr/http-header.mdx @@ -24,7 +24,7 @@ the lifetime of the current reactive scope during SSR — call it bare in a component or reactive-scope body. Client build: a no-op — the response head was sent long ago. -Naming note — this is a scope-tied *declaration*, not a mutation: "while +Naming note — this is a scope-tied _declaration_, not a mutation: "while this reactive scope is live, the response has this header." Solid reserves `set*` verbs for event-time mutation; like `createSignal`/`onCleanup` this is called in scope bodies and un-declares @@ -46,7 +46,11 @@ import { httpHeader } from "@solidjs/web"; ## Type signature ```ts -function httpHeader(name: string, value: string, options?: { append?: boolean }): void; +function httpHeader( + name: string, + value: string, + options?: { append?: boolean } +): void; ``` ## Parameters @@ -84,7 +88,9 @@ function ProductPage() { ### Append a header ```ts -httpHeader("Link", "; rel=preload; as=font", { append: true }); +httpHeader("Link", "; rel=preload; as=font", { + append: true, +}); ``` ## Caveats diff --git a/src/routes/reference/(2)solid-web/(1)rendering-ssr/http-status.mdx b/src/routes/reference/(2)solid-web/(1)rendering-ssr/http-status.mdx index acc0f742f..2b396f62f 100644 --- a/src/routes/reference/(2)solid-web/(1)rendering-ssr/http-status.mdx +++ b/src/routes/reference/(2)solid-web/(1)rendering-ssr/http-status.mdx @@ -25,7 +25,7 @@ component or reactive-scope body where the status is decided (a 404 route, an error fallback). Client build: a no-op — the response head was sent long ago. -Naming note — this is a scope-tied *declaration*, not a mutation: "while +Naming note — this is a scope-tied _declaration_, not a mutation: "while this reactive scope is live, the response has this status." Solid reserves `set*` verbs for event-time mutation; like `createSignal`/`onCleanup` this is called in scope bodies and un-declares diff --git a/src/routes/reference/(2)solid-web/(1)rendering-ssr/is-dev.mdx b/src/routes/reference/(2)solid-web/(1)rendering-ssr/is-dev.mdx index 045c093c3..6d38c585d 100644 --- a/src/routes/reference/(2)solid-web/(1)rendering-ssr/is-dev.mdx +++ b/src/routes/reference/(2)solid-web/(1)rendering-ssr/is-dev.mdx @@ -39,7 +39,7 @@ const isDev: boolean; import { isDev } from "@solidjs/web"; if (isDev) { - console.warn("debug-only path"); + console.warn("debug-only path"); } ``` diff --git a/src/routes/reference/(2)solid-web/(1)rendering-ssr/is-server.mdx b/src/routes/reference/(2)solid-web/(1)rendering-ssr/is-server.mdx index 57e5daeca..d1a26d260 100644 --- a/src/routes/reference/(2)solid-web/(1)rendering-ssr/is-server.mdx +++ b/src/routes/reference/(2)solid-web/(1)rendering-ssr/is-server.mdx @@ -39,8 +39,8 @@ const isServer: boolean; import { isServer } from "@solidjs/web"; if (!isServer) { - // Browser-only: tree-shaken out of the SSR bundle. - window.addEventListener("resize", onResize); + // Browser-only: tree-shaken out of the SSR bundle. + window.addEventListener("resize", onResize); } ``` diff --git a/src/routes/reference/(2)solid-web/(1)rendering-ssr/render-to-stream.mdx b/src/routes/reference/(2)solid-web/(1)rendering-ssr/render-to-stream.mdx index 4e5db8fd8..6b991c208 100644 --- a/src/routes/reference/(2)solid-web/(1)rendering-ssr/render-to-stream.mdx +++ b/src/routes/reference/(2)solid-web/(1)rendering-ssr/render-to-stream.mdx @@ -41,42 +41,42 @@ import { renderToStream } from "@solidjs/web"; ```ts function renderToStream( - fn: () => T, - options?: { - nonce?: CSPNonce; - renderId?: string; - noScripts?: boolean; - plugins?: any[]; - manifest?: AssetManifest | AssetResolver | AssetResolverFn; - onCompleteShell?: (info: { write: (v: string) => void }) => void; - onCompleteAll?: (info: { write: (v: string) => void }) => void; - onError?: (err: any) => void; - /** - * Embedded-render contract for hosts that own the document. When the - * shell contains no ``, everything head-bound at first flush - * (resolved `useHead` winners, eager resources, tracked asset links, - * inline styles) is delivered here as one HTML string — prelude first — - * before the shell chunk is emitted, so the host can write its own - * `` ahead of piping the stream. Post-shell head updates flow - * through the stream itself and apply in the browser. Not called when - * the shell has a `` (splicing is automatic then). - */ - onHead?: (head: string) => void; - } + fn: () => T, + options?: { + nonce?: CSPNonce; + renderId?: string; + noScripts?: boolean; + plugins?: any[]; + manifest?: AssetManifest | AssetResolver | AssetResolverFn; + onCompleteShell?: (info: { write: (v: string) => void }) => void; + onCompleteAll?: (info: { write: (v: string) => void }) => void; + onError?: (err: any) => void; + /** + * Embedded-render contract for hosts that own the document. When the + * shell contains no ``, everything head-bound at first flush + * (resolved `useHead` winners, eager resources, tracked asset links, + * inline styles) is delivered here as one HTML string — prelude first — + * before the shell chunk is emitted, so the host can write its own + * `` ahead of piping the stream. Post-shell head updates flow + * through the stream itself and apply in the browser. Not called when + * the shell has a `` (splicing is automatic then). + */ + onHead?: (head: string) => void; + } ): { - /** - * Awaiting the stream resolves with the complete HTML once every boundary - * settles — the fully-settled-string form of the render. Render errors - * route through `onError` and the promise resolves with whatever HTML the - * render produced; it never rejects. - */ - then( - onfulfilled?: ((html: string) => TResult1 | PromiseLike) | null, - onrejected?: ((reason: any) => TResult2 | PromiseLike) | null - ): Promise; - pipe: (writable: { write: (v: string) => void; end: () => void }) => void; - pipeTo: (writable: WritableStream) => Promise; - readonly readable: ReadableStream; + /** + * Awaiting the stream resolves with the complete HTML once every boundary + * settles — the fully-settled-string form of the render. Render errors + * route through `onError` and the promise resolves with whatever HTML the + * render produced; it never rejects. + */ + then( + onfulfilled?: ((html: string) => TResult1 | PromiseLike) | null, + onrejected?: ((reason: any) => TResult2 | PromiseLike) | null + ): Promise; + pipe: (writable: { write: (v: string) => void; end: () => void }) => void; + pipeTo: (writable: WritableStream) => Promise; + readonly readable: ReadableStream; }; ``` @@ -144,24 +144,24 @@ it would likely preload the wrong candidate. ```ts type PreloadLink = PreloadLinkAttributes & - ( - | { - href: string; - as: Exclude; - imagesrcset?: never; - imagesizes?: never; - } - | { - href: string; - as: "image"; - imagesrcset?: string; - imagesizes?: string; - } - | { - href?: never; - as: "image"; - imagesrcset: string; - imagesizes?: string; - } - ); + ( + | { + href: string; + as: Exclude; + imagesrcset?: never; + imagesizes?: never; + } + | { + href: string; + as: "image"; + imagesrcset?: string; + imagesizes?: string; + } + | { + href?: never; + as: "image"; + imagesrcset: string; + imagesizes?: string; + } + ); ``` diff --git a/src/routes/reference/(2)solid-web/(1)rendering-ssr/render-to-string.mdx b/src/routes/reference/(2)solid-web/(1)rendering-ssr/render-to-string.mdx index 1fb94b40f..8f51efbb2 100644 --- a/src/routes/reference/(2)solid-web/(1)rendering-ssr/render-to-string.mdx +++ b/src/routes/reference/(2)solid-web/(1)rendering-ssr/render-to-string.mdx @@ -36,26 +36,26 @@ import { renderToString } from "@solidjs/web"; ```ts function renderToString( - fn: () => T, - options?: { - nonce?: CSPNonce; - renderId?: string; - noScripts?: boolean; - plugins?: any[]; - manifest?: AssetManifest | AssetResolver | AssetResolverFn; - onError?: (err: any) => void; - /** - * Embedded-render contract for hosts that own the document. When the - * render output contains no ``, everything head-bound (resolved - * `useHead` winners, eager resources, tracked asset links, inline - * styles) is delivered here as one HTML string — prelude (charset/base) - * first — for the host to splice into its own `` template, instead - * of being dropped. Called synchronously before `renderToString` - * returns; not called when the output has a `` (splicing is - * automatic then). - */ - onHead?: (head: string) => void; - } + fn: () => T, + options?: { + nonce?: CSPNonce; + renderId?: string; + noScripts?: boolean; + plugins?: any[]; + manifest?: AssetManifest | AssetResolver | AssetResolverFn; + onError?: (err: any) => void; + /** + * Embedded-render contract for hosts that own the document. When the + * render output contains no ``, everything head-bound (resolved + * `useHead` winners, eager resources, tracked asset links, inline + * styles) is delivered here as one HTML string — prelude (charset/base) + * first — for the host to splice into its own `` template, instead + * of being dropped. Called synchronously before `renderToString` + * returns; not called when the output has a `` (splicing is + * automatic then). + */ + onHead?: (head: string) => void; + } ): string; ``` @@ -84,7 +84,9 @@ The rendered HTML string. import { renderToString } from "@solidjs/web"; const html = renderToString(() => ); -res.send(`

${html}
`); +res.send( + `
${html}
` +); ``` ## Caveats diff --git a/src/routes/reference/(2)solid-web/(1)rendering-ssr/render.mdx b/src/routes/reference/(2)solid-web/(1)rendering-ssr/render.mdx index 009c45fec..38a2f1ea0 100644 --- a/src/routes/reference/(2)solid-web/(1)rendering-ssr/render.mdx +++ b/src/routes/reference/(2)solid-web/(1)rendering-ssr/render.mdx @@ -41,10 +41,10 @@ import { render } from "@solidjs/web"; ```ts function render( - code: () => JSX.Element, - element: MountableElement, - init?: JSX.Element, - options?: { owner?: unknown; renderId?: string } + code: () => JSX.Element, + element: MountableElement, + init?: JSX.Element, + options?: { owner?: unknown; renderId?: string } ): () => void; ``` diff --git a/src/routes/reference/(2)solid-web/(3)components/dynamic.mdx b/src/routes/reference/(2)solid-web/(3)components/dynamic.mdx index e80e1408c..7c65e96d5 100644 --- a/src/routes/reference/(2)solid-web/(3)components/dynamic.mdx +++ b/src/routes/reference/(2)solid-web/(3)components/dynamic.mdx @@ -31,8 +31,8 @@ import { dynamic } from "@solidjs/web"; ```ts function dynamic( - source: () => T | Promise | null | undefined | false, - options?: DynamicOptions + source: () => T | Promise | null | undefined | false, + options?: DynamicOptions ): Component>; ``` @@ -78,8 +78,8 @@ return ; ```ts interface DynamicOptions { - deferStream?: boolean; -}; + deferStream?: boolean; +} ``` #### `deferStream` diff --git a/src/routes/reference/(2)solid-web/(3)components/portal.mdx b/src/routes/reference/(2)solid-web/(3)components/portal.mdx index ff990715d..2e20bd503 100644 --- a/src/routes/reference/(2)solid-web/(3)components/portal.mdx +++ b/src/routes/reference/(2)solid-web/(3)components/portal.mdx @@ -61,7 +61,7 @@ Content to render at the mount point. ```tsx - + ``` diff --git a/src/routes/reference/(2)solid-web/(5)server-functions/addressing.mdx b/src/routes/reference/(2)solid-web/(5)server-functions/addressing.mdx index 95e0507aa..8b04527d8 100644 --- a/src/routes/reference/(2)solid-web/(5)server-functions/addressing.mdx +++ b/src/routes/reference/(2)solid-web/(5)server-functions/addressing.mdx @@ -26,7 +26,10 @@ Reads a server-function id from a server-function URL. ## Import ```ts -import { parseServerFunctionUrl, serverFunctionUrl } from "@solidjs/web/server-functions"; +import { + parseServerFunctionUrl, + serverFunctionUrl, +} from "@solidjs/web/server-functions"; ``` ## `parseServerFunctionUrl` diff --git a/src/routes/reference/(2)solid-web/(5)server-functions/configure-client.mdx b/src/routes/reference/(2)solid-web/(5)server-functions/configure-client.mdx index 3a66c3d30..16610fb4c 100644 --- a/src/routes/reference/(2)solid-web/(5)server-functions/configure-client.mdx +++ b/src/routes/reference/(2)solid-web/(5)server-functions/configure-client.mdx @@ -30,7 +30,9 @@ import { configureServerFunctionsClient } from "@solidjs/web/server-functions"; ## Type signature ```ts -function configureServerFunctionsClient(config?: ServerFunctionsClientConfig): void; +function configureServerFunctionsClient( + config?: ServerFunctionsClientConfig +): void; ``` ## Parameters @@ -65,9 +67,9 @@ The context `prepareRequest` receives alongside the outgoing RequestInit. ```ts interface PrepareRequestContext { - id: string; - meta: ServerFunctionMetadata | undefined; -}; + id: string; + meta: ServerFunctionMetadata | undefined; +} ``` #### `id` @@ -95,8 +97,8 @@ a chain — compose by wrapping functions in userland. ```ts type PrepareRequestHook = ( - init: RequestInit, - context: PrepareRequestContext + init: RequestInit, + context: PrepareRequestContext ) => RequestInit | Promise; ``` @@ -106,19 +108,21 @@ Options for `configureServerFunctionsClient`. ```ts interface ServerFunctionsClientConfig { - endpoint?: string; - codec?: JSONCodecOptions; - fetch?: ((address: string, init: RequestInit) => Response | Promise) | null; - prepareRequest?: PrepareRequestHook; - responseHandler?: { - capture?(info: { id: string; meta: unknown }): unknown; - handle( - response: Response, - ctx: { id: string; meta: unknown; args: unknown[]; context: unknown } - ): unknown; - }; - serializeArgs?(args: unknown[]): string | Promise; -}; + endpoint?: string; + codec?: JSONCodecOptions; + fetch?: + | ((address: string, init: RequestInit) => Response | Promise) + | null; + prepareRequest?: PrepareRequestHook; + responseHandler?: { + capture?(info: { id: string; meta: unknown }): unknown; + handle( + response: Response, + ctx: { id: string; meta: unknown; args: unknown[]; context: unknown } + ): unknown; + }; + serializeArgs?(args: unknown[]): string | Promise; +} ``` #### `endpoint` @@ -151,7 +155,7 @@ restores the global. ```ts configureServerFunctionsClient({ - fetch: (address, init) => fetch(rewrite(address), init) + fetch: (address, init) => fetch(rewrite(address), init), }); ``` @@ -180,24 +184,24 @@ cross-cutting concerns — bearer tokens, tracing headers: ```ts configureServerFunctionsClient({ - prepareRequest(init) { - return { - ...init, - headers: { ...init.headers, Authorization: `Bearer ${session.token()}` } - }; - } + prepareRequest(init) { + return { + ...init, + headers: { ...init.headers, Authorization: `Bearer ${session.token()}` }, + }; + }, }); ``` #### `responseHandler` - **Type:** `{ - capture?(info: { id: string; meta: unknown }): unknown; - handle( - response: Response, - ctx: { id: string; meta: unknown; args: unknown[]; context: unknown } - ): unknown; - }` + capture?(info: { id: string; meta: unknown }): unknown; + handle( + response: Response, + ctx: { id: string; meta: unknown; args: unknown[]; context: unknown } + ): unknown; +}` Response-side integration seam — the client mirror of the handler's `transformResult`. `handle(response, ctx)` sees every response before diff --git a/src/routes/reference/(2)solid-web/(5)server-functions/get.mdx b/src/routes/reference/(2)solid-web/(5)server-functions/get.mdx index be58749e1..1a7660a98 100644 --- a/src/routes/reference/(2)solid-web/(5)server-functions/get.mdx +++ b/src/routes/reference/(2)solid-web/(5)server-functions/get.mdx @@ -32,7 +32,7 @@ import { GET } from "@solidjs/web/server-functions"; ```ts function GET( - fn: (...args: A) => R + fn: (...args: A) => R ): ServerFunction>; ``` diff --git a/src/routes/reference/(2)solid-web/(5)server-functions/host-configuration.mdx b/src/routes/reference/(2)solid-web/(5)server-functions/host-configuration.mdx index 3af0fd021..fd043b266 100644 --- a/src/routes/reference/(2)solid-web/(5)server-functions/host-configuration.mdx +++ b/src/routes/reference/(2)solid-web/(5)server-functions/host-configuration.mdx @@ -27,7 +27,10 @@ Configures request scoping, invocation policy, result transforms, no-JavaScript ## Import ```ts -import { configureServerFunctionsServer, handleServerFunctionRequest } from "@solidjs/web/server-functions/server"; +import { + configureServerFunctionsServer, + handleServerFunctionRequest, +} from "@solidjs/web/server-functions/server"; ``` ## `configureServerFunctionsServer` @@ -35,7 +38,9 @@ import { configureServerFunctionsServer, handleServerFunctionRequest } from "@so ### Type signature ```ts -function configureServerFunctionsServer(config?: ServerFunctionsServerConfig): void; +function configureServerFunctionsServer( + config?: ServerFunctionsServerConfig +): void; ``` ### Parameters @@ -53,8 +58,8 @@ Dispatches one web-standard `Request` to a registered server function and return ```ts function handleServerFunctionRequest( - request: Request, - options?: HandleServerFunctionOptions + request: Request, + options?: HandleServerFunctionOptions ): Promise; ``` @@ -77,7 +82,7 @@ import "virtual:solid-server-function-manifest"; // in the server's request handling: if (url.pathname.startsWith("/_server")) { - return handleServerFunctionRequest(request); + return handleServerFunctionRequest(request); } ``` @@ -91,36 +96,36 @@ encodes results on its own. ```ts interface HandleServerFunctionOptions { - createEvent?(request: Request): ServerFunctionEvent; - provideEvent?(event: ServerFunctionEvent, fn: () => T): T; - wrapInvocation?: WrapInvocationHook; - transformResult?( - event: ServerFunctionEvent, - result: unknown, - context: { - id: string; - args: unknown[]; - request: Request; - thrown?: boolean; - } - ): unknown | ResponseEnvelope | Promise; - collectFlightData?: CollectFlightDataHook; - transformFlightResult?( - event: ServerFunctionEvent, - outcome: { value: unknown; data: unknown }, - context: { id: string; args: unknown[]; request: Request } - ): Response | undefined | Promise; - handleNoJS?( - result: unknown, - request: Request, - args: unknown[], - thrown?: boolean - ): Response | Promise; - csrf?: boolean | ServerFunctionCSRFOptions; - codec?: JSONCodecOptions; - bodySizeLimit?: number; - maxArguments?: number; -}; + createEvent?(request: Request): ServerFunctionEvent; + provideEvent?(event: ServerFunctionEvent, fn: () => T): T; + wrapInvocation?: WrapInvocationHook; + transformResult?( + event: ServerFunctionEvent, + result: unknown, + context: { + id: string; + args: unknown[]; + request: Request; + thrown?: boolean; + } + ): unknown | ResponseEnvelope | Promise; + collectFlightData?: CollectFlightDataHook; + transformFlightResult?( + event: ServerFunctionEvent, + outcome: { value: unknown; data: unknown }, + context: { id: string; args: unknown[]; request: Request } + ): Response | undefined | Promise; + handleNoJS?( + result: unknown, + request: Request, + args: unknown[], + thrown?: boolean + ): Response | Promise; + csrf?: boolean | ServerFunctionCSRFOptions; + codec?: JSONCodecOptions; + bodySizeLimit?: number; + maxArguments?: number; +} ``` #### `createEvent` @@ -241,10 +246,10 @@ Same-origin validation options for server function requests. ```ts interface ServerFunctionCSRFOptions { - origin?: ServerFunctionOriginMatcher; - allowRequestsWithoutOriginCheck?: boolean; - protectDeclaredReads?: boolean; -}; + origin?: ServerFunctionOriginMatcher; + allowRequestsWithoutOriginCheck?: boolean; + protectDeclaredReads?: boolean; +} ``` #### `origin` @@ -283,8 +288,8 @@ client. ```ts interface ServerFunctionEvent extends RequestEvent { - serverOnly?: boolean; -}; + serverOnly?: boolean; +} ``` #### `serverOnly` @@ -295,9 +300,9 @@ interface ServerFunctionEvent extends RequestEvent { ```ts type ServerFunctionOriginMatcher = - | string - | readonly string[] - | ((origin: string, request: Request) => boolean | Promise); + | string + | readonly string[] + | ((origin: string, request: Request) => boolean | Promise); ``` ### `ServerFunctionsServerConfig` @@ -306,43 +311,43 @@ Options for `configureServerFunctionsServer`. ```ts interface ServerFunctionsServerConfig { - provideEvent?: (event: ServerFunctionEvent, fn: () => T) => T; - wrapInvocation?: WrapInvocationHook; - collectFlightData?: CollectFlightDataHook; - transformResult?( - event: ServerFunctionEvent, - result: unknown, - context: { - id: string; - args: unknown[]; - request: Request; - thrown?: boolean; - } - ): unknown | ResponseEnvelope | Promise; - transformFlightResult?( - event: ServerFunctionEvent, - outcome: { value: unknown; data: unknown }, - context: { id: string; args: unknown[]; request: Request } - ): Response | undefined | Promise; - transformDirectResult?( - value: unknown, - options: { id: string; args: unknown[]; event: ServerFunctionEvent } - ): unknown; - handleNoJS?: - | (( - result: unknown, - request: Request, - args: unknown[], - thrown?: boolean - ) => Response | Promise) - | null; - endpoint?: string; - csrf?: boolean | ServerFunctionCSRFOptions; - codec?: JSONCodecOptions; - bodySizeLimit?: number; - maxArguments?: number; - secret?: string; -}; + provideEvent?: (event: ServerFunctionEvent, fn: () => T) => T; + wrapInvocation?: WrapInvocationHook; + collectFlightData?: CollectFlightDataHook; + transformResult?( + event: ServerFunctionEvent, + result: unknown, + context: { + id: string; + args: unknown[]; + request: Request; + thrown?: boolean; + } + ): unknown | ResponseEnvelope | Promise; + transformFlightResult?( + event: ServerFunctionEvent, + outcome: { value: unknown; data: unknown }, + context: { id: string; args: unknown[]; request: Request } + ): Response | undefined | Promise; + transformDirectResult?( + value: unknown, + options: { id: string; args: unknown[]; event: ServerFunctionEvent } + ): unknown; + handleNoJS?: + | (( + result: unknown, + request: Request, + args: unknown[], + thrown?: boolean + ) => Response | Promise) + | null; + endpoint?: string; + csrf?: boolean | ServerFunctionCSRFOptions; + codec?: JSONCodecOptions; + bodySizeLimit?: number; + maxArguments?: number; + secret?: string; +} ``` #### `provideEvent` @@ -409,12 +414,12 @@ calls during document SSR — e.g. frames' `frameTransformDirectResult`. #### `handleNoJS` - **Type:** `| (( - result: unknown, - request: Request, - args: unknown[], - thrown?: boolean - ) => Response | Promise) - | null` + result: unknown, + request: Request, + args: unknown[], + thrown?: boolean + ) => Response | Promise) +| null` Server-wide response builder for calls made without the client runtime (see `handleNoJS` in `HandleServerFunctionRequestOptions`); a @@ -526,13 +531,13 @@ be async. ```ts type WrapInvocationHook = ( - run: () => unknown, - context: { - id: string; - args: unknown[]; - event: ServerFunctionEvent; - request?: Request; - direct: boolean; - } + run: () => unknown, + context: { + id: string; + args: unknown[]; + event: ServerFunctionEvent; + request?: Request; + direct: boolean; + } ) => unknown; ``` diff --git a/src/routes/reference/(2)solid-web/(5)server-functions/invocation-context.mdx b/src/routes/reference/(2)solid-web/(5)server-functions/invocation-context.mdx index 001ecf5d6..67021043e 100644 --- a/src/routes/reference/(2)solid-web/(5)server-functions/invocation-context.mdx +++ b/src/routes/reference/(2)solid-web/(5)server-functions/invocation-context.mdx @@ -45,8 +45,8 @@ either entry. ```ts interface ServerFunctionInvocation { - id: string; -}; + id: string; +} ``` #### `id` diff --git a/src/routes/reference/(2)solid-web/(5)server-functions/invoke.mdx b/src/routes/reference/(2)solid-web/(5)server-functions/invoke.mdx index d975b8fa3..daa8e6063 100644 --- a/src/routes/reference/(2)solid-web/(5)server-functions/invoke.mdx +++ b/src/routes/reference/(2)solid-web/(5)server-functions/invoke.mdx @@ -32,9 +32,9 @@ import { invoke } from "@solidjs/web/server-functions"; ```ts function invoke( - fn: (...args: A) => R, - options: InvokeOptions, - ...args: A + fn: (...args: A) => R, + options: InvokeOptions, + ...args: A ): R; ``` @@ -75,10 +75,10 @@ no-ops (they describe a wire that does not exist). ```ts interface InvokeOptions { - signal?: AbortSignal; - keepalive?: boolean; - priority?: "high" | "low" | "auto"; -}; + signal?: AbortSignal; + keepalive?: boolean; + priority?: "high" | "low" | "auto"; +} ``` #### `signal` @@ -118,7 +118,7 @@ invocation-scoped keys. ```ts type ServerFunctionInvoker = ( - args: A, - options?: InvokeOptions + args: A, + options?: InvokeOptions ) => R; ``` diff --git a/src/routes/reference/(2)solid-web/(5)server-functions/live.mdx b/src/routes/reference/(2)solid-web/(5)server-functions/live.mdx index 4e0832ff9..ba779089b 100644 --- a/src/routes/reference/(2)solid-web/(5)server-functions/live.mdx +++ b/src/routes/reference/(2)solid-web/(5)server-functions/live.mdx @@ -32,7 +32,7 @@ import { live } from "@solidjs/web/server-functions"; ```ts function live( - fn: (...args: A) => R + fn: (...args: A) => R ): LiveServerFunction>; ``` @@ -64,10 +64,10 @@ export const stockPrice = live(async function* (symbol: string) { ```ts interface LiveServerFunction { - (...args: A): LiveSource; - readonly id: string; - readonly url: string; -}; + (...args: A): LiveSource; + readonly id: string; + readonly url: string; +} ``` #### `id` @@ -93,7 +93,7 @@ end was a definite rejection (4xx) failing fast instead of retrying. ```ts type LiveSource = R & { - onstatus?: (state: LiveSourceStatus, error?: unknown) => void; + onstatus?: (state: LiveSourceStatus, error?: unknown) => void; }; ``` diff --git a/src/routes/reference/(2)solid-web/(5)server-functions/metadata.mdx b/src/routes/reference/(2)solid-web/(5)server-functions/metadata.mdx index c6b140a5a..1de113e61 100644 --- a/src/routes/reference/(2)solid-web/(5)server-functions/metadata.mdx +++ b/src/routes/reference/(2)solid-web/(5)server-functions/metadata.mdx @@ -28,7 +28,11 @@ Attaches declaration metadata to a server-function reference and returns the ref ## Import ```ts -import { withMeta, getServerFunctionMetadata, isServerFunction } from "@solidjs/web/server-functions"; +import { + withMeta, + getServerFunctionMetadata, + isServerFunction, +} from "@solidjs/web/server-functions"; ``` ## `withMeta` @@ -89,9 +93,7 @@ Returns whether a value is a server-function reference. ### Type signature ```ts -function isServerFunction( - fn: unknown -): fn is ServerFunction; +function isServerFunction(fn: unknown): fn is ServerFunction; ``` ### Parameters @@ -115,10 +117,10 @@ build-stable identity. ```ts interface ServerFunction { - (...args: A): Promise; - readonly id: string; - readonly url: string; -}; + (...args: A): Promise; + readonly id: string; + readonly url: string; +} ``` #### `id` @@ -144,10 +146,10 @@ over earlier ones. ```ts interface ServerFunctionMetadata { - readonly method?: "GET" | "POST"; - readonly name?: string; - readonly [key: string]: unknown; -}; + readonly method?: "GET" | "POST"; + readonly name?: string; + readonly [key: string]: unknown; +} ``` #### `method` diff --git a/src/routes/reference/(2)solid-web/(5)server-functions/observe-calls.mdx b/src/routes/reference/(2)solid-web/(5)server-functions/observe-calls.mdx index f2f6a2681..419896d3e 100644 --- a/src/routes/reference/(2)solid-web/(5)server-functions/observe-calls.mdx +++ b/src/routes/reference/(2)solid-web/(5)server-functions/observe-calls.mdx @@ -33,7 +33,7 @@ import { observeServerFunctionCalls } from "@solidjs/web/server-functions"; ```ts function observeServerFunctionCalls( - observer: (call: ServerFunctionCall) => void + observer: (call: ServerFunctionCall) => void ): () => void; ``` @@ -48,20 +48,21 @@ function observeServerFunctionCalls( ### `ServerFunctionCall` ```ts -type ServerFunctionCall = ServerFunctionRequestCall | ServerFunctionResponseCall; +type ServerFunctionCall = + ServerFunctionRequestCall | ServerFunctionResponseCall; ``` ### `ServerFunctionRequestCall` ```ts interface ServerFunctionRequestCall { - type: "request"; - id: string; - instance: string; - request: Request; - meta: ServerFunctionMetadata | undefined; - time: number; -}; + type: "request"; + id: string; + instance: string; + request: Request; + meta: ServerFunctionMetadata | undefined; + time: number; +} ``` #### `type` @@ -92,13 +93,13 @@ interface ServerFunctionRequestCall { ```ts interface ServerFunctionResponseCall { - type: "response"; - id: string; - instance: string; - response: Response; - meta: ServerFunctionMetadata | undefined; - time: number; -}; + type: "response"; + id: string; + instance: string; + response: Response; + meta: ServerFunctionMetadata | undefined; + time: number; +} ``` #### `type` diff --git a/src/routes/reference/(2)solid-web/(5)server-functions/progressive-enhancement.mdx b/src/routes/reference/(2)solid-web/(5)server-functions/progressive-enhancement.mdx index cdbf36580..6296d94f3 100644 --- a/src/routes/reference/(2)solid-web/(5)server-functions/progressive-enhancement.mdx +++ b/src/routes/reference/(2)solid-web/(5)server-functions/progressive-enhancement.mdx @@ -35,8 +35,13 @@ import { createNoJSHandler } from "@solidjs/web/server-functions/server"; ```ts function createNoJSHandler( - options?: NoJSHandlerOptions -): (result: unknown, request: Request, args: unknown[], thrown?: boolean) => Promise; + options?: NoJSHandlerOptions +): ( + result: unknown, + request: Request, + args: unknown[], + thrown?: boolean +) => Promise; ``` ## Parameters @@ -67,12 +72,12 @@ returned one fills `result` — mirroring the split a scripted call sees. ```ts interface FlashSubmission { - input: any[]; - url: string; - result?: any; - error?: any; - truncated?: boolean; -}; + input: any[]; + url: string; + result?: any; + error?: any; + truncated?: boolean; +} ``` #### `input` @@ -122,8 +127,8 @@ Options for `createNoJSHandler`. ```ts interface NoJSHandlerOptions { - base?: string; -}; + base?: string; +} ``` #### `base` diff --git a/src/routes/reference/(2)solid-web/(5)server-functions/single-flight.mdx b/src/routes/reference/(2)solid-web/(5)server-functions/single-flight.mdx index 5ab4ae6ca..ab585ecdc 100644 --- a/src/routes/reference/(2)solid-web/(5)server-functions/single-flight.mdx +++ b/src/routes/reference/(2)solid-web/(5)server-functions/single-flight.mdx @@ -30,7 +30,10 @@ Decodes a server-function response, including response envelopes and single-flig ## Import ```ts -import { decodeResponse, subscribeFlightData } from "@solidjs/web/server-functions"; +import { + decodeResponse, + subscribeFlightData, +} from "@solidjs/web/server-functions"; import { registerFlightDataSource } from "@solidjs/web/server-functions/server"; ``` @@ -40,8 +43,8 @@ import { registerFlightDataSource } from "@solidjs/web/server-functions/server"; ```ts function decodeResponse( - response: Response, - codecOptions?: JSONCodecOptions + response: Response, + codecOptions?: JSONCodecOptions ): Promise; ``` @@ -65,7 +68,10 @@ function. ### Type signature ```ts -function registerFlightDataSource(source: string, hook: CollectFlightDataHook): () => void; +function registerFlightDataSource( + source: string, + hook: CollectFlightDataHook +): () => void; ``` ### Parameters @@ -85,10 +91,12 @@ Registers the integration that receives data folded into a mutation response. ### Type signature ```ts -function subscribeFlightData(consumer: FlightDataConsumer): () => void; function subscribeFlightData( - source: string, - consumer: FlightDataConsumer + consumer: FlightDataConsumer +): () => void; +function subscribeFlightData( + source: string, + consumer: FlightDataConsumer ): () => void; ``` @@ -126,8 +134,8 @@ pre-digested on the outcome (`targetUrl`, `revalidateKeys`, ```ts type CollectFlightDataHook = ( - event: ServerFunctionEvent, - outcome: ServerFunctionOutcome + event: ServerFunctionEvent, + outcome: ServerFunctionOutcome ) => unknown | Promise; ``` @@ -140,8 +148,8 @@ value is returned to the caller, so caches are seeded first. ```ts type FlightDataConsumer = ( - data: D, - context: FlightDataContext + data: D, + context: FlightDataContext ) => void | Promise; ``` @@ -155,8 +163,8 @@ not from here. ```ts interface FlightDataContext { - response: Response; -}; + response: Response; +} ``` #### `response` @@ -173,15 +181,15 @@ assuming one. ```ts interface ServerFunctionOutcome { - id: string; - value: unknown; - response: Response | undefined; - request: Request; - thrown: boolean; - targetUrl: string | undefined; - revalidateKeys: string[] | undefined; - foldedHeaders: Headers; -}; + id: string; + value: unknown; + response: Response | undefined; + request: Request; + thrown: boolean; + targetUrl: string | undefined; + revalidateKeys: string[] | undefined; + foldedHeaders: Headers; +} ``` #### `id` @@ -265,9 +273,9 @@ codec-serializable value. ```ts interface SingleFlightPayload { - value: T; - data: D; -}; + value: T; + data: D; +} ``` #### `value` diff --git a/src/routes/reference/(2)solid-web/(6)request-response/cookies.mdx b/src/routes/reference/(2)solid-web/(6)request-response/cookies.mdx index 9056e7028..ae001a4dd 100644 --- a/src/routes/reference/(2)solid-web/(6)request-response/cookies.mdx +++ b/src/routes/reference/(2)solid-web/(6)request-response/cookies.mdx @@ -41,7 +41,9 @@ import { parseCookieHeader, serializeCookie } from "@solidjs/web"; ### Type signature ```ts -function parseCookieHeader(header: string | null | undefined): Record; +function parseCookieHeader( + header: string | null | undefined +): Record; ``` ### Parameters @@ -57,7 +59,11 @@ serializeCookie API reference. ### Type signature ```ts -function serializeCookie(name: string, value: string, options: CookieOptions = {}): string; +function serializeCookie( + name: string, + value: string, + options: CookieOptions = {} +): string; ``` ### Parameters @@ -87,15 +93,15 @@ function serializeCookie(name: string, value: string, options: CookieOptions = { ```ts interface CookieOptions { - path?: string; - domain?: string; - maxAge?: number; - expires?: Date; - httpOnly?: boolean; - secure?: boolean; - sameSite?: "lax" | "strict" | "none" | "Lax" | "Strict" | "None"; - partitioned?: boolean; -}; + path?: string; + domain?: string; + maxAge?: number; + expires?: Date; + httpOnly?: boolean; + secure?: boolean; + sameSite?: "lax" | "strict" | "none" | "Lax" | "Strict" | "None"; + partitioned?: boolean; +} ``` #### `path` diff --git a/src/routes/reference/(2)solid-web/(6)request-response/get-request-event.mdx b/src/routes/reference/(2)solid-web/(6)request-response/get-request-event.mdx index c35973cf1..0d238944e 100644 --- a/src/routes/reference/(2)solid-web/(6)request-response/get-request-event.mdx +++ b/src/routes/reference/(2)solid-web/(6)request-response/get-request-event.mdx @@ -58,9 +58,9 @@ extend this shape with richer fields (e.g. a `response` head — see ```ts interface RequestEvent { - request: Request; - locals: RequestEventLocals; -}; + request: Request; + locals: RequestEventLocals; +} ``` #### `request` @@ -80,9 +80,9 @@ identity flows through the re-export chain): ```ts declare module "@solidjs/web" { - interface RequestEventLocals { - user: User; - } + interface RequestEventLocals { + user: User; + } } ``` @@ -94,8 +94,8 @@ read as `any` rather than erroring, a deliberate trade (a strict-only ```ts interface RequestEventLocals { - [key: string | number | symbol]: any; -}; + [key: string | number | symbol]: any; +} ``` ### `ResponseStub` @@ -105,11 +105,11 @@ head integrations expose as `event.response` via module augmentation. ```ts interface ResponseStub { - status?: number; - statusText?: string; - headers: Headers; - committed?: boolean; -}; + status?: number; + statusText?: string; + headers: Headers; + committed?: boolean; +} ``` #### `status` diff --git a/src/routes/reference/(2)solid-web/(6)request-response/get-trace-context.mdx b/src/routes/reference/(2)solid-web/(6)request-response/get-trace-context.mdx index 60d184d04..70e27605a 100644 --- a/src/routes/reference/(2)solid-web/(6)request-response/get-trace-context.mdx +++ b/src/routes/reference/(2)solid-web/(6)request-response/get-trace-context.mdx @@ -63,14 +63,14 @@ otherwise. Read with `getTraceContext()`. ```ts interface TraceContext { - traceId: string; - spanId: string; - parentId?: string; - sampled?: boolean; - state?: string; - baggage?: string; - entries: Record; -}; + traceId: string; + spanId: string; + parentId?: string; + sampled?: boolean; + state?: string; + baggage?: string; + entries: Record; +} ``` #### `traceId` @@ -131,7 +131,9 @@ shell flush or the first `getTraceContext()`, whichever comes first. Return `undefined` to leave the derivation alone. ```ts -type TraceProvider = (request: Request | undefined) => Partial | undefined; +type TraceProvider = ( + request: Request | undefined +) => Partial | undefined; ``` ### `TraceSlot` @@ -142,8 +144,8 @@ later install replaces it — the single-plugin shape, not a chain. ```ts interface TraceSlot { - provide(provider: TraceProvider): () => void; -}; + provide(provider: TraceProvider): () => void; +} ``` #### `provide` diff --git a/src/routes/reference/(2)solid-web/(6)request-response/provide-request-event.mdx b/src/routes/reference/(2)solid-web/(6)request-response/provide-request-event.mdx index 51a324bec..860ffd5f9 100644 --- a/src/routes/reference/(2)solid-web/(6)request-response/provide-request-event.mdx +++ b/src/routes/reference/(2)solid-web/(6)request-response/provide-request-event.mdx @@ -30,7 +30,10 @@ import { provideRequestEvent } from "@solidjs/web/storage"; ## Type signature ```ts -function provideRequestEvent(init: T, cb: () => U): U; +function provideRequestEvent( + init: T, + cb: () => U +): U; ``` ## Parameters diff --git a/src/routes/reference/(2)solid-web/(6)request-response/redirect.mdx b/src/routes/reference/(2)solid-web/(6)request-response/redirect.mdx index 489121b7e..86dadd1ef 100644 --- a/src/routes/reference/(2)solid-web/(6)request-response/redirect.mdx +++ b/src/routes/reference/(2)solid-web/(6)request-response/redirect.mdx @@ -87,9 +87,9 @@ function isHref(value: unknown): value is Href; ```ts interface Href { - [HREF]: true | string; - toString(): string; -}; + [HREF]: true | string; + toString(): string; +} ``` #### `[HREF]` @@ -97,7 +97,7 @@ interface Href { - **Type:** `true | string` The brand doubles as a channel: when the slot holds a string it is the -value's *logical* path — the routable pathname before an integration's +value's _logical_ path — the routable pathname before an integration's display rendering (for example, a hash router's `#` prefix). `redirect()` prefers it over coercion so Location headers carry routable paths; `toString()` remains the display href for the DOM. `true` brands a value whose @@ -113,8 +113,8 @@ string form is already logical. ```ts interface ResponseHelperInit extends ResponseInit { - revalidate?: string | string[]; -}; + revalidate?: string | string[]; +} ``` #### `revalidate` diff --git a/src/routes/reference/(2)solid-web/(6)request-response/reload.mdx b/src/routes/reference/(2)solid-web/(6)request-response/reload.mdx index 96433e32e..18da9871e 100644 --- a/src/routes/reference/(2)solid-web/(6)request-response/reload.mdx +++ b/src/routes/reference/(2)solid-web/(6)request-response/reload.mdx @@ -62,8 +62,8 @@ return reload({ revalidate: "todos" }); ```ts interface ResponseHelperInit extends ResponseInit { - revalidate?: string | string[]; -}; + revalidate?: string | string[]; +} ``` #### `revalidate` diff --git a/src/routes/reference/(2)solid-web/(6)request-response/respond.mdx b/src/routes/reference/(2)solid-web/(6)request-response/respond.mdx index 0ec2aa104..3d6c5d80c 100644 --- a/src/routes/reference/(2)solid-web/(6)request-response/respond.mdx +++ b/src/routes/reference/(2)solid-web/(6)request-response/respond.mdx @@ -37,10 +37,7 @@ import { respond, isResponseEnvelope } from "@solidjs/web"; ### Type signature ```ts -function respond( - value: T, - init?: ResponseHelperInit -): ResponseEnvelope; +function respond(value: T, init?: ResponseHelperInit): ResponseEnvelope; ``` ### Parameters @@ -102,9 +99,9 @@ while client-only integrations read `value` directly — no reparse. ```ts interface ResponseEnvelope { - response: Response | undefined; - value: T; -}; + response: Response | undefined; + value: T; +} ``` #### `response` @@ -121,8 +118,8 @@ interface ResponseEnvelope { ```ts interface ResponseHelperInit extends ResponseInit { - revalidate?: string | string[]; -}; + revalidate?: string | string[]; +} ``` #### `revalidate` diff --git a/src/routes/reference/(5)vite-plugin-solid/(2)start.mdx b/src/routes/reference/(5)vite-plugin-solid/(2)start.mdx index 5756ccea0..0cbddc107 100644 --- a/src/routes/reference/(5)vite-plugin-solid/(2)start.mdx +++ b/src/routes/reference/(5)vite-plugin-solid/(2)start.mdx @@ -29,6 +29,7 @@ interface StartOptions { setup?: string; env?: boolean | string; external?: boolean; + node?: boolean; } ``` @@ -165,6 +166,48 @@ The plugin ignores `external` in client mode. A host-owned, non-runnable `ssr` development environment is detected without this option. Use `serverFunctions.devMiddleware: false` to hand over only development endpoint dispatch. +### `node` + +- **Type:** `boolean` +- **Default:** `false` + +Emits `dist/server/node.js`, a complete Node server, next to `dist/server/server.js` during `vite build`. +`server.js`, `handleRequest`, and the default `{ fetch }` export do not change. + +The emitted module: + +- Serves the client build as static files before the handler, under a root-relative `base`. + Files under `build.assetsDir` carry `Cache-Control: public, max-age=31536000, immutable`; other files carry `public, max-age=0, must-revalidate` and `Last-Modified`. + Dot-segment paths and `..` traversal are refused. +- Passes remaining requests to `handleRequest(request, { event: { nativeEvent: req } })` through the bridge used by `vite dev` and `vite preview`. + A thrown error logs to `console.error` and answers `500`. +- In client mode with server functions, serves `dist/client/index.html` for HTML `GET` requests that match no file and dispatches the server-function endpoint. +- Listens on `PORT` (default `3000`) and `HOST` when run directly with `node dist/server/node.js`. + +```ts +// dist/server/node.js +import type { IncomingMessage, Server, ServerResponse } from "node:http"; + +type Listener = (req: IncomingMessage, res: ServerResponse) => Promise; + +interface ListenerOptions { + static?: boolean; + event?: (req: IncomingMessage) => Record; +} + +export declare const listener: Listener; // createListener() +export declare function createListener(options?: ListenerOptions): Listener; +export declare function serve( + options?: { port?: number; host?: string } & ListenerOptions +): Server; +``` + +`static: false` skips the file lookup and the client-mode `index.html` fallback. +`event` returns fields merged over `{ nativeEvent: req }`. + +The build emits `node.js` only in the `ssr` environment and only when that build contains `server.js`. +The plugin warns and emits nothing with `external`, and in client mode without `serverFunctions`. + ## Valid mode combinations ### Transform only @@ -196,6 +239,7 @@ solidPlugin({ start: true, ssr: true }); - Development streams HTML through the runnable `ssr` environment. - `vite build` builds the client first, writes client assets and a Vite manifest to `dist/client`, and writes `dist/server/server.js`. +- With `node: true`, the build also writes `dist/server/node.js`. - The server bundle exports `handleRequest(request, options?)`. - `vite preview` serves client assets and sends other requests through the built handler. @@ -203,4 +247,5 @@ solidPlugin({ start: true, ssr: true }); `serverFunctions` composes with either start mode. In client mode, pages remain static while `dist/server/server.js` remains available for endpoint requests. +With `node: true`, `dist/server/node.js` serves the static pages and the endpoint from one process. In SSR mode, the same handler dispatches the endpoint before rendering a page.