@vitejs/plugin-rsc 0.4.10-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +447 -0
  2. package/dist/browser-D8OPzpF5.js +35 -0
  3. package/dist/browser-DjnGtEmB.d.ts +15 -0
  4. package/dist/browser-Dw18EFgE.d.ts +6 -0
  5. package/dist/browser-LizIyxet.js +17 -0
  6. package/dist/browser-QWbIPyhO.js +17 -0
  7. package/dist/browser.d.ts +4 -0
  8. package/dist/browser.js +7 -0
  9. package/dist/client-edAdk2GF.js +23 -0
  10. package/dist/core/browser.d.ts +2 -0
  11. package/dist/core/browser.js +5 -0
  12. package/dist/core/plugin.d.ts +6 -0
  13. package/dist/core/plugin.js +3 -0
  14. package/dist/core/rsc.d.ts +3 -0
  15. package/dist/core/rsc.js +5 -0
  16. package/dist/core/ssr.d.ts +3 -0
  17. package/dist/core/ssr.js +5 -0
  18. package/dist/dist-DEF94lDJ.js +41 -0
  19. package/dist/encryption-utils-BDwwcMVT.js +73 -0
  20. package/dist/extra/browser.d.ts +7 -0
  21. package/dist/extra/browser.js +83 -0
  22. package/dist/extra/rsc.d.ts +2 -0
  23. package/dist/extra/rsc.js +60 -0
  24. package/dist/extra/ssr.d.ts +10 -0
  25. package/dist/extra/ssr.js +35 -0
  26. package/dist/index-BHqtj9tT.d.ts +26 -0
  27. package/dist/index.d.ts +23 -0
  28. package/dist/index.js +8 -0
  29. package/dist/plugin-BZEsXXjV.js +1442 -0
  30. package/dist/plugin-CZbI4rhS.js +24 -0
  31. package/dist/plugin-Dg2agPFN.d.ts +88 -0
  32. package/dist/plugin.d.ts +2 -0
  33. package/dist/plugin.js +8 -0
  34. package/dist/react/browser.d.ts +4 -0
  35. package/dist/react/browser.js +6 -0
  36. package/dist/react/rsc.d.ts +4 -0
  37. package/dist/react/rsc.js +6 -0
  38. package/dist/react/ssr.d.ts +4 -0
  39. package/dist/react/ssr.js +6 -0
  40. package/dist/rpc-tGuLT8PD.js +47 -0
  41. package/dist/rsc-BOV3yNSd.d.ts +12 -0
  42. package/dist/rsc-Cmvt9txp.d.ts +13 -0
  43. package/dist/rsc-DHfL29FT.js +36 -0
  44. package/dist/rsc-DKA6wwTB.js +78 -0
  45. package/dist/rsc-DgrejoNf.d.ts +15 -0
  46. package/dist/rsc-DmPsJrxF.js +42 -0
  47. package/dist/rsc-html-stream/browser.d.ts +4 -0
  48. package/dist/rsc-html-stream/browser.js +7 -0
  49. package/dist/rsc-html-stream/ssr.d.ts +6 -0
  50. package/dist/rsc-html-stream/ssr.js +7 -0
  51. package/dist/rsc.d.ts +13 -0
  52. package/dist/rsc.js +8 -0
  53. package/dist/server-DGTepepH.js +67 -0
  54. package/dist/shared-CEyKoKAb.js +22 -0
  55. package/dist/ssr-BOIYlvSn.js +23 -0
  56. package/dist/ssr-D5pxP29F.js +18 -0
  57. package/dist/ssr-D708H86k.d.ts +7 -0
  58. package/dist/ssr-DgSrGrln.d.ts +9 -0
  59. package/dist/ssr-Do_Ok_bB.js +47 -0
  60. package/dist/ssr.d.ts +4 -0
  61. package/dist/ssr.js +7 -0
  62. package/dist/utils/rpc.d.ts +7 -0
  63. package/dist/utils/rpc.js +3 -0
  64. package/dist/vendor/react-server-dom/LICENSE +21 -0
  65. package/dist/vendor/react-server-dom/README.md +5 -0
  66. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.browser.development.js +2785 -0
  67. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.browser.production.js +1664 -0
  68. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.edge.development.js +2959 -0
  69. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.edge.production.js +1845 -0
  70. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.node.development.js +3002 -0
  71. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.node.production.js +1894 -0
  72. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.node.unbundled.development.js +2964 -0
  73. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-client.node.unbundled.production.js +1859 -0
  74. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-node-register.js +69 -0
  75. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-plugin.js +400 -0
  76. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.browser.development.js +4079 -0
  77. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.browser.production.js +2806 -0
  78. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.edge.development.js +4187 -0
  79. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.edge.production.js +2845 -0
  80. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.node.development.js +4195 -0
  81. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.node.production.js +2902 -0
  82. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.node.unbundled.development.js +4158 -0
  83. package/dist/vendor/react-server-dom/cjs/react-server-dom-webpack-server.node.unbundled.production.js +2868 -0
  84. package/dist/vendor/react-server-dom/client.browser.js +7 -0
  85. package/dist/vendor/react-server-dom/client.edge.js +7 -0
  86. package/dist/vendor/react-server-dom/client.js +3 -0
  87. package/dist/vendor/react-server-dom/client.node.js +7 -0
  88. package/dist/vendor/react-server-dom/client.node.unbundled.js +7 -0
  89. package/dist/vendor/react-server-dom/esm/package.json +3 -0
  90. package/dist/vendor/react-server-dom/esm/react-server-dom-webpack-node-loader.production.js +515 -0
  91. package/dist/vendor/react-server-dom/index.js +12 -0
  92. package/dist/vendor/react-server-dom/node-register.js +3 -0
  93. package/dist/vendor/react-server-dom/package.json +111 -0
  94. package/dist/vendor/react-server-dom/plugin.js +3 -0
  95. package/dist/vendor/react-server-dom/server.browser.js +17 -0
  96. package/dist/vendor/react-server-dom/server.edge.js +18 -0
  97. package/dist/vendor/react-server-dom/server.js +6 -0
  98. package/dist/vendor/react-server-dom/server.node.js +18 -0
  99. package/dist/vendor/react-server-dom/server.node.unbundled.js +18 -0
  100. package/dist/vendor/react-server-dom/static.browser.js +12 -0
  101. package/dist/vendor/react-server-dom/static.edge.js +12 -0
  102. package/dist/vendor/react-server-dom/static.js +6 -0
  103. package/dist/vendor/react-server-dom/static.node.js +12 -0
  104. package/dist/vendor/react-server-dom/static.node.unbundled.js +12 -0
  105. package/dist/vite-utils-CcqBE-C4.js +64 -0
  106. package/dist/vite-utils.d.ts +21 -0
  107. package/dist/vite-utils.js +3 -0
  108. package/package.json +64 -0
  109. package/types/index.d.ts +19 -0
  110. package/types/virtual.d.ts +5 -0
package/README.md ADDED
@@ -0,0 +1,447 @@
1
+ # @vitejs/plugin-rsc
2
+
3
+ This package provides [React Server Components](https://react.dev/reference/rsc/server-components) (RSC) support for Vite.
4
+
5
+ ## Features
6
+
7
+ - **Framework-less RSC experience**: The plugin implements [RSC conventions](https://react.dev/reference/rsc/server-components) and provides low level `react-server-dom` runtime API without framework-specific abstractions.
8
+ - **CSS support**: CSS is automatically code-split both at client and server components and they are injected upon rendering.
9
+ - **HMR support**: Enables editing both client and server components without full page reloads.
10
+ - **Runtime agnostic**: Built on [Vite environment API](https://vite.dev/guide/api-environment.html) and works with other runtimes (e.g., [`@cloudflare/vite-plugin`](https://github.com/cloudflare/workers-sdk/tree/main/packages/vite-plugin-cloudflare)).
11
+
12
+ ## Getting Started
13
+
14
+ You can start a project by copying an example locally by:
15
+
16
+ ```sh
17
+ npx degit vitejs/vite-plugin-react/packages/plugin-rsc/examples/starter my-app
18
+ ```
19
+
20
+ ## Examples
21
+
22
+ - [`./examples/starter`](./examples/starter)
23
+ - This example provides an in-depth overview of API with inline comments to explain how they function within RSC-powered React application.
24
+ - [`./examples/react-router`](./examples/react-router)
25
+ - This demonstrates how to integrate [experimental React Router RSC API](https://remix.run/blog/rsc-preview) with this plugin.
26
+ It also includes `@cloudflare/vite-plugin` integration.
27
+ - [`./examples/basic`](./examples/basic)
28
+ - This is mainly used for e2e testing and include various advanced RSC usages (e.g. `"use cache"` example).
29
+ It also uses a high level `@vitejs/plugin-rsc/extra/{rsc,ssr,browser}` API for quick setup.
30
+ - [`./examples/ssg`](./examples/ssg)
31
+ - Static site generation (SSG) example with MDX and client components for interactivity.
32
+
33
+ ## Basic Concepts
34
+
35
+ This example is a simplified version of [`./examples/starter`](./examples/starter). You can read [`./examples/starter/src/framework/entry.{rsc,ssr,browser}.tsx`](./examples/starter/src/framework) for more in-depth commentary, which includes server function handling and client-side RSC re-fetching/re-rendering.
36
+
37
+ This is the diagram to show the basic flow of RSC rendering process. See also https://github.com/hi-ogawa/vite-plugins/discussions/606.
38
+
39
+ ```mermaid
40
+ graph TD
41
+
42
+ subgraph "<strong>rsc environment</strong>"
43
+ A["React virtual dom tree"] --> |"[@vitejs/plugin-rsc/rsc]<br /><code>renderToReadableStream</code>"| B1["RSC Stream"];
44
+ end
45
+
46
+ B1 --> B2
47
+ B1 --> B3
48
+
49
+ subgraph "<strong>ssr environment</strong>"
50
+ B2["RSC Stream"] --> |"[@vitejs/plugin-rsc/ssr]<br /><code>createFromReadableStream</code>"| C1["React virtual dom tree"];
51
+ C1 --> |"[react-dom/server]<br/>SSR"| E["HTML String/Stream"];
52
+ end
53
+
54
+ subgraph "<strong>client environment</strong>"
55
+ B3["RSC Stream"] --> |"[@vitejs/plugin-rsc/browser]<br /><code>createFromReadableStream</code>"| C2["React virtual dom tree"];
56
+ C2 --> |"[react-dom/client]<br/>CSR: mount, hydration"| D["DOM Elements"];
57
+ end
58
+
59
+ style A fill:#D6EAF8,stroke:#333,stroke-width:2px
60
+ style B1 fill:#FEF9E7,stroke:#333,stroke-width:2px
61
+ style B2 fill:#FEF9E7,stroke:#333,stroke-width:2px
62
+ style B3 fill:#FEF9E7,stroke:#333,stroke-width:2px
63
+ style C1 fill:#D6EAF8,stroke:#333,stroke-width:2px
64
+ style C2 fill:#D6EAF8,stroke:#333,stroke-width:2px
65
+ style D fill:#D5F5E3,stroke:#333,stroke-width:2px
66
+ style E fill:#FADBD8,stroke:#333,stroke-width:2px
67
+ ```
68
+
69
+ - [`vite.config.ts`](./examples/starter/vite.config.ts)
70
+
71
+ ```js
72
+ import rsc from '@vitejs/plugin-rsc'
73
+ import { defineConfig } from 'vite'
74
+
75
+ export default defineConfig({
76
+ plugins: [
77
+ // add plugin
78
+ rsc(),
79
+ ],
80
+
81
+ // specify entry point for each environment.
82
+ environments: {
83
+ // `rsc` environment loads modules with `react-server` condition.
84
+ // this environment is responsible for:
85
+ // - RSC stream serialization (React VDOM -> RSC stream)
86
+ // - server functions handling
87
+ rsc: {
88
+ build: {
89
+ rollupOptions: {
90
+ input: {
91
+ index: './src/framework/entry.rsc.tsx',
92
+ },
93
+ },
94
+ },
95
+ },
96
+
97
+ // `ssr` environment loads modules without `react-server` condition.
98
+ // this environment is responsible for:
99
+ // - RSC stream deserialization (RSC stream -> React VDOM)
100
+ // - traditional SSR (React VDOM -> HTML string/stream)
101
+ // (NOTE: as it can be seen in the above diagram. SSR is technically an optional mechanism.)
102
+ ssr: {
103
+ build: {
104
+ rollupOptions: {
105
+ input: {
106
+ index: './src/framework/entry.ssr.tsx',
107
+ },
108
+ },
109
+ },
110
+ },
111
+
112
+ // client environment is used for hydration and client-side rendering
113
+ // this environment is responsible for:
114
+ // - RSC stream deserialization (RSC stream -> React VDOM)
115
+ // - traditional CSR (React VDOM -> Browser DOM tree mount/hydration)
116
+ // - refetch and re-render RSC
117
+ // - calling server functions
118
+ client: {
119
+ build: {
120
+ rollupOptions: {
121
+ input: {
122
+ index: './src/framework/entry.browser.tsx',
123
+ },
124
+ },
125
+ },
126
+ },
127
+ },
128
+ })
129
+ ```
130
+
131
+ - [`entry.rsc.tsx`](./examples/starter/src/framework/entry.rsc.tsx)
132
+
133
+ ```tsx
134
+ import * as ReactServer from '@vitejs/plugin-rsc/rsc' // re-export of react-server-dom/server.edge
135
+
136
+ // the plugin assumes `rsc` entry having default export of request handler
137
+ export default async function handler(request: Request): Promise<Response> {
138
+ // serialization React VDOM to RSC stream
139
+ const root = (
140
+ <html>
141
+ <body>
142
+ <h1>Test</h1>
143
+ </body>
144
+ </html>
145
+ )
146
+ const rscStream = ReactServer.renderToReadableStream(root)
147
+
148
+ // respond direct RSC stream request based on framework's convention
149
+ if (request.url.endsWith('.rsc')) {
150
+ return new Response(rscStream, {
151
+ headers: {
152
+ 'Content-type': 'text/x-component;charset=utf-8',
153
+ },
154
+ })
155
+ }
156
+
157
+ // delegate to SSR environment for html rendering
158
+ // `loadModule` is a helper API provided by the plugin for multi environment interaction.
159
+ const ssrEntry = await import.meta.viteRsc.loadModule<
160
+ typeof import('./entry.ssr.tsx')
161
+ >('ssr', 'index')
162
+ const htmlStream = await ssrEntry.handleSsr(rscStream)
163
+
164
+ // respond html
165
+ return new Response(htmlStream, {
166
+ headers: {
167
+ 'Content-type': 'text/html',
168
+ },
169
+ })
170
+ }
171
+ ```
172
+
173
+ - [`entry.ssr.tsx`](./examples/starter/src/framework/entry.ssr.tsx)
174
+
175
+ ```tsx
176
+ import * as ReactClient from '@vitejs/plugin-rsc/ssr' // re-export of react-server-dom/client.edge
177
+ import * as ReactDOMServer from 'react-dom/server.edge'
178
+
179
+ export async function handleSsr(rscStream: ReadableStream) {
180
+ // deserialize RSC stream back to React VDOM
181
+ const root = await ReactClient.createFromReadableStream(rscStream)
182
+
183
+ // helper API to allow referencing browser entry content from SSR environment
184
+ const bootstrapScriptContent =
185
+ await import.meta.viteRsc.loadBootstrapScriptContent('index')
186
+
187
+ // render html (traditional SSR)
188
+ const htmlStream = ReactDOMServer.renderToReadableStream(root, {
189
+ bootstrapScriptContent,
190
+ })
191
+
192
+ return htmlStream
193
+ }
194
+ ```
195
+
196
+ - [`entry.browser.tsx`](./examples/starter/src/framework/entry.browser.tsx)
197
+
198
+ ```tsx
199
+ import * as ReactClient from "@vitejs/plugin-rsc/browser"; // re-export of react-server-dom/client.browser
200
+ import * as ReactDOMClient from "react-dom/client";
201
+
202
+ async function main() {
203
+ // fetch and deserialize RSC stream back to React VDOM
204
+ const rscResponse = await fetch(window.location.href + ".rsc);
205
+ const root = await ReactClient.createFromReadableStream(rscResponse.body);
206
+
207
+ // hydration (traditional CSR)
208
+ ReactDOMClient.hydrateRoot(document, root);
209
+ }
210
+
211
+ main();
212
+ ```
213
+
214
+ ## `react-server-dom` API
215
+
216
+ ### `@vitejs/plugin-rsc/rsc`
217
+
218
+ This module re-exports RSC runtime API provided by `react-server-dom/server.edge`
219
+
220
+ - `renderToReadableStream`: RSC serialization (React VDOM -> RSC stream)
221
+ - `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM). This is also available on rsc environment itself. For example, it allows saving serailized RSC and deserializing it for later use.
222
+ - `decodeAction/decodeReply/loadServerAction`: server function related...
223
+
224
+ ### `@vitejs/plugin-rsc/ssr`
225
+
226
+ This module re-exports RSC runtime API provided by `react-server-dom/client.edge`
227
+
228
+ - `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM)
229
+
230
+ ### `@vitejs/plugin-rsc/browser`
231
+
232
+ This module re-exports RSC runtime API provided by `react-server-dom/client.browser`
233
+
234
+ - `createFromReadableStream`: RSC deserialization (RSC stream -> React VDOM)
235
+ - `createFromFetch`: a robust way of `createFromReadableStream((await fetch("...")).body)`
236
+ - `encodeReply/setServerCallback`: server function related...
237
+
238
+ ## Environment helper API
239
+
240
+ The plugin provides an additional helper for multi environment interaction.
241
+
242
+ ### available on `rsc` or `ssr` environment
243
+
244
+ #### `import.meta.viteRsc.loadModule`
245
+
246
+ - Type: `(environmentName: "ssr" | "rsc", entryName: string) => Promise<T>`
247
+
248
+ This allows importing `ssr` environment module specified by `environments.ssr.build.rollupOptions.input[entryName]` inside `rsc` environment and vice versa.
249
+
250
+ During development, by default, this API assumes both `rsc` and `ssr` environments execute under the main Vite process. When enabling `rsc({ loadModuleDevProxy: true })` plugin option, the loaded module is implemented as a proxy with `fetch`-based RPC to call in node environment on the main Vite process, which for example, allows `rsc` environment inside cloudflare workers to access `ssr` environment on the main Vite process.
251
+
252
+ During production build, this API will be rewritten into a static import of the specified entry of other environment build and the modules are executed inside the same runtime.
253
+
254
+ For example,
255
+
256
+ ```js
257
+ // ./entry.rsc.tsx
258
+ const ssrModule = await import.meta.viteRsc.loadModule("ssr", "index");
259
+ ssrModule.renderHTML(...);
260
+
261
+ // ./entry.ssr.tsx (with environments.ssr.build.rollupOptions.input.index = "./entry.ssr.tsx")
262
+ export function renderHTML(...) {}
263
+ ```
264
+
265
+ ### available on `rsc` environment
266
+
267
+ #### `import.meta.viteRsc.loadCss`
268
+
269
+ - Type: `(importer?: string) => React.ReactNode`
270
+
271
+ This allows collecting css which is imported through a current server module and injecting them inside server components.
272
+
273
+ ```tsx
274
+ import './test.css'
275
+ import dep from './dep.tsx'
276
+
277
+ export function ServerPage() {
278
+ // this will include css assets for "test.css"
279
+ // and any css transitively imported through "dep.tsx"
280
+ return (
281
+ <>
282
+ {import.meta.viteRsc.loadCss()}
283
+ ...
284
+ </>
285
+ )
286
+ }
287
+ ```
288
+
289
+ Where specifying `loadCss(<id>)`, it will collect css through the server module resolved by `<id>`.
290
+
291
+ ```tsx
292
+ // virtual:my-framework-helper
293
+ export function Assets() {
294
+ return <>
295
+ {import.meta.viteRsc.loadCss("/routes/home.tsx")}
296
+ {import.meta.viteRsc.loadCss("/routes/about.tsx")}
297
+ {...}
298
+ </>
299
+ }
300
+
301
+ // user-app.tsx
302
+ import { Assets } from "virtual:my-framework-helper";
303
+
304
+ export function UserApp() {
305
+ return <html>
306
+ <head>
307
+ <Assets />
308
+ </head>
309
+ <body>...</body>
310
+ </html>
311
+ }
312
+ ```
313
+
314
+ #### `<id>?vite-rsc-css-export=<name>`
315
+
316
+ This special query convention provides automatic injection of `import.meta.viteRsc.loadCss`.
317
+
318
+ For example,
319
+
320
+ ```tsx
321
+ // my-route.tsx
322
+ export function Page(props) {
323
+ return <div>...</div>
324
+ }
325
+
326
+ // my-route.css?vite-rsc-css-export=Page
327
+ function Page(props) {
328
+ return <div>...</div>
329
+ }
330
+
331
+ function __Page(props) {
332
+ return (
333
+ <>
334
+ {import.meta.viteRsc.loadCss()}
335
+ <Page {...props} />
336
+ </>
337
+ )
338
+ }
339
+
340
+ export { __Page as Page }
341
+ ```
342
+
343
+ ### available on `ssr` environment
344
+
345
+ #### `import.meta.viteRsc.loadBootstrapScriptContent("index")`
346
+
347
+ This provides a raw js code to execute a browser entry file specified by `environments.client.build.rollupOptions.input.index`. This is intended to be used with React DOM SSR API, such as [`renderToReadableStream`](https://react.dev/reference/react-dom/server/renderToReadableStream)
348
+
349
+ ```js
350
+ import bootstrapScriptContent from 'virtual:vite-rsc/bootstrap-script-content'
351
+ import { renderToReadableStream } from 'react-dom/server.edge'
352
+
353
+ const bootstrapScriptContent =
354
+ await import.meta.viteRsc.loadBootstrapScriptContent('index')
355
+ const htmlStream = await renderToReadableStream(reactNode, {
356
+ bootstrapScriptContent,
357
+ })
358
+ ```
359
+
360
+ ### available on `client` environment
361
+
362
+ #### `rsc:update` event
363
+
364
+ This event is fired when server modules are updated, which can be used to trigger re-fetching and re-rendering of RSC components on browser.
365
+
366
+ ```js
367
+ import * as ReactClient from '@vitejs/plugin-rsc/browser'
368
+
369
+ import.meta.hot.on('rsc:update', async () => {
370
+ // re-fetch RSC stream
371
+ const rscPayload = await ReactClient.createFromFetch(
372
+ fetch(window.location.href + '.rsc'),
373
+ )
374
+ // re-render ...
375
+ })
376
+ ```
377
+
378
+ ## Plugin API
379
+
380
+ ### `@vitejs/plugin-rsc`
381
+
382
+ ```js
383
+ import rsc from '@vitejs/plugin-rsc'
384
+ import { defineConfig } from 'vite'
385
+
386
+ export default defineConfig({
387
+ plugins: [
388
+ rsc({
389
+ // this is only a shorthand of specifying each rollup input via
390
+ // `environments[name].build.rollupOptions.input.index`
391
+ entries: {
392
+ rsc: '...',
393
+ ssr: '...',
394
+ client: '...',
395
+ },
396
+
397
+ // by default, the plugin sets up middleware
398
+ // using `default` export of `rsc` environment `index` entry.
399
+ // this behavior can be customized by `serverHandler` option.
400
+ serverHandler: false,
401
+
402
+ // when `loadModuleDevProxy: true`, `import.meta.viteRsc.loadModule` is implemented
403
+ // through `fetch` based RPC, which allows, for example, rsc environment inside
404
+ // cloudflare workers to communicate with node ssr environment on main Vite process.
405
+ loadModuleDevProxy: true,
406
+
407
+ // by default, `loadCss()` helper is injected based on certain heuristics.
408
+ // if it breaks, it can be opt-out or selectively applied based on files.
409
+ rscCssTransform: { filter: (id) => id.includes('/my-app/') },
410
+
411
+ // by default, the plugin uses a build-time generated encryption key for
412
+ // "use server" closure argument binding.
413
+ // This can be overwritten by configuring `defineEncryptionKey` option,
414
+ // for example, to obtain a key through environment variable during runtime.
415
+ // cf. https://nextjs.org/docs/app/guides/data-security#overwriting-encryption-keys-advanced
416
+ defineEncryptionKey: 'process.env.MY_ENCRYPTION_KEY',
417
+ }),
418
+ ],
419
+ })
420
+ ```
421
+
422
+ ## Higher level API
423
+
424
+ This is a wrapper of `react-server-dom` API and helper API to setup a minimal RSC app without writing own framework code like [`./examples/starter/src/framework`](./examples/starter/src/framework/). See [`./examples/basic`](./examples/basic/) for how this API is used.
425
+
426
+ ### `@vitejs/plugin-rsc/extra/rsc`
427
+
428
+ - `renderRequest`
429
+
430
+ ### `@vitejs/plugin-rsc/extra/ssr`
431
+
432
+ - `renderHtml`
433
+
434
+ ### `@vitejs/plugin-rsc/extra/browser`
435
+
436
+ - `hydrate`
437
+
438
+ ## Credits
439
+
440
+ This project builds on fundamental techniques and insights from pioneering Vite RSC implementations.
441
+ Additionally, Parcel and React Router's work on standardizing the RSC bundler/app responsibility has guided this plugin's API design:
442
+
443
+ - [Waku](https://github.com/wakujs/waku)
444
+ - [@lazarv/react-server](https://github.com/lazarv/react-server)
445
+ - [@jacob-ebey/vite-react-server-dom](https://github.com/jacob-ebey/vite-plugins/tree/main/packages/vite-react-server-dom)
446
+ - [React Router RSC](https://remix.run/blog/rsc-preview)
447
+ - [Parcel RSC](https://parceljs.org/recipes/rsc)
@@ -0,0 +1,35 @@
1
+ import * as ReactClient from "@vitejs/plugin-rsc/vendor/react-server-dom/client.browser";
2
+
3
+ //#region src/react/browser.ts
4
+ function createFromReadableStream(stream, options = {}) {
5
+ return ReactClient.createFromReadableStream(stream, {
6
+ callServer,
7
+ findSourceMapURL,
8
+ ...options
9
+ });
10
+ }
11
+ function createFromFetch(promiseForResponse, options = {}) {
12
+ return ReactClient.createFromFetch(promiseForResponse, {
13
+ callServer,
14
+ findSourceMapURL,
15
+ ...options
16
+ });
17
+ }
18
+ const encodeReply = ReactClient.encodeReply;
19
+ const createServerReference = ReactClient.createServerReference;
20
+ function callServer(...args) {
21
+ return globalThis.__viteRscCallServer(...args);
22
+ }
23
+ function setServerCallback(fn) {
24
+ globalThis.__viteRscCallServer = fn;
25
+ }
26
+ const createTemporaryReferenceSet = ReactClient.createTemporaryReferenceSet;
27
+ function findSourceMapURL(filename, environmentName) {
28
+ const url = new URL("/__vite_rsc_findSourceMapURL", window.location.origin);
29
+ url.searchParams.set("filename", filename);
30
+ url.searchParams.set("environmentName", environmentName);
31
+ return url.toString();
32
+ }
33
+
34
+ //#endregion
35
+ export { callServer, createFromFetch, createFromReadableStream, createServerReference, createTemporaryReferenceSet, encodeReply, findSourceMapURL, setServerCallback };
@@ -0,0 +1,15 @@
1
+ import { CallServerCallback } from "./index-BHqtj9tT.js";
2
+
3
+ //#region src/react/browser.d.ts
4
+ declare function createFromReadableStream<T>(stream: ReadableStream<Uint8Array>, options?: object): Promise<T>;
5
+ declare function createFromFetch<T>(promiseForResponse: Promise<Response>, options?: object): Promise<T>;
6
+ declare const encodeReply: (v: unknown[], options?: unknown) => Promise<string | FormData>;
7
+ declare const createServerReference: (...args: any[]) => unknown;
8
+ // use global instead of local variable to tolerate duplicate modules
9
+ // e.g. when `setServerCallback` is pre-bundled but `createServerReference` is not
10
+ declare function callServer(...args: any[]): any;
11
+ declare function setServerCallback(fn: CallServerCallback): void;
12
+ declare const createTemporaryReferenceSet: () => unknown;
13
+ declare function findSourceMapURL(filename: string, environmentName: string): string | null;
14
+ //#endregion
15
+ export { callServer, createFromFetch, createFromReadableStream, createServerReference, createTemporaryReferenceSet, encodeReply, findSourceMapURL, setServerCallback };
@@ -0,0 +1,6 @@
1
+ //#region src/core/browser.d.ts
2
+ declare function setRequireModule(options: {
3
+ load: (id: string) => Promise<unknown>;
4
+ }): void;
5
+ //#endregion
6
+ export { setRequireModule };
@@ -0,0 +1,17 @@
1
+ import { setRequireModule } from "./browser-QWbIPyhO.js";
2
+ import * as clientReferences from "virtual:vite-rsc/client-references";
3
+
4
+ //#region src/browser.ts
5
+ initialize();
6
+ function initialize() {
7
+ setRequireModule({ load: async (id) => {
8
+ if (!import.meta.env.__vite_rsc_build__) return __vite_rsc_raw_import__(import.meta.env.BASE_URL + id.slice(1));
9
+ else {
10
+ const import_ = clientReferences.default[id];
11
+ if (!import_) throw new Error(`client reference not found '${id}'`);
12
+ return import_();
13
+ }
14
+ } });
15
+ }
16
+
17
+ //#endregion
@@ -0,0 +1,17 @@
1
+ import { memoize } from "./dist-DEF94lDJ.js";
2
+ import { removeReferenceCacheTag, setInternalRequire } from "./shared-CEyKoKAb.js";
3
+
4
+ //#region src/core/browser.ts
5
+ let init = false;
6
+ function setRequireModule(options) {
7
+ if (init) return;
8
+ init = true;
9
+ const requireModule = memoize((id) => {
10
+ return options.load(removeReferenceCacheTag(id));
11
+ });
12
+ globalThis.__vite_rsc_client_require__ = requireModule;
13
+ setInternalRequire();
14
+ }
15
+
16
+ //#endregion
17
+ export { setRequireModule };
@@ -0,0 +1,4 @@
1
+ import { CallServerCallback } from "./index-BHqtj9tT.js";
2
+ import { setRequireModule } from "./browser-Dw18EFgE.js";
3
+ import { callServer, createFromFetch, createFromReadableStream, createServerReference, createTemporaryReferenceSet, encodeReply, findSourceMapURL, setServerCallback } from "./browser-DjnGtEmB.js";
4
+ export { CallServerCallback, callServer, createFromFetch, createFromReadableStream, createServerReference, createTemporaryReferenceSet, encodeReply, findSourceMapURL, setRequireModule, setServerCallback };
@@ -0,0 +1,7 @@
1
+ import "./dist-DEF94lDJ.js";
2
+ import "./shared-CEyKoKAb.js";
3
+ import { setRequireModule } from "./browser-QWbIPyhO.js";
4
+ import { callServer, createFromFetch, createFromReadableStream, createServerReference, createTemporaryReferenceSet, encodeReply, findSourceMapURL, setServerCallback } from "./browser-D8OPzpF5.js";
5
+ import "./browser-LizIyxet.js";
6
+
7
+ export { callServer, createFromFetch, createFromReadableStream, createServerReference, createTemporaryReferenceSet, encodeReply, findSourceMapURL, setRequireModule, setServerCallback };
@@ -0,0 +1,23 @@
1
+ //#region ../../node_modules/.pnpm/rsc-html-stream@0.0.6/node_modules/rsc-html-stream/client.js
2
+ let encoder = new TextEncoder();
3
+ let streamController;
4
+ let rscStream = new ReadableStream({ start(controller) {
5
+ if (typeof window === "undefined") return;
6
+ let handleChunk = (chunk) => {
7
+ if (typeof chunk === "string") controller.enqueue(encoder.encode(chunk));
8
+ else controller.enqueue(chunk);
9
+ };
10
+ window.__FLIGHT_DATA ||= [];
11
+ window.__FLIGHT_DATA.forEach(handleChunk);
12
+ window.__FLIGHT_DATA.push = (chunk) => {
13
+ handleChunk(chunk);
14
+ };
15
+ streamController = controller;
16
+ } });
17
+ if (typeof document !== "undefined" && document.readyState === "loading") document.addEventListener("DOMContentLoaded", () => {
18
+ streamController?.close();
19
+ });
20
+ else streamController?.close();
21
+
22
+ //#endregion
23
+ export { rscStream };
@@ -0,0 +1,2 @@
1
+ import { setRequireModule } from "../browser-Dw18EFgE.js";
2
+ export { setRequireModule };
@@ -0,0 +1,5 @@
1
+ import "../dist-DEF94lDJ.js";
2
+ import "../shared-CEyKoKAb.js";
3
+ import { setRequireModule } from "../browser-QWbIPyhO.js";
4
+
5
+ export { setRequireModule };
@@ -0,0 +1,6 @@
1
+ import { Plugin } from "vite";
2
+
3
+ //#region src/core/plugin.d.ts
4
+ declare function vitePluginRscCore(): Plugin[];
5
+ //#endregion
6
+ export { vitePluginRscCore as default };
@@ -0,0 +1,3 @@
1
+ import { vitePluginRscCore } from "../plugin-CZbI4rhS.js";
2
+
3
+ export { vitePluginRscCore as default };
@@ -0,0 +1,3 @@
1
+ import "../index-BHqtj9tT.js";
2
+ import { createClientManifest, createServerDecodeClientManifest, createServerManifest, loadServerAction, setRequireModule } from "../rsc-BOV3yNSd.js";
3
+ export { createClientManifest, createServerDecodeClientManifest, createServerManifest, loadServerAction, setRequireModule };
@@ -0,0 +1,5 @@
1
+ import "../dist-DEF94lDJ.js";
2
+ import "../shared-CEyKoKAb.js";
3
+ import { createClientManifest, createServerDecodeClientManifest, createServerManifest, loadServerAction, setRequireModule } from "../rsc-DKA6wwTB.js";
4
+
5
+ export { createClientManifest, createServerDecodeClientManifest, createServerManifest, loadServerAction, setRequireModule };
@@ -0,0 +1,3 @@
1
+ import "../index-BHqtj9tT.js";
2
+ import { createServerConsumerManifest, setRequireModule } from "../ssr-DgSrGrln.js";
3
+ export { createServerConsumerManifest, setRequireModule };
@@ -0,0 +1,5 @@
1
+ import "../dist-DEF94lDJ.js";
2
+ import "../shared-CEyKoKAb.js";
3
+ import { createServerConsumerManifest, setRequireModule } from "../ssr-BOIYlvSn.js";
4
+
5
+ export { createServerConsumerManifest, setRequireModule };
@@ -0,0 +1,41 @@
1
+ //#region ../../node_modules/.pnpm/@hiogawa+utils@1.7.0/node_modules/@hiogawa/utils/dist/index.js
2
+ function tinyassert(value, message) {
3
+ if (value) return;
4
+ if (message instanceof Error) throw message;
5
+ throw new TinyAssertionError(message, tinyassert);
6
+ }
7
+ var TinyAssertionError = class extends Error {
8
+ constructor(message, stackStartFunction) {
9
+ super(message ?? "TinyAssertionError");
10
+ if (stackStartFunction && "captureStackTrace" in Error) Error.captureStackTrace(this, stackStartFunction);
11
+ }
12
+ };
13
+ function safeFunctionCast(f) {
14
+ return f;
15
+ }
16
+ function once(f) {
17
+ let result;
18
+ let called = false;
19
+ return safeFunctionCast(function(...args) {
20
+ if (!called) {
21
+ result = f.apply(this, args);
22
+ called = true;
23
+ }
24
+ return result;
25
+ });
26
+ }
27
+ function memoize(f, options) {
28
+ const keyFn = options?.keyFn ?? ((...args) => args[0]);
29
+ const cache = options?.cache ?? /* @__PURE__ */ new Map();
30
+ return safeFunctionCast(function(...args) {
31
+ const key = keyFn(...args);
32
+ const value = cache.get(key);
33
+ if (typeof value !== "undefined") return value;
34
+ const newValue = f.apply(this, args);
35
+ cache.set(key, newValue);
36
+ return newValue;
37
+ });
38
+ }
39
+
40
+ //#endregion
41
+ export { memoize, once, tinyassert };