diff --git a/.github/workflows/release-experimental.yml b/.github/workflows/release-experimental.yml index cf1171bb..6aa69d27 100644 --- a/.github/workflows/release-experimental.yml +++ b/.github/workflows/release-experimental.yml @@ -131,4 +131,4 @@ jobs: - name: Publish @lazarv/create-react-server if: steps.prepare-create-react-server.outcome == 'success' working-directory: ./packages/create-react-server - run: pnpm publish --provenance --access=public --tag=latest \ No newline at end of file + run: pnpm publish --provenance --access=public --tag=latest diff --git a/docs/src/components/Terminal.module.css b/docs/src/components/Terminal.module.css index 11f8dd3a..79b7530c 100644 --- a/docs/src/components/Terminal.module.css +++ b/docs/src/components/Terminal.module.css @@ -235,7 +235,9 @@ background: #1e1e2e; color: #cdd6f4; padding: 1rem 1.25rem; - font-family: "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", "Menlo", "Consolas", monospace; + font-family: + "SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", "Menlo", + "Consolas", monospace; font-size: 0.95rem; line-height: 1.6; white-space: nowrap; @@ -263,6 +265,11 @@ } @keyframes blink { - 0%, 100% { opacity: 1; } - 50% { opacity: 0; } + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0; + } } diff --git a/docs/src/pages/en/(pages)/features/caching.mdx b/docs/src/pages/en/(pages)/features/caching.mdx index 0c5c73be..3e526158 100644 --- a/docs/src/pages/en/(pages)/features/caching.mdx +++ b/docs/src/pages/en/(pages)/features/caching.mdx @@ -260,11 +260,135 @@ export default { `@lazarv/react-server` provides a few built-in cache providers that you can use out of the box without any configuration. These are: - `memory`: A simple in-memory cache provider. This is the default cache provider. -- `request`: A cache provider that only lives for the duration of the request. This is useful for caching data that is only needed for the current request. +- `request`: A cache provider that only lives for the duration of the request. This is useful for deduplicating expensive computations within a single request. The cached value is shared across both RSC and SSR environments, so the function body runs only once per request regardless of how many components consume it. See [Request-scoped caching](#request-scoped-caching) for details. - `null`: A cache provider that does not store any data. This is useful for disabling caching in specific parts of your application. Useful with a cache provider alias. - `local`: A cache provider that uses the browser's local storage. This is useful for caching data that needs to persist across page reloads. - `session`: A cache provider that uses the browser's session storage. This is useful for caching data that needs to persist across page reloads, but only for the current session. + +## Request-scoped caching + + +The `request` cache provider deduplicates function calls within a single HTTP request. When you mark a function with `"use cache: request"`, the function body executes only once per request — every subsequent call with the same arguments returns the same cached result, even across RSC and SSR rendering environments. + +This is useful for expensive computations or data fetching that multiple components depend on within the same page render. + +### Defining a request-cached function + +Use the `"use cache: request"` directive at the top of any function. The function can be async and can return any RSC-serializable value, including `Date` objects, nested objects, and arrays. + +```mjs filename="get-request-data.mjs" +let computeCount = 0; + +export async function getRequestData() { + "use cache: request"; + // Simulate an async operation + await new Promise((resolve) => setTimeout(resolve, 5)); + computeCount++; + return { + timestamp: Date.now(), + random: Math.random(), + computeCount, + createdAt: new Date(), + }; +} +``` + +In this example, `getRequestData` will only execute once per request. Every component that calls it during the same request receives identical `timestamp`, `random`, and `computeCount` values. + +### Using in server components + +Server components can `await` a request-cached function directly. Multiple server components calling the same function will share the result. + +```jsx filename="App.jsx" +import { getRequestData } from "./get-request-data.mjs"; + +async function First() { + const data = await getRequestData(); + return