Skip to content

Commit 9581df5

Browse files
linting
1 parent 10885e8 commit 9581df5

11 files changed

+102
-85
lines changed

node_package/src/RSCClientRoot.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const createRSCStreamFromPage = () => {
6262
return chunks.length;
6363
};
6464
streamController = controller;
65-
}
65+
},
6666
});
6767

6868
if (typeof document !== 'undefined' && document.readyState === 'loading') {
@@ -74,13 +74,13 @@ const createRSCStreamFromPage = () => {
7474
}
7575

7676
return stream;
77-
}
77+
};
7878

7979
const createFromRSCStream = () => {
8080
const stream = createRSCStreamFromPage();
8181
const transformedStream = transformRSCStreamAndReplayConsoleLogs(stream);
8282
return createFromReadableStream<React.ReactNode>(transformedStream);
83-
}
83+
};
8484

8585
/**
8686
* RSCClientRoot is a React component that handles client-side rendering of React Server Components (RSC).
@@ -111,7 +111,7 @@ const RSCClientRoot: RenderFunction = async (
111111
const root = await createFromRSCStream();
112112
ReactDOMClient.hydrateRoot(domNode, root);
113113
} else {
114-
const root = await fetchRSC({ componentName, rscPayloadGenerationUrlPath, componentProps })
114+
const root = await fetchRSC({ componentName, rscPayloadGenerationUrlPath, componentProps });
115115
ReactDOMClient.createRoot(domNode).render(root);
116116
}
117117
// Added only to satisfy the return type of RenderFunction

node_package/src/RSCPayloadContainer.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,25 @@ import * as React from 'react';
33
type StreamChunk = {
44
chunk: string;
55
isLastChunk: boolean;
6-
}
6+
};
77

88
type RSCPayloadContainerProps = {
99
RSCPayloadStream: NodeJS.ReadableStream;
10-
}
10+
};
1111

1212
type RSCPayloadContainerInnerProps = {
1313
chunkIndex: number;
1414
getChunkPromise: (chunkIndex: number) => Promise<StreamChunk>;
15-
}
15+
};
1616

1717
function escapeScript(script: string) {
18-
return script
19-
.replace(/<!--/g, '<\\!--')
20-
.replace(/<\/(script)/gi, '</\\$1');
18+
return script.replace(/<!--/g, '<\\!--').replace(/<\/(script)/gi, '</\\$1');
2119
}
2220

23-
const RSCPayloadContainer = (
24-
{ chunkIndex, getChunkPromise }: RSCPayloadContainerInnerProps,
25-
): React.ReactNode => {
21+
const RSCPayloadContainer = ({
22+
chunkIndex,
23+
getChunkPromise,
24+
}: RSCPayloadContainerInnerProps): React.ReactNode => {
2625
const chunkPromise = getChunkPromise(chunkIndex);
2726
const chunk = React.use(chunkPromise);
2827

@@ -42,13 +41,10 @@ const RSCPayloadContainer = (
4241
React.createElement(
4342
React.Suspense,
4443
{ fallback: null, key: `suspense-${chunkIndex}` },
45-
React.createElement(
46-
RSCPayloadContainer,
47-
{ chunkIndex: chunkIndex + 1, getChunkPromise },
48-
),
44+
React.createElement(RSCPayloadContainer, { chunkIndex: chunkIndex + 1, getChunkPromise }),
4945
),
5046
]);
51-
}
47+
};
5248

5349
export default function RSCPayloadContainerWrapper({ RSCPayloadStream }: RSCPayloadContainerProps) {
5450
const [chunkPromises] = React.useState<Promise<StreamChunk>[]>(() => {
@@ -84,13 +80,16 @@ export default function RSCPayloadContainerWrapper({ RSCPayloadStream }: RSCPayl
8480
return promises;
8581
});
8682

87-
const getChunkPromise = React.useCallback((chunkIndex: number) => {
88-
if (chunkIndex > chunkPromises.length) {
89-
throw new Error('React on Rails Error: RSC Chunk index out of bounds');
90-
}
83+
const getChunkPromise = React.useCallback(
84+
(chunkIndex: number) => {
85+
if (chunkIndex > chunkPromises.length) {
86+
throw new Error('React on Rails Error: RSC Chunk index out of bounds');
87+
}
9188

92-
return chunkPromises[chunkIndex];
93-
}, [chunkPromises]);
89+
return chunkPromises[chunkIndex];
90+
},
91+
[chunkPromises],
92+
);
9493

9594
return React.createElement(
9695
React.Suspense,

node_package/src/RSCServerRoot.ts

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,36 @@ declare global {
1717
type RSCServerRootProps = {
1818
componentName: string;
1919
componentProps: Record<string, unknown>;
20-
}
20+
};
2121

2222
if (!('use' in React && typeof React.use === 'function')) {
23-
throw new Error('React.use is not defined. Please ensure you are using React 18 with experimental features enabled or React 19+ to use server components.');
23+
throw new Error(
24+
'React.use is not defined. Please ensure you are using React 18 with experimental features enabled or React 19+ to use server components.',
25+
);
2426
}
2527

2628
const { use } = React;
2729

28-
const createFromReactOnRailsNodeStream = (stream: NodeJS.ReadableStream, ssrManifest: Record<string, unknown>) => {
30+
const createFromReactOnRailsNodeStream = (
31+
stream: NodeJS.ReadableStream,
32+
ssrManifest: Record<string, unknown>,
33+
) => {
2934
const transformedStream = transformRSCStream(stream);
3035
return createFromNodeStream(transformedStream, ssrManifest);
31-
}
36+
};
3237

33-
const createSSRManifest = async (reactServerManifestFileName: string, reactClientManifestFileName: string) => {
38+
const createSSRManifest = async (
39+
reactServerManifestFileName: string,
40+
reactClientManifestFileName: string,
41+
) => {
3442
const [reactServerManifest, reactClientManifest] = await Promise.all([
3543
loadJsonFile(reactServerManifestFileName),
3644
loadJsonFile(reactClientManifestFileName),
3745
]);
3846

3947
const ssrManifest = {
4048
moduleLoading: {
41-
prefix: "/webpack/development/",
49+
prefix: '/webpack/development/',
4250
crossOrigin: null,
4351
},
4452
moduleMap: {} as Record<string, unknown>,
@@ -51,38 +59,47 @@ const createSSRManifest = async (reactServerManifestFileName: string, reactClien
5159
id: (serverFileBundlingInfo as { id: string }).id,
5260
chunks: (serverFileBundlingInfo as { chunks: string[] }).chunks,
5361
name: '*',
54-
}
62+
},
5563
};
5664
});
5765

5866
return ssrManifest;
59-
}
67+
};
6068

61-
const RSCServerRoot: RenderFunction = async ({ componentName, componentProps }: RSCServerRootProps, railsContext?: RailsContext) => {
62-
if (!railsContext?.serverSide || !railsContext?.reactClientManifestFileName || !railsContext?.reactServerClientManifestFileName) {
69+
const RSCServerRoot: RenderFunction = async (
70+
{ componentName, componentProps }: RSCServerRootProps,
71+
railsContext?: RailsContext,
72+
) => {
73+
if (
74+
!railsContext?.serverSide ||
75+
!railsContext?.reactClientManifestFileName ||
76+
!railsContext?.reactServerClientManifestFileName
77+
) {
6378
throw new Error(
64-
`${'serverClientManifestFileName and reactServerClientManifestFileName are required. ' +
65-
'Please ensure that React Server Component webpack configurations are properly set ' +
66-
'as stated in the React Server Component tutorial. The received rails context is: '}${ JSON.stringify(railsContext)}`
79+
`${
80+
'serverClientManifestFileName and reactServerClientManifestFileName are required. ' +
81+
'Please ensure that React Server Component webpack configurations are properly set ' +
82+
'as stated in the React Server Component tutorial. The received rails context is: '
83+
}${JSON.stringify(railsContext)}`,
6784
);
6885
}
6986

7087
if (typeof generateRSCPayload !== 'function') {
7188
throw new Error(
7289
'generateRSCPayload is not defined. Please ensure that you are using at least version 4.0.0 of ' +
73-
'React on Rails Pro and the node renderer, and that ReactOnRailsPro.configuration.enable_rsc_support ' +
74-
'is set to true.'
90+
'React on Rails Pro and the node renderer, and that ReactOnRailsPro.configuration.enable_rsc_support ' +
91+
'is set to true.',
7592
);
7693
}
7794

7895
const ssrManifest = await createSSRManifest(
7996
railsContext.reactServerClientManifestFileName,
80-
railsContext.reactClientManifestFileName
97+
railsContext.reactClientManifestFileName,
8198
);
8299
const rscPayloadStream = await generateRSCPayload(
83100
componentName,
84101
componentProps,
85-
railsContext.serverSideRSCPayloadParameters
102+
railsContext.serverSideRSCPayloadParameters,
86103
);
87104

88105
// Tee the stream to pass it to the server component and the payload container
@@ -92,20 +109,14 @@ const RSCServerRoot: RenderFunction = async ({ componentName, componentProps }:
92109
rscPayloadStream.pipe(rscPayloadStream2);
93110
const serverComponentElement = createFromReactOnRailsNodeStream(rscPayloadStream1, ssrManifest);
94111

95-
return () => React.createElement(
96-
React.Fragment,
97-
null, [
98-
React.createElement(
99-
React.Fragment,
100-
{ key: 'serverComponentElement' },
101-
use(serverComponentElement)
102-
),
103-
React.createElement(
104-
RSCPayloadContainer,
105-
{ RSCPayloadStream: rscPayloadStream2, key: 'rscPayloadContainer' },
106-
),
107-
]
108-
);
112+
return () =>
113+
React.createElement(React.Fragment, null, [
114+
React.createElement(React.Fragment, { key: 'serverComponentElement' }, use(serverComponentElement)),
115+
React.createElement(RSCPayloadContainer, {
116+
RSCPayloadStream: rscPayloadStream2,
117+
key: 'rscPayloadContainer',
118+
}),
119+
]);
109120
};
110121

111122
export default RSCServerRoot;

node_package/src/ReactOnRails.client.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ ctx.ReactOnRails = {
9393
}
9494

9595
if (Object.keys(newOptions).length > 0) {
96-
throw new Error(
97-
`Invalid options passed to ReactOnRails.options: ${JSON.stringify(newOptions)}`,
98-
);
96+
throw new Error(`Invalid options passed to ReactOnRails.options: ${JSON.stringify(newOptions)}`);
9997
}
10098
},
10199

node_package/src/buildConsoleReplay.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function consoleReplay(
5151
}
5252

5353
export default function buildConsoleReplay(
54-
customConsoleHistory: typeof console['history'] | undefined = undefined,
54+
customConsoleHistory: (typeof console)['history'] | undefined = undefined,
5555
numberOfMessagesToSkip: number = 0,
5656
): string {
5757
const consoleReplayJS = consoleReplay(customConsoleHistory, numberOfMessagesToSkip);

node_package/src/registerServerComponent/server.rsc.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import { ReactComponent, RenderFunction } from '../types';
33

44
/**
55
* Registers React Server Components (RSC) with React on Rails for the RSC bundle.
6-
*
6+
*
77
* This function handles the registration of components in the RSC bundle context,
88
* where components are registered directly into the ComponentRegistry without any
99
* additional wrapping. This is different from the server bundle registration,
1010
* which wraps components with RSCServerRoot.
11-
*
11+
*
1212
* @param components - Object mapping component names to their implementations
1313
*
1414
* @example
@@ -19,8 +19,7 @@ import { ReactComponent, RenderFunction } from '../types';
1919
* });
2020
* ```
2121
*/
22-
const registerServerComponent = (
23-
components: { [id: string]: ReactComponent | RenderFunction },
24-
) => ReactOnRails.register(components);
22+
const registerServerComponent = (components: { [id: string]: ReactComponent | RenderFunction }) =>
23+
ReactOnRails.register(components);
2524

2625
export default registerServerComponent;

node_package/src/registerServerComponent/server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import { ReactComponent, RenderFunction, RailsContext } from '../types';
44

55
/**
66
* Registers React Server Components (RSC) with React on Rails for the server bundle.
7-
*
7+
*
88
* This function wraps each component with RSCServerRoot, which handles the server-side
99
* rendering of React Server Components using pre-generated RSC payloads.
10-
*
10+
*
1111
* The RSCServerRoot component:
1212
* - Uses pre-generated RSC payloads from the RSC bundle
1313
* - Builds the rendering tree of the server component

node_package/src/streamServerRenderedReactComponent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export const transformRenderStreamChunksToResultObject = (renderState: StreamRen
9696
}
9797
const consoleReplayJsonChunk = JSON.stringify(createResultObject('', consoleReplayScript, renderState));
9898
return consoleReplayJsonChunk;
99-
}
99+
};
100100

101101
const transformStream = new PassThrough({
102102
transform(chunk, _, callback) {

node_package/src/transformRSCNodeStreamAndReplayConsoleLogs.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export default function transformRSCStream(stream: NodeJS.ReadableStream): NodeJ
3030
try {
3131
return stream.pipe(htmlExtractor);
3232
} catch (error) {
33-
throw new Error(`Error transforming RSC stream (${stream.constructor.name}), (stream: ${stream}), stringified stream: ${JSON.stringify(stream)}, error: ${error}`);
33+
throw new Error(
34+
`Error transforming RSC stream (${stream.constructor.name}), (stream: ${stream}), stringified stream: ${JSON.stringify(stream)}, error: ${error}`,
35+
);
3436
}
3537
}

node_package/src/transformRSCStreamAndReplayConsoleLogs.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { RSCPayloadChunk } from './types';
22

3-
export default function transformRSCStreamAndReplayConsoleLogs(stream: ReadableStream<Uint8Array | RenderResult>) {
3+
export default function transformRSCStreamAndReplayConsoleLogs(
4+
stream: ReadableStream<Uint8Array | RenderResult>,
5+
) {
46
return new ReadableStream({
57
async start(controller) {
68
const reader = stream.getReader();
@@ -9,12 +11,15 @@ export default function transformRSCStreamAndReplayConsoleLogs(stream: ReadableS
911

1012
let lastIncompleteChunk = '';
1113
let { value, done } = await reader.read();
12-
14+
1315
const handleJsonChunk = (chunk: RenderResult) => {
1416
const { html, consoleReplayScript = '' } = chunk;
1517
controller.enqueue(encoder.encode(html ?? ''));
1618

17-
const replayConsoleCode = consoleReplayScript.trim().replace(/^<script.*>/, '').replace(/<\/script>$/, '');
19+
const replayConsoleCode = consoleReplayScript
20+
.trim()
21+
.replace(/^<script.*>/, '')
22+
.replace(/<\/script>$/, '');
1823
if (replayConsoleCode?.trim() !== '') {
1924
const scriptElement = document.createElement('script');
2025
scriptElement.textContent = replayConsoleCode;

node_package/src/types/index.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,23 @@ export type RailsContext = {
3535
search: string | null;
3636
httpAcceptLanguage: string;
3737
rscPayloadGenerationUrl: string;
38-
} & ({
39-
serverSide: false;
40-
} | {
41-
serverSide: true;
42-
// These parameters are passed from React on Rails Pro to the node renderer.
43-
// They contain the necessary information to generate the RSC (React Server Components) payload.
44-
// Typically, this includes the bundle hash of the RSC bundle.
45-
// The react-on-rails package uses 'unknown' for these parameters to avoid direct dependency.
46-
// This ensures that if the communication protocol between the node renderer and the Rails server changes,
47-
// we don't need to update this type or introduce a breaking change.
48-
serverSideRSCPayloadParameters: unknown;
49-
reactClientManifestFileName?: string;
50-
reactServerClientManifestFileName?: string;
51-
});
38+
} & (
39+
| {
40+
serverSide: false;
41+
}
42+
| {
43+
serverSide: true;
44+
// These parameters are passed from React on Rails Pro to the node renderer.
45+
// They contain the necessary information to generate the RSC (React Server Components) payload.
46+
// Typically, this includes the bundle hash of the RSC bundle.
47+
// The react-on-rails package uses 'unknown' for these parameters to avoid direct dependency.
48+
// This ensures that if the communication protocol between the node renderer and the Rails server changes,
49+
// we don't need to update this type or introduce a breaking change.
50+
serverSideRSCPayloadParameters: unknown;
51+
reactClientManifestFileName?: string;
52+
reactServerClientManifestFileName?: string;
53+
}
54+
);
5255

5356
// not strictly what we want, see https://github.com/microsoft/TypeScript/issues/17867#issuecomment-323164375
5457
type AuthenticityHeaders = Record<string, string> & {

0 commit comments

Comments
 (0)