rwsdk 1.0.0-alpha.5 → 1.0.0-alpha.7

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 (56) hide show
  1. package/dist/lib/e2e/browser.d.mts +10 -0
  2. package/dist/lib/e2e/browser.mjs +107 -0
  3. package/dist/lib/e2e/dev.d.mts +8 -0
  4. package/dist/lib/e2e/dev.mjs +232 -0
  5. package/dist/lib/e2e/environment.d.mts +14 -0
  6. package/dist/lib/e2e/environment.mjs +201 -0
  7. package/dist/lib/e2e/index.d.mts +7 -0
  8. package/dist/lib/e2e/index.mjs +7 -0
  9. package/dist/lib/e2e/release.d.mts +56 -0
  10. package/dist/lib/e2e/release.mjs +537 -0
  11. package/dist/lib/e2e/tarball.d.mts +14 -0
  12. package/dist/lib/e2e/tarball.mjs +189 -0
  13. package/dist/lib/e2e/testHarness.d.mts +98 -0
  14. package/dist/lib/e2e/testHarness.mjs +393 -0
  15. package/dist/lib/e2e/types.d.mts +31 -0
  16. package/dist/lib/e2e/types.mjs +1 -0
  17. package/dist/lib/smokeTests/browser.mjs +3 -94
  18. package/dist/lib/smokeTests/development.mjs +2 -223
  19. package/dist/lib/smokeTests/environment.d.mts +4 -11
  20. package/dist/lib/smokeTests/environment.mjs +10 -158
  21. package/dist/lib/smokeTests/release.d.mts +2 -49
  22. package/dist/lib/smokeTests/release.mjs +3 -503
  23. package/dist/runtime/lib/injectHtmlAtMarker.d.ts +11 -0
  24. package/dist/runtime/lib/injectHtmlAtMarker.js +90 -0
  25. package/dist/runtime/lib/realtime/worker.d.ts +1 -1
  26. package/dist/runtime/lib/router.js +32 -20
  27. package/dist/runtime/lib/router.test.js +506 -1
  28. package/dist/runtime/lib/rwContext.d.ts +22 -0
  29. package/dist/runtime/lib/rwContext.js +1 -0
  30. package/dist/runtime/render/assembleDocument.d.ts +6 -0
  31. package/dist/runtime/render/assembleDocument.js +22 -0
  32. package/dist/runtime/render/createThenableFromReadableStream.d.ts +1 -0
  33. package/dist/runtime/render/createThenableFromReadableStream.js +9 -0
  34. package/dist/runtime/render/normalizeActionResult.d.ts +1 -0
  35. package/dist/runtime/render/normalizeActionResult.js +43 -0
  36. package/dist/runtime/render/preloads.d.ts +2 -2
  37. package/dist/runtime/render/preloads.js +2 -3
  38. package/dist/runtime/render/{renderRscThenableToHtmlStream.d.ts → renderDocumentHtmlStream.d.ts} +3 -3
  39. package/dist/runtime/render/renderDocumentHtmlStream.js +39 -0
  40. package/dist/runtime/render/renderHtmlStream.d.ts +7 -0
  41. package/dist/runtime/render/renderHtmlStream.js +31 -0
  42. package/dist/runtime/render/renderToRscStream.d.ts +2 -3
  43. package/dist/runtime/render/renderToRscStream.js +2 -41
  44. package/dist/runtime/render/renderToStream.d.ts +2 -1
  45. package/dist/runtime/render/renderToStream.js +15 -8
  46. package/dist/runtime/render/stylesheets.d.ts +2 -2
  47. package/dist/runtime/render/stylesheets.js +2 -3
  48. package/dist/runtime/ssrBridge.d.ts +2 -1
  49. package/dist/runtime/ssrBridge.js +2 -1
  50. package/dist/runtime/worker.d.ts +1 -0
  51. package/dist/runtime/worker.js +11 -6
  52. package/dist/vite/configPlugin.mjs +2 -2
  53. package/package.json +8 -4
  54. package/dist/runtime/render/renderRscThenableToHtmlStream.js +0 -54
  55. package/dist/runtime/render/transformRscToHtmlStream.d.ts +0 -8
  56. package/dist/runtime/render/transformRscToHtmlStream.js +0 -19
@@ -0,0 +1,43 @@
1
+ // context(justinvdm, 24 Mar 2025): React flight limits chunks to 28 bytes, so we need to rechunk
2
+ // the stream to avoid losing data
3
+ function rechunkStream(stream, maxChunkSize = 28) {
4
+ const reader = stream.getReader();
5
+ return new ReadableStream({
6
+ async pull(controller) {
7
+ let buffer = new Uint8Array(0);
8
+ try {
9
+ while (true) {
10
+ const { done, value } = await reader.read();
11
+ if (done && buffer.length === 0) {
12
+ controller.close();
13
+ return;
14
+ }
15
+ if (value) {
16
+ buffer = new Uint8Array([...buffer, ...value]);
17
+ }
18
+ while (buffer.length >= maxChunkSize || (done && buffer.length > 0)) {
19
+ const chunk = buffer.slice(0, maxChunkSize);
20
+ buffer = buffer.slice(maxChunkSize);
21
+ controller.enqueue(chunk);
22
+ }
23
+ if (done) {
24
+ controller.close();
25
+ return;
26
+ }
27
+ }
28
+ }
29
+ catch (error) {
30
+ controller.error(error);
31
+ }
32
+ },
33
+ });
34
+ }
35
+ export const normalizeActionResult = (actionResult) => {
36
+ if (actionResult instanceof Response) {
37
+ return null;
38
+ }
39
+ if (actionResult instanceof ReadableStream) {
40
+ return rechunkStream(actionResult);
41
+ }
42
+ return actionResult;
43
+ };
@@ -1,6 +1,6 @@
1
1
  import type { RequestInfo } from "../requestInfo/types.js";
2
2
  import type { Manifest, ManifestChunk } from "../lib/manifest.js";
3
3
  export declare function findScriptForModule(id: string, manifest: Manifest): ManifestChunk | undefined;
4
- export declare const Preloads: ({ requestInfo }: {
4
+ export declare const Preloads: ({ requestInfo, }: {
5
5
  requestInfo: RequestInfo;
6
- }) => import("react/jsx-runtime.js").JSX.Element;
6
+ }) => Promise<import("react/jsx-runtime.js").JSX.Element>;
@@ -1,5 +1,4 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { use } from "react";
3
2
  import { getManifest } from "../lib/manifest.js";
4
3
  export function findScriptForModule(id, manifest) {
5
4
  const visited = new Set();
@@ -27,8 +26,8 @@ export function findScriptForModule(id, manifest) {
27
26
  }
28
27
  return find(id);
29
28
  }
30
- export const Preloads = ({ requestInfo }) => {
31
- const manifest = use(getManifest());
29
+ export const Preloads = async ({ requestInfo, }) => {
30
+ const manifest = await getManifest();
32
31
  const allScripts = new Set();
33
32
  for (const scriptId of requestInfo.rw.scriptsToBeLoaded) {
34
33
  const script = findScriptForModule(scriptId, manifest);
@@ -1,9 +1,9 @@
1
1
  import { type DocumentProps } from "../lib/router.js";
2
2
  import { type RequestInfo } from "../requestInfo/types.js";
3
- export declare const renderRscThenableToHtmlStream: ({ thenable, Document, requestInfo, shouldSSR, onError, }: {
4
- thenable: any;
3
+ export declare const renderDocumentHtmlStream: ({ rscPayloadStream, Document, requestInfo, shouldSSR, onError, }: {
4
+ rscPayloadStream: ReadableStream;
5
5
  Document: React.FC<DocumentProps>;
6
6
  requestInfo: RequestInfo;
7
7
  shouldSSR: boolean;
8
8
  onError: (error: unknown) => void;
9
- }) => Promise<import("react-dom/server.js").ReactDOMServerReadableStream>;
9
+ }) => Promise<ReadableStream<Uint8Array<ArrayBufferLike>>>;
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Preloads } from "./preloads.js";
3
+ import { Stylesheets } from "./stylesheets.js";
4
+ import { renderHtmlStream, createThenableFromReadableStream, } from "rwsdk/__ssr_bridge";
5
+ import { injectHtmlAtMarker } from "../lib/injectHtmlAtMarker.js";
6
+ export const renderDocumentHtmlStream = async ({ rscPayloadStream, Document, requestInfo, shouldSSR, onError, }) => {
7
+ // Extract the app node from the RSC payload
8
+ const rscAppThenable = createThenableFromReadableStream(rscPayloadStream);
9
+ const { node: appNode } = (await rscAppThenable);
10
+ // todo(justinvdm, 18 Jun 2025): We can build on this later to allow users
11
+ // surface context. e.g:
12
+ // * we assign `user: requestInfo.clientCtx` here
13
+ // * user populates requestInfo.clientCtx on worker side
14
+ // * user can import a read only `import { clientCtx } from "rwsdk/client"`
15
+ // on client side
16
+ const clientContext = {
17
+ rw: {
18
+ ssr: shouldSSR,
19
+ },
20
+ };
21
+ // Create the outer document with a marker for injection
22
+ const documentElement = (_jsxs(Document, { ...requestInfo, children: [_jsx("script", { nonce: requestInfo.rw.nonce, dangerouslySetInnerHTML: {
23
+ __html: `globalThis.__RWSDK_CONTEXT = ${JSON.stringify(clientContext)}`,
24
+ } }), _jsx(Stylesheets, { requestInfo: requestInfo }), _jsx(Preloads, { requestInfo: requestInfo }), _jsx("div", { id: "hydrate-root", dangerouslySetInnerHTML: { __html: "<!-- RWSDK_INJECT_APP_HTML -->" } })] }));
25
+ const outerHtmlStream = await renderHtmlStream({
26
+ node: documentElement,
27
+ requestInfo,
28
+ onError,
29
+ identifierPrefix: "__RWSDK_DOCUMENT__",
30
+ });
31
+ const appHtmlStream = await renderHtmlStream({
32
+ node: appNode,
33
+ requestInfo,
34
+ onError,
35
+ });
36
+ // Stitch the streams together
37
+ const stitchedStream = injectHtmlAtMarker(outerHtmlStream, appHtmlStream, "<!-- RWSDK_INJECT_APP_HTML -->");
38
+ return stitchedStream;
39
+ };
@@ -0,0 +1,7 @@
1
+ import { type RequestInfo } from "../requestInfo/types.js";
2
+ export declare const renderHtmlStream: ({ node, identifierPrefix, requestInfo, onError, }: {
3
+ node: React.ReactNode;
4
+ requestInfo: RequestInfo;
5
+ onError: (error: unknown) => void;
6
+ identifierPrefix?: string;
7
+ }) => Promise<import("react-dom/server.js").ReactDOMServerReadableStream>;
@@ -0,0 +1,31 @@
1
+ import { renderToReadableStream } from "react-dom/server.edge";
2
+ export const renderHtmlStream = async ({ node, identifierPrefix, requestInfo, onError, }) => {
3
+ return await renderToReadableStream(node, {
4
+ nonce: requestInfo.rw.nonce,
5
+ identifierPrefix,
6
+ onError(error, { componentStack }) {
7
+ try {
8
+ if (!error) {
9
+ error = new Error(`A falsy value was thrown during rendering: ${String(error)}.`);
10
+ }
11
+ const message = error
12
+ ? (error.stack ?? error.message ?? error)
13
+ : error;
14
+ const wrappedMessage = `${message}\n\nComponent stack:${componentStack}`;
15
+ if (error instanceof Error) {
16
+ const wrappedError = new Error(wrappedMessage);
17
+ wrappedError.stack = error.stack;
18
+ error = wrappedError;
19
+ }
20
+ else {
21
+ error = new Error(wrappedMessage);
22
+ error.stack = componentStack;
23
+ }
24
+ onError(error);
25
+ }
26
+ catch {
27
+ onError(error);
28
+ }
29
+ },
30
+ });
31
+ };
@@ -1,5 +1,4 @@
1
- export declare const renderToRscStream: (app: {
2
- node: React.ReactElement;
3
- actionResult: any;
1
+ export declare const renderToRscStream: ({ input, onError, }: {
2
+ input: any;
4
3
  onError?: (error: unknown) => void;
5
4
  }) => ReadableStream;
@@ -1,46 +1,7 @@
1
1
  import { renderToReadableStream as baseRenderToRscStream } from "react-server-dom-webpack/server.edge";
2
2
  import { createClientManifest } from "./createClientManifest.js";
3
- // context(justinvdm, 24 Mar 2025): React flight limits chunks to 28 bytes, so we need to rechunk
4
- // the stream to avoid losing data
5
- function rechunkStream(stream, maxChunkSize = 28) {
6
- const reader = stream.getReader();
7
- return new ReadableStream({
8
- async pull(controller) {
9
- let buffer = new Uint8Array(0);
10
- try {
11
- while (true) {
12
- const { done, value } = await reader.read();
13
- if (done && buffer.length === 0) {
14
- controller.close();
15
- return;
16
- }
17
- if (value) {
18
- buffer = new Uint8Array([...buffer, ...value]);
19
- }
20
- while (buffer.length >= maxChunkSize || (done && buffer.length > 0)) {
21
- const chunk = buffer.slice(0, maxChunkSize);
22
- buffer = buffer.slice(maxChunkSize);
23
- controller.enqueue(chunk);
24
- }
25
- if (done) {
26
- controller.close();
27
- return;
28
- }
29
- }
30
- }
31
- catch (error) {
32
- controller.error(error);
33
- }
34
- },
35
- });
36
- }
37
- export const renderToRscStream = (app) => {
38
- const { node, onError } = app;
39
- let { actionResult } = app;
40
- if (actionResult instanceof ReadableStream) {
41
- actionResult = rechunkStream(actionResult);
42
- }
43
- return baseRenderToRscStream({ node, actionResult }, createClientManifest(), {
3
+ export const renderToRscStream = ({ input, onError, }) => {
4
+ return baseRenderToRscStream(input, createClientManifest(), {
44
5
  onError,
45
6
  });
46
7
  };
@@ -2,8 +2,9 @@ import { ReactElement, FC } from "react";
2
2
  import { DocumentProps } from "../lib/router";
3
3
  export interface RenderToStreamOptions {
4
4
  Document?: FC<DocumentProps>;
5
+ ssr?: boolean;
5
6
  injectRSCPayload?: boolean;
6
7
  onError?: (error: unknown) => void;
7
8
  }
8
9
  export declare const IdentityDocument: FC<DocumentProps>;
9
- export declare const renderToStream: (element: ReactElement, { Document, injectRSCPayload: shouldInjectRSCPayload, onError, }?: RenderToStreamOptions) => Promise<ReadableStream>;
10
+ export declare const renderToStream: (element: ReactElement, { ssr: shouldSSR, Document, injectRSCPayload: shouldInjectRSCPayload, onError, }?: RenderToStreamOptions) => Promise<ReadableStream>;
@@ -1,27 +1,34 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { renderToRscStream } from "./renderToRscStream";
3
- import { transformRscToHtmlStream } from "./transformRscToHtmlStream";
4
3
  import { requestInfo } from "../requestInfo/worker";
5
4
  import { injectRSCPayload } from "rsc-html-stream/server";
5
+ import { renderDocumentHtmlStream } from "./renderDocumentHtmlStream";
6
6
  export const IdentityDocument = ({ children }) => (_jsx(_Fragment, { children: children }));
7
- export const renderToStream = async (element, { Document = IdentityDocument, injectRSCPayload: shouldInjectRSCPayload = false, onError = () => { }, } = {}) => {
7
+ export const renderToStream = async (element, { ssr: shouldSSR = true, Document = IdentityDocument, injectRSCPayload: shouldInjectRSCPayload = true, onError = () => { }, } = {}) => {
8
8
  let rscStream = renderToRscStream({
9
- node: element,
10
- actionResult: null,
9
+ input: {
10
+ node: element,
11
+ actionResult: undefined,
12
+ },
11
13
  onError,
12
14
  });
15
+ let injectRSCStream;
13
16
  if (shouldInjectRSCPayload) {
14
17
  const [rscPayloadStream1, rscPayloadStream2] = rscStream.tee();
15
18
  rscStream = rscPayloadStream1;
16
- rscStream = rscStream.pipeThrough(injectRSCPayload(rscPayloadStream2, {
19
+ injectRSCStream = injectRSCPayload(rscPayloadStream2, {
17
20
  nonce: requestInfo.rw.nonce,
18
- }));
21
+ });
19
22
  }
20
- const htmlStream = await transformRscToHtmlStream({
21
- stream: rscStream,
23
+ let htmlStream = await renderDocumentHtmlStream({
24
+ rscPayloadStream: rscStream,
22
25
  Document,
23
26
  requestInfo,
27
+ shouldSSR,
24
28
  onError,
25
29
  });
30
+ if (injectRSCStream) {
31
+ htmlStream = htmlStream.pipeThrough(injectRSCStream);
32
+ }
26
33
  return htmlStream;
27
34
  };
@@ -1,4 +1,4 @@
1
1
  import { type RequestInfo } from "../requestInfo/types.js";
2
- export declare const Stylesheets: ({ requestInfo }: {
2
+ export declare const Stylesheets: ({ requestInfo, }: {
3
3
  requestInfo: RequestInfo;
4
- }) => import("react/jsx-runtime.js").JSX.Element;
4
+ }) => Promise<import("react/jsx-runtime.js").JSX.Element>;
@@ -1,5 +1,4 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { use } from "react";
3
2
  import { getManifest } from "../lib/manifest.js";
4
3
  const findCssForModule = (scriptId, manifest) => {
5
4
  const css = new Set();
@@ -22,8 +21,8 @@ const findCssForModule = (scriptId, manifest) => {
22
21
  inner(scriptId);
23
22
  return Array.from(css);
24
23
  };
25
- export const Stylesheets = ({ requestInfo }) => {
26
- const manifest = use(getManifest());
24
+ export const Stylesheets = async ({ requestInfo, }) => {
25
+ const manifest = await getManifest();
27
26
  const allStylesheets = new Set();
28
27
  for (const scriptId of requestInfo.rw.scriptsToBeLoaded) {
29
28
  const css = findCssForModule(scriptId, manifest);
@@ -1,2 +1,3 @@
1
- export { renderRscThenableToHtmlStream } from "./render/renderRscThenableToHtmlStream";
1
+ export { renderHtmlStream } from "./render/renderHtmlStream";
2
+ export { createThenableFromReadableStream } from "./render/createThenableFromReadableStream";
2
3
  export { ssrLoadModule, ssrGetModuleExport, ssrWebpackRequire, } from "./imports/ssr";
@@ -7,5 +7,6 @@
7
7
  // import it through this bridge module, using the bare import path
8
8
  // `rwsdk/__ssr_bridge`. We have bundler logic (ssrBridgePlugin) that looks out
9
9
  // for imports to it.
10
- export { renderRscThenableToHtmlStream } from "./render/renderRscThenableToHtmlStream";
10
+ export { renderHtmlStream } from "./render/renderHtmlStream";
11
+ export { createThenableFromReadableStream } from "./render/createThenableFromReadableStream";
11
12
  export { ssrLoadModule, ssrGetModuleExport, ssrWebpackRequire, } from "./imports/ssr";
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import { RequestInfo, DefaultAppContext } from "./requestInfo/types";
3
3
  import { Route } from "./lib/router";
4
+ export * from "./requestInfo/types";
4
5
  declare global {
5
6
  type Env = {
6
7
  ASSETS: Fetcher;
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { transformRscToHtmlStream } from "./render/transformRscToHtmlStream";
2
+ import { renderDocumentHtmlStream } from "./render/renderDocumentHtmlStream";
3
+ import { normalizeActionResult } from "./render/normalizeActionResult";
3
4
  import { renderToRscStream } from "./render/renderToRscStream";
4
5
  import { rscActionHandler } from "./register/worker";
5
6
  import { injectRSCPayload } from "rsc-html-stream/server";
@@ -8,6 +9,7 @@ import { getRequestInfo, runWithRequestInfo, runWithRequestInfoOverrides, } from
8
9
  import { defineRoutes } from "./lib/router";
9
10
  import { generateNonce } from "./lib/utils";
10
11
  import { ssrWebpackRequire } from "./imports/worker";
12
+ export * from "./requestInfo/types";
11
13
  export const defineApp = (routes) => {
12
14
  return {
13
15
  fetch: async (request, env, cf) => {
@@ -79,12 +81,14 @@ export const defineApp = (routes) => {
79
81
  status: 500,
80
82
  });
81
83
  }
82
- const actionResult = requestInfo.rw.actionResult;
84
+ const actionResult = normalizeActionResult(requestInfo.rw.actionResult);
83
85
  const pageElement = createPageElement(requestInfo, Page);
84
86
  const { rscPayload: shouldInjectRSCPayload } = rw;
85
87
  let rscPayloadStream = renderToRscStream({
86
- node: pageElement,
87
- actionResult: actionResult instanceof Response ? null : actionResult,
88
+ input: {
89
+ node: pageElement,
90
+ actionResult,
91
+ },
88
92
  onError,
89
93
  });
90
94
  if (isRSCRequest) {
@@ -104,11 +108,12 @@ export const defineApp = (routes) => {
104
108
  nonce: rw.nonce,
105
109
  });
106
110
  }
107
- let html = await transformRscToHtmlStream({
108
- stream: rscPayloadStream,
111
+ let html = await renderDocumentHtmlStream({
112
+ rscPayloadStream: rscPayloadStream,
109
113
  Document: rw.Document,
110
114
  requestInfo: requestInfo,
111
115
  onError,
116
+ shouldSSR: rw.ssr,
112
117
  });
113
118
  if (injectRSCPayloadStream) {
114
119
  html = html.pipeThrough(injectRSCPayloadStream);
@@ -148,8 +148,8 @@ export const configPlugin = ({ silent, projectRootDir, workerEntryPathname, clie
148
148
  // original `export` statement from the bundle to prevent syntax
149
149
  // errors.
150
150
  inlineDynamicImports: true,
151
- banner: `export const { renderRscThenableToHtmlStream, ssrWebpackRequire, ssrGetModuleExport } = (function() {`,
152
- footer: `return { renderRscThenableToHtmlStream, ssrWebpackRequire, ssrGetModuleExport };\n})();`,
151
+ banner: `export const { renderHtmlStream, ssrWebpackRequire, ssrGetModuleExport, createThenableFromReadableStream } = (function() {`,
152
+ footer: `return { renderHtmlStream, ssrWebpackRequire, ssrGetModuleExport, createThenableFromReadableStream };\n})();`,
153
153
  },
154
154
  plugins: [
155
155
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rwsdk",
3
- "version": "1.0.0-alpha.5",
3
+ "version": "1.0.0-alpha.7",
4
4
  "description": "Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime",
5
5
  "type": "module",
6
6
  "bin": {
@@ -90,6 +90,10 @@
90
90
  "./realtime/durableObject": {
91
91
  "types": "./dist/runtime/lib/realtime/durableObject.d.ts",
92
92
  "default": "./dist/runtime/lib/realtime/durableObject.js"
93
+ },
94
+ "./e2e": {
95
+ "types": "./dist/lib/e2e/index.d.mts",
96
+ "default": "./dist/lib/e2e/index.mjs"
93
97
  }
94
98
  },
95
99
  "keywords": [
@@ -159,9 +163,9 @@
159
163
  },
160
164
  "peerDependencies": {
161
165
  "@cloudflare/vite-plugin": "^1.12.4",
162
- "react": "19.2.0-canary-3fb190f7-20250908",
163
- "react-dom": "19.2.0-canary-3fb190f7-20250908",
164
- "react-server-dom-webpack": "19.2.0-canary-3fb190f7-20250908",
166
+ "react": "19.2.0-canary-3fb190f7-20250908 <20.0.0",
167
+ "react-dom": "19.2.0-canary-3fb190f7-20250908 <20.0.0",
168
+ "react-server-dom-webpack": ">=19.2.0-canary-3fb190f7-20250908 <20.0.0",
165
169
  "vite": "^6.2.6 || 7.x",
166
170
  "wrangler": "^4.35.0"
167
171
  },
@@ -1,54 +0,0 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { use } from "react";
3
- import { renderToReadableStream } from "react-dom/server.edge";
4
- import { Preloads } from "./preloads.js";
5
- import { Stylesheets } from "./stylesheets.js";
6
- export const renderRscThenableToHtmlStream = async ({ thenable, Document, requestInfo, shouldSSR, onError, }) => {
7
- const Component = () => {
8
- const RscApp = () => {
9
- const node = use(thenable).node;
10
- return (_jsxs(_Fragment, { children: [_jsx(Stylesheets, { requestInfo: requestInfo }), _jsx(Preloads, { requestInfo: requestInfo }), _jsx("div", { id: "hydrate-root", children: node })] }));
11
- };
12
- // todo(justinvdm, 18 Jun 2025): We can build on this later to allow users
13
- // surface context. e.g:
14
- // * we assign `user: requestInfo.clientCtx` here
15
- // * user populates requestInfo.clientCtx on worker side
16
- // * user can import a read only `import { clientCtx } from "rwsdk/client"`
17
- // on client side
18
- const clientContext = {
19
- rw: {
20
- ssr: shouldSSR,
21
- },
22
- };
23
- return (_jsxs(Document, { ...requestInfo, children: [_jsx("script", { nonce: requestInfo.rw.nonce, dangerouslySetInnerHTML: {
24
- __html: `globalThis.__RWSDK_CONTEXT = ${JSON.stringify(clientContext)}`,
25
- } }), _jsx(RscApp, {})] }));
26
- };
27
- return await renderToReadableStream(_jsx(Component, {}), {
28
- nonce: requestInfo.rw.nonce,
29
- onError(error, { componentStack }) {
30
- try {
31
- if (!error) {
32
- error = new Error(`A falsy value was thrown during rendering: ${String(error)}.`);
33
- }
34
- const message = error
35
- ? (error.stack ?? error.message ?? error)
36
- : error;
37
- const wrappedMessage = `${message}\n\nComponent stack:${componentStack}`;
38
- if (error instanceof Error) {
39
- const wrappedError = new Error(wrappedMessage);
40
- wrappedError.stack = error.stack;
41
- error = wrappedError;
42
- }
43
- else {
44
- error = new Error(wrappedMessage);
45
- error.stack = componentStack;
46
- }
47
- onError(error);
48
- }
49
- catch {
50
- onError(error);
51
- }
52
- },
53
- });
54
- };
@@ -1,8 +0,0 @@
1
- import { DocumentProps } from "../lib/router";
2
- import { RequestInfo } from "../requestInfo/types";
3
- export declare const transformRscToHtmlStream: ({ stream, Document, requestInfo, onError, }: {
4
- stream: ReadableStream;
5
- Document: React.FC<DocumentProps>;
6
- requestInfo: RequestInfo;
7
- onError: (error: unknown) => void;
8
- }) => Promise<import("react-dom/server.js").ReactDOMServerReadableStream>;
@@ -1,19 +0,0 @@
1
- import { createModuleMap } from "./createModuleMap.js";
2
- import ReactServerDom from "react-server-dom-webpack/client.edge";
3
- import { renderRscThenableToHtmlStream } from "rwsdk/__ssr_bridge";
4
- const { createFromReadableStream } = ReactServerDom;
5
- export const transformRscToHtmlStream = ({ stream, Document, requestInfo, onError, }) => {
6
- const thenable = createFromReadableStream(stream, {
7
- serverConsumerManifest: {
8
- moduleMap: createModuleMap(),
9
- moduleLoading: null,
10
- },
11
- });
12
- return renderRscThenableToHtmlStream({
13
- thenable,
14
- Document,
15
- requestInfo,
16
- shouldSSR: requestInfo.rw.ssr,
17
- onError,
18
- });
19
- };