react-on-rails-pro 16.2.0-beta.0

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 (63) hide show
  1. package/lib/CallbackRegistry.d.ts +18 -0
  2. package/lib/CallbackRegistry.js +112 -0
  3. package/lib/ClientSideRenderer.d.ts +8 -0
  4. package/lib/ClientSideRenderer.js +238 -0
  5. package/lib/ComponentRegistry.d.ts +22 -0
  6. package/lib/ComponentRegistry.js +57 -0
  7. package/lib/PostSSRHookTracker.d.ts +32 -0
  8. package/lib/PostSSRHookTracker.js +70 -0
  9. package/lib/RSCProvider.d.ts +52 -0
  10. package/lib/RSCProvider.js +90 -0
  11. package/lib/RSCRequestTracker.d.ts +75 -0
  12. package/lib/RSCRequestTracker.js +130 -0
  13. package/lib/RSCRoute.d.ts +30 -0
  14. package/lib/RSCRoute.js +57 -0
  15. package/lib/ReactOnRails.client.d.ts +4 -0
  16. package/lib/ReactOnRails.client.js +20 -0
  17. package/lib/ReactOnRails.full.d.ts +4 -0
  18. package/lib/ReactOnRails.full.js +26 -0
  19. package/lib/ReactOnRails.node.d.ts +3 -0
  20. package/lib/ReactOnRails.node.js +21 -0
  21. package/lib/ReactOnRailsRSC.d.ts +4 -0
  22. package/lib/ReactOnRailsRSC.js +81 -0
  23. package/lib/ServerComponentFetchError.d.ts +15 -0
  24. package/lib/ServerComponentFetchError.js +33 -0
  25. package/lib/StoreRegistry.d.ts +59 -0
  26. package/lib/StoreRegistry.js +108 -0
  27. package/lib/createReactOnRailsPro.d.ts +7 -0
  28. package/lib/createReactOnRailsPro.js +111 -0
  29. package/lib/getReactServerComponent.client.d.ts +47 -0
  30. package/lib/getReactServerComponent.client.js +156 -0
  31. package/lib/getReactServerComponent.server.d.ts +39 -0
  32. package/lib/getReactServerComponent.server.js +70 -0
  33. package/lib/handleError.d.ts +5 -0
  34. package/lib/handleError.js +8 -0
  35. package/lib/handleErrorRSC.d.ts +4 -0
  36. package/lib/handleErrorRSC.js +11 -0
  37. package/lib/injectRSCPayload.d.ts +31 -0
  38. package/lib/injectRSCPayload.js +276 -0
  39. package/lib/loadJsonFile.d.ts +4 -0
  40. package/lib/loadJsonFile.js +36 -0
  41. package/lib/registerServerComponent/client.d.ts +33 -0
  42. package/lib/registerServerComponent/client.js +43 -0
  43. package/lib/registerServerComponent/server.d.ts +22 -0
  44. package/lib/registerServerComponent/server.js +31 -0
  45. package/lib/registerServerComponent/server.rsc.d.ts +24 -0
  46. package/lib/registerServerComponent/server.rsc.js +37 -0
  47. package/lib/streamServerRenderedReactComponent.d.ts +5 -0
  48. package/lib/streamServerRenderedReactComponent.js +76 -0
  49. package/lib/streamingUtils.d.ts +34 -0
  50. package/lib/streamingUtils.js +201 -0
  51. package/lib/transformRSCNodeStream.d.ts +16 -0
  52. package/lib/transformRSCNodeStream.js +56 -0
  53. package/lib/transformRSCStreamAndReplayConsoleLogs.d.ts +16 -0
  54. package/lib/transformRSCStreamAndReplayConsoleLogs.js +83 -0
  55. package/lib/utils.d.ts +26 -0
  56. package/lib/utils.js +43 -0
  57. package/lib/wrapServerComponentRenderer/client.d.ts +23 -0
  58. package/lib/wrapServerComponentRenderer/client.js +80 -0
  59. package/lib/wrapServerComponentRenderer/server.d.ts +23 -0
  60. package/lib/wrapServerComponentRenderer/server.js +59 -0
  61. package/lib/wrapServerComponentRenderer/server.rsc.d.ts +3 -0
  62. package/lib/wrapServerComponentRenderer/server.rsc.js +19 -0
  63. package/package.json +83 -0
@@ -0,0 +1,90 @@
1
+ /*
2
+ * Copyright (c) 2025 Shakacode LLC
3
+ *
4
+ * This file is NOT licensed under the MIT (open source) license.
5
+ * It is part of the React on Rails Pro offering and is licensed separately.
6
+ *
7
+ * Unauthorized copying, modification, distribution, or use of this file,
8
+ * via any medium, is strictly prohibited without a valid license agreement
9
+ * from Shakacode LLC.
10
+ *
11
+ * For licensing terms, please see:
12
+ * https://github.com/shakacode/react_on_rails/blob/master/REACT-ON-RAILS-PRO-LICENSE.md
13
+ */
14
+ 'use client';
15
+ import { jsx as _jsx } from "react/jsx-runtime";
16
+ import { createContext, useContext } from 'react';
17
+ import { createRSCPayloadKey } from "./utils.js";
18
+ const RSCContext = createContext(undefined);
19
+ /**
20
+ * Creates a provider context for React Server Components.
21
+ *
22
+ * RSCProvider is a foundational component that:
23
+ * 1. Provides caching for server components to prevent redundant requests
24
+ * 2. Manages the fetching of server components through getComponent
25
+ * 3. Offers environment-agnostic access to server components
26
+ *
27
+ * This factory function accepts an environment-specific getServerComponent implementation,
28
+ * allowing it to work correctly in both client and server environments.
29
+ *
30
+ * @param railsContext - Context for the current request
31
+ * @param getServerComponent - Environment-specific function for fetching server components
32
+ * @returns A provider component that wraps children with RSC context
33
+ *
34
+ * @important This is an internal function. End users should not use this directly.
35
+ * Instead, use wrapServerComponentRenderer from 'react-on-rails/wrapServerComponentRenderer/client'
36
+ * for client-side rendering or 'react-on-rails/wrapServerComponentRenderer/server' for server-side rendering.
37
+ */
38
+ export const createRSCProvider = ({ getServerComponent, }) => {
39
+ const fetchRSCPromises = {};
40
+ const getComponent = (componentName, componentProps) => {
41
+ const key = createRSCPayloadKey(componentName, componentProps);
42
+ if (key in fetchRSCPromises) {
43
+ return fetchRSCPromises[key];
44
+ }
45
+ const promise = getServerComponent({ componentName, componentProps });
46
+ fetchRSCPromises[key] = promise;
47
+ return promise;
48
+ };
49
+ const refetchComponent = (componentName, componentProps) => {
50
+ const key = createRSCPayloadKey(componentName, componentProps);
51
+ const promise = getServerComponent({
52
+ componentName,
53
+ componentProps,
54
+ enforceRefetch: true,
55
+ });
56
+ fetchRSCPromises[key] = promise;
57
+ return promise;
58
+ };
59
+ const contextValue = { getComponent, refetchComponent };
60
+ return ({ children }) => {
61
+ return _jsx(RSCContext.Provider, { value: contextValue, children: children });
62
+ };
63
+ };
64
+ /**
65
+ * Hook to access the RSC context within client components.
66
+ *
67
+ * This hook provides access to:
68
+ * - getComponent: For fetching and rendering server components
69
+ * - refetchComponent: For refetching server components
70
+ *
71
+ * It must be used within a component wrapped by RSCProvider (typically done
72
+ * automatically by wrapServerComponentRenderer).
73
+ *
74
+ * @returns The RSC context containing methods for working with server components
75
+ * @throws Error if used outside of an RSCProvider
76
+ *
77
+ * @example
78
+ * ```tsx
79
+ * const { getComponent } = useRSC();
80
+ * const serverComponent = use(getComponent('MyServerComponent', props));
81
+ * ```
82
+ */
83
+ export const useRSC = () => {
84
+ const context = useContext(RSCContext);
85
+ if (!context) {
86
+ throw new Error('useRSC must be used within a RSCProvider');
87
+ }
88
+ return context;
89
+ };
90
+ //# sourceMappingURL=RSCProvider.js.map
@@ -0,0 +1,75 @@
1
+ import { RSCPayloadStreamInfo, RSCPayloadCallback, RailsContextWithServerComponentMetadata } from 'react-on-rails/types';
2
+ /**
3
+ * Global function provided by React on Rails Pro for generating RSC payloads.
4
+ *
5
+ * This function is injected into the global scope during server-side rendering
6
+ * by the RORP rendering request. It handles the actual generation of React Server
7
+ * Component payloads on the server side.
8
+ *
9
+ * @see https://github.com/shakacode/react_on_rails_pro/blob/master/lib/react_on_rails_pro/server_rendering_js_code.rb
10
+ */
11
+ declare global {
12
+ function generateRSCPayload(componentName: string, props: unknown, railsContext: RailsContextWithServerComponentMetadata): Promise<NodeJS.ReadableStream>;
13
+ }
14
+ /**
15
+ * RSC Request Tracker - manages RSC payload generation and tracking for a single request.
16
+ *
17
+ * This class provides a local alternative to the global RSC payload management,
18
+ * allowing each request to have its own isolated tracker without sharing state.
19
+ * It includes both tracking functionality for the server renderer and fetching
20
+ * functionality for components.
21
+ */
22
+ declare class RSCRequestTracker {
23
+ private streams;
24
+ private callbacks;
25
+ private railsContext;
26
+ constructor(railsContext: RailsContextWithServerComponentMetadata);
27
+ /**
28
+ * Clears all streams and callbacks for this request.
29
+ * Should be called when the request is complete to ensure proper cleanup,
30
+ * though garbage collection will handle cleanup automatically when the tracker goes out of scope.
31
+ *
32
+ * This method is safe to call multiple times and will handle any errors during cleanup gracefully.
33
+ */
34
+ clear(): void;
35
+ /**
36
+ * Registers a callback to be executed when RSC payloads are generated.
37
+ *
38
+ * This function:
39
+ * 1. Stores the callback function for this tracker
40
+ * 2. Immediately executes the callback for any existing streams
41
+ *
42
+ * This synchronous execution is critical for preventing hydration race conditions.
43
+ * It ensures payload array initialization happens before component HTML appears
44
+ * in the response stream.
45
+ *
46
+ * @param callback - Function to call when an RSC payload is generated
47
+ */
48
+ onRSCPayloadGenerated(callback: RSCPayloadCallback): void;
49
+ /**
50
+ * Generates and tracks RSC payloads for server components.
51
+ *
52
+ * getRSCPayloadStream:
53
+ * 1. Calls the provided generateRSCPayload function
54
+ * 2. Tracks streams in this tracker for later access
55
+ * 3. Notifies callbacks immediately to enable early payload embedding
56
+ *
57
+ * The immediate callback notification is critical for preventing hydration race conditions,
58
+ * as it ensures the payload array is initialized in the HTML stream before component rendering.
59
+ *
60
+ * @param componentName - Name of the server component
61
+ * @param props - Props for the server component
62
+ * @returns A stream of the RSC payload
63
+ * @throws Error if generateRSCPayload is not available or fails
64
+ */
65
+ getRSCPayloadStream(componentName: string, props: unknown): Promise<NodeJS.ReadableStream>;
66
+ /**
67
+ * Returns all RSC payload streams tracked by this request tracker.
68
+ * Used by the server renderer to access all fetched RSCs for this request.
69
+ *
70
+ * @returns Array of RSC payload stream information
71
+ */
72
+ getRSCPayloadStreams(): RSCPayloadStreamInfo[];
73
+ }
74
+ export default RSCRequestTracker;
75
+ //# sourceMappingURL=RSCRequestTracker.d.ts.map
@@ -0,0 +1,130 @@
1
+ /*
2
+ * Copyright (c) 2025 Shakacode LLC
3
+ *
4
+ * This file is NOT licensed under the MIT (open source) license.
5
+ * It is part of the React on Rails Pro offering and is licensed separately.
6
+ *
7
+ * Unauthorized copying, modification, distribution, or use of this file,
8
+ * via any medium, is strictly prohibited without a valid license agreement
9
+ * from Shakacode LLC.
10
+ *
11
+ * For licensing terms, please see:
12
+ * https://github.com/shakacode/react_on_rails/blob/master/REACT-ON-RAILS-PRO-LICENSE.md
13
+ */
14
+ import { PassThrough } from 'stream';
15
+ import { extractErrorMessage } from "./utils.js";
16
+ /**
17
+ * RSC Request Tracker - manages RSC payload generation and tracking for a single request.
18
+ *
19
+ * This class provides a local alternative to the global RSC payload management,
20
+ * allowing each request to have its own isolated tracker without sharing state.
21
+ * It includes both tracking functionality for the server renderer and fetching
22
+ * functionality for components.
23
+ */
24
+ class RSCRequestTracker {
25
+ constructor(railsContext) {
26
+ this.streams = [];
27
+ this.callbacks = [];
28
+ this.railsContext = railsContext;
29
+ }
30
+ /**
31
+ * Clears all streams and callbacks for this request.
32
+ * Should be called when the request is complete to ensure proper cleanup,
33
+ * though garbage collection will handle cleanup automatically when the tracker goes out of scope.
34
+ *
35
+ * This method is safe to call multiple times and will handle any errors during cleanup gracefully.
36
+ */
37
+ clear() {
38
+ // Close any active streams before clearing
39
+ this.streams.forEach(({ stream, componentName }, index) => {
40
+ try {
41
+ if (stream && typeof stream.destroy === 'function') {
42
+ stream.destroy();
43
+ }
44
+ }
45
+ catch (error) {
46
+ // Log the error but don't throw to avoid disrupting cleanup of other streams
47
+ console.warn(`Warning: Error while destroying RSC stream for component "${componentName}" at index ${index}:`, error);
48
+ }
49
+ });
50
+ this.streams = [];
51
+ this.callbacks = [];
52
+ }
53
+ /**
54
+ * Registers a callback to be executed when RSC payloads are generated.
55
+ *
56
+ * This function:
57
+ * 1. Stores the callback function for this tracker
58
+ * 2. Immediately executes the callback for any existing streams
59
+ *
60
+ * This synchronous execution is critical for preventing hydration race conditions.
61
+ * It ensures payload array initialization happens before component HTML appears
62
+ * in the response stream.
63
+ *
64
+ * @param callback - Function to call when an RSC payload is generated
65
+ */
66
+ onRSCPayloadGenerated(callback) {
67
+ this.callbacks.push(callback);
68
+ // Call callback for any existing streams
69
+ this.streams.forEach(callback);
70
+ }
71
+ /**
72
+ * Generates and tracks RSC payloads for server components.
73
+ *
74
+ * getRSCPayloadStream:
75
+ * 1. Calls the provided generateRSCPayload function
76
+ * 2. Tracks streams in this tracker for later access
77
+ * 3. Notifies callbacks immediately to enable early payload embedding
78
+ *
79
+ * The immediate callback notification is critical for preventing hydration race conditions,
80
+ * as it ensures the payload array is initialized in the HTML stream before component rendering.
81
+ *
82
+ * @param componentName - Name of the server component
83
+ * @param props - Props for the server component
84
+ * @returns A stream of the RSC payload
85
+ * @throws Error if generateRSCPayload is not available or fails
86
+ */
87
+ async getRSCPayloadStream(componentName, props) {
88
+ // Validate that the global generateRSCPayload function is available
89
+ if (typeof generateRSCPayload !== 'function') {
90
+ throw new Error('generateRSCPayload is not defined. Please ensure that you are using at least version 4.0.0 of ' +
91
+ 'React on Rails Pro and the Node renderer, and that ReactOnRailsPro.configuration.enable_rsc_support ' +
92
+ 'is set to true.');
93
+ }
94
+ try {
95
+ const stream = await generateRSCPayload(componentName, props, this.railsContext);
96
+ // Tee stream to allow for multiple consumers:
97
+ // 1. stream1 - Used by React's runtime to perform server-side rendering
98
+ // 2. stream2 - Used by react-on-rails to embed the RSC payloads
99
+ // into the HTML stream for client-side hydration
100
+ const stream1 = new PassThrough();
101
+ stream.pipe(stream1);
102
+ const stream2 = new PassThrough();
103
+ stream.pipe(stream2);
104
+ const streamInfo = {
105
+ componentName,
106
+ props,
107
+ stream: stream2,
108
+ };
109
+ this.streams.push(streamInfo);
110
+ // Notify callbacks about the new stream in a sync manner to maintain proper hydration timing
111
+ this.callbacks.forEach((callback) => callback(streamInfo));
112
+ return stream1;
113
+ }
114
+ catch (error) {
115
+ // Provide a more helpful error message that includes context
116
+ throw new Error(`Failed to generate RSC payload for component "${componentName}": ${extractErrorMessage(error)}`);
117
+ }
118
+ }
119
+ /**
120
+ * Returns all RSC payload streams tracked by this request tracker.
121
+ * Used by the server renderer to access all fetched RSCs for this request.
122
+ *
123
+ * @returns Array of RSC payload stream information
124
+ */
125
+ getRSCPayloadStreams() {
126
+ return [...this.streams]; // Return a copy to prevent external mutation
127
+ }
128
+ }
129
+ export default RSCRequestTracker;
130
+ //# sourceMappingURL=RSCRequestTracker.js.map
@@ -0,0 +1,30 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * Renders a React Server Component inside a React Client Component.
4
+ *
5
+ * RSCRoute provides a bridge between client and server components, allowing server components
6
+ * to be directly rendered inside client components. This component:
7
+ *
8
+ * 1. During initial SSR - Uses the RSC payload to render the server component and embeds the payload in the page
9
+ * 2. During hydration - Uses the embedded RSC payload already in the page
10
+ * 3. During client navigation - Fetches the RSC payload via HTTP
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * <RSCRoute componentName="MyServerComponent" componentProps={{ user }} />
15
+ * ```
16
+ *
17
+ * @important Only use for server components whose props change rarely. Frequent prop changes
18
+ * will cause network requests for each change, impacting performance.
19
+ *
20
+ * @important This component expects that the component tree that contains it is wrapped using
21
+ * wrapServerComponentRenderer from 'react-on-rails/wrapServerComponentRenderer/client' for client-side
22
+ * rendering or 'react-on-rails/wrapServerComponentRenderer/server' for server-side rendering.
23
+ */
24
+ export type RSCRouteProps = {
25
+ componentName: string;
26
+ componentProps: unknown;
27
+ };
28
+ declare const RSCRoute: ({ componentName, componentProps }: RSCRouteProps) => ReactNode;
29
+ export default RSCRoute;
30
+ //# sourceMappingURL=RSCRoute.d.ts.map
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Copyright (c) 2025 Shakacode LLC
3
+ *
4
+ * This file is NOT licensed under the MIT (open source) license.
5
+ * It is part of the React on Rails Pro offering and is licensed separately.
6
+ *
7
+ * Unauthorized copying, modification, distribution, or use of this file,
8
+ * via any medium, is strictly prohibited without a valid license agreement
9
+ * from Shakacode LLC.
10
+ *
11
+ * For licensing terms, please see:
12
+ * https://github.com/shakacode/react_on_rails/blob/master/REACT-ON-RAILS-PRO-LICENSE.md
13
+ */
14
+ /// <reference types="react/experimental" />
15
+ 'use client';
16
+ import { jsx as _jsx } from "react/jsx-runtime";
17
+ import { Component, use } from 'react';
18
+ import { useRSC } from "./RSCProvider.js";
19
+ import { ServerComponentFetchError } from "./ServerComponentFetchError.js";
20
+ /**
21
+ * Error boundary component for RSCRoute that adds server component name and props to the error
22
+ * So, the parent ErrorBoundary can refetch the server component
23
+ */
24
+ class RSCRouteErrorBoundary extends Component {
25
+ constructor(props) {
26
+ super(props);
27
+ this.state = { error: null };
28
+ }
29
+ static getDerivedStateFromError(error) {
30
+ return { error };
31
+ }
32
+ render() {
33
+ const { error } = this.state;
34
+ const { componentName, componentProps, children } = this.props;
35
+ if (error) {
36
+ throw new ServerComponentFetchError(error.message, componentName, componentProps, error);
37
+ }
38
+ return children;
39
+ }
40
+ }
41
+ const PromiseWrapper = ({ promise }) => {
42
+ // use is available in React 18.3+
43
+ const promiseResult = use(promise);
44
+ // In case that an error happened during the rendering of the RSC payload before the rendering of the component itself starts
45
+ // RSC bundle will return an error object serialized inside the RSC payload
46
+ if (promiseResult instanceof Error) {
47
+ throw promiseResult;
48
+ }
49
+ return promiseResult;
50
+ };
51
+ const RSCRoute = ({ componentName, componentProps }) => {
52
+ const { getComponent } = useRSC();
53
+ const componentPromise = getComponent(componentName, componentProps);
54
+ return (_jsx(RSCRouteErrorBoundary, { componentName: componentName, componentProps: componentProps, children: _jsx(PromiseWrapper, { promise: componentPromise }) }));
55
+ };
56
+ export default RSCRoute;
57
+ //# sourceMappingURL=RSCRoute.js.map
@@ -0,0 +1,4 @@
1
+ declare const ReactOnRails: import("react-on-rails/types").ReactOnRailsInternal;
2
+ export * from 'react-on-rails/types';
3
+ export default ReactOnRails;
4
+ //# sourceMappingURL=ReactOnRails.client.d.ts.map
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Copyright (c) 2025 Shakacode LLC
3
+ *
4
+ * This file is NOT licensed under the MIT (open source) license.
5
+ * It is part of the React on Rails Pro offering and is licensed separately.
6
+ *
7
+ * Unauthorized copying, modification, distribution, or use of this file,
8
+ * via any medium, is strictly prohibited without a valid license agreement
9
+ * from Shakacode LLC.
10
+ *
11
+ * For licensing terms, please see:
12
+ * https://github.com/shakacode/react_on_rails/blob/master/REACT-ON-RAILS-PRO-LICENSE.md
13
+ */
14
+ import { createBaseClientObject } from 'react-on-rails/@internal/base/client';
15
+ import createReactOnRailsPro from "./createReactOnRailsPro.js";
16
+ const currentGlobal = globalThis.ReactOnRails || null;
17
+ const ReactOnRails = createReactOnRailsPro(createBaseClientObject, currentGlobal);
18
+ export * from 'react-on-rails/types';
19
+ export default ReactOnRails;
20
+ //# sourceMappingURL=ReactOnRails.client.js.map
@@ -0,0 +1,4 @@
1
+ declare const ReactOnRails: import("react-on-rails/types").ReactOnRailsInternal;
2
+ export * from 'react-on-rails/types';
3
+ export default ReactOnRails;
4
+ //# sourceMappingURL=ReactOnRails.full.d.ts.map
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright (c) 2025 Shakacode LLC
3
+ *
4
+ * This file is NOT licensed under the MIT (open source) license.
5
+ * It is part of the React on Rails Pro offering and is licensed separately.
6
+ *
7
+ * Unauthorized copying, modification, distribution, or use of this file,
8
+ * via any medium, is strictly prohibited without a valid license agreement
9
+ * from Shakacode LLC.
10
+ *
11
+ * For licensing terms, please see:
12
+ * https://github.com/shakacode/react_on_rails/blob/master/REACT-ON-RAILS-PRO-LICENSE.md
13
+ */
14
+ import { createBaseFullObject } from 'react-on-rails/@internal/base/full';
15
+ import createReactOnRailsPro from "./createReactOnRailsPro.js";
16
+ // Warn about bundle size when included in browser bundles
17
+ if (typeof window !== 'undefined') {
18
+ console.warn('Optimization opportunity: "react-on-rails-pro" includes ~14KB of server-rendering code. ' +
19
+ 'Browsers may not need it. See https://forum.shakacode.com/t/how-to-use-different-versions-of-a-file-for-client-and-server-rendering/1352 ' +
20
+ '(Requires creating a free account). Click this for the stack trace.');
21
+ }
22
+ const currentGlobal = globalThis.ReactOnRails || null;
23
+ const ReactOnRails = createReactOnRailsPro(createBaseFullObject, currentGlobal);
24
+ export * from 'react-on-rails/types';
25
+ export default ReactOnRails;
26
+ //# sourceMappingURL=ReactOnRails.full.js.map
@@ -0,0 +1,3 @@
1
+ export * from './ReactOnRails.full.ts';
2
+ export { default } from './ReactOnRails.full.ts';
3
+ //# sourceMappingURL=ReactOnRails.node.d.ts.map
@@ -0,0 +1,21 @@
1
+ /*
2
+ * Copyright (c) 2025 Shakacode LLC
3
+ *
4
+ * This file is NOT licensed under the MIT (open source) license.
5
+ * It is part of the React on Rails Pro offering and is licensed separately.
6
+ *
7
+ * Unauthorized copying, modification, distribution, or use of this file,
8
+ * via any medium, is strictly prohibited without a valid license agreement
9
+ * from Shakacode LLC.
10
+ *
11
+ * For licensing terms, please see:
12
+ * https://github.com/shakacode/react_on_rails/blob/master/REACT-ON-RAILS-PRO-LICENSE.md
13
+ */
14
+ import ReactOnRails from "./ReactOnRails.full.js";
15
+ import streamServerRenderedReactComponent from "./streamServerRenderedReactComponent.js";
16
+ // Add Pro server-side streaming functionality
17
+ ReactOnRails.streamServerRenderedReactComponent = streamServerRenderedReactComponent;
18
+ export * from "./ReactOnRails.full.js";
19
+ // eslint-disable-next-line no-restricted-exports -- see https://github.com/eslint/eslint/issues/15617
20
+ export { default } from "./ReactOnRails.full.js";
21
+ //# sourceMappingURL=ReactOnRails.node.js.map
@@ -0,0 +1,4 @@
1
+ import ReactOnRails from './ReactOnRails.full.ts';
2
+ export * from 'react-on-rails/types';
3
+ export default ReactOnRails;
4
+ //# sourceMappingURL=ReactOnRailsRSC.d.ts.map
@@ -0,0 +1,81 @@
1
+ /*
2
+ * Copyright (c) 2025 Shakacode LLC
3
+ *
4
+ * This file is NOT licensed under the MIT (open source) license.
5
+ * It is part of the React on Rails Pro offering and is licensed separately.
6
+ *
7
+ * Unauthorized copying, modification, distribution, or use of this file,
8
+ * via any medium, is strictly prohibited without a valid license agreement
9
+ * from Shakacode LLC.
10
+ *
11
+ * For licensing terms, please see:
12
+ * https://github.com/shakacode/react_on_rails/blob/master/REACT-ON-RAILS-PRO-LICENSE.md
13
+ */
14
+ import { buildServerRenderer } from 'react-on-rails-rsc/server.node';
15
+ import { assertRailsContextWithServerStreamingCapabilities, } from 'react-on-rails/types';
16
+ import { convertToError } from 'react-on-rails/serverRenderUtils';
17
+ import handleError from "./handleErrorRSC.js";
18
+ import ReactOnRails from "./ReactOnRails.full.js";
19
+ import { streamServerRenderedComponent, transformRenderStreamChunksToResultObject, } from "./streamingUtils.js";
20
+ import loadJsonFile from "./loadJsonFile.js";
21
+ let serverRendererPromise;
22
+ const streamRenderRSCComponent = (reactRenderingResult, options, streamingTrackers) => {
23
+ const { throwJsErrors } = options;
24
+ const { railsContext } = options;
25
+ assertRailsContextWithServerStreamingCapabilities(railsContext);
26
+ const { reactClientManifestFileName } = railsContext;
27
+ const renderState = {
28
+ result: null,
29
+ hasErrors: false,
30
+ isShellReady: true,
31
+ };
32
+ const { pipeToTransform, readableStream, emitError } = transformRenderStreamChunksToResultObject(renderState);
33
+ const reportError = (error) => {
34
+ console.error('Error in RSC stream', error);
35
+ if (throwJsErrors) {
36
+ emitError(error);
37
+ }
38
+ renderState.hasErrors = true;
39
+ renderState.error = error;
40
+ };
41
+ const initializeAndRender = async () => {
42
+ if (!serverRendererPromise) {
43
+ serverRendererPromise = loadJsonFile(reactClientManifestFileName)
44
+ .then((reactClientManifest) => buildServerRenderer(reactClientManifest))
45
+ .catch((err) => {
46
+ serverRendererPromise = undefined;
47
+ throw err;
48
+ });
49
+ }
50
+ const { renderToPipeableStream } = await serverRendererPromise;
51
+ const rscStream = renderToPipeableStream(await reactRenderingResult, {
52
+ onError: (err) => {
53
+ const error = convertToError(err);
54
+ reportError(error);
55
+ },
56
+ });
57
+ pipeToTransform(rscStream);
58
+ };
59
+ initializeAndRender().catch((e) => {
60
+ const error = convertToError(e);
61
+ reportError(error);
62
+ const errorHtml = handleError({ e: error, name: options.name, serverSide: true });
63
+ pipeToTransform(errorHtml);
64
+ });
65
+ readableStream.on('end', () => {
66
+ streamingTrackers.postSSRHookTracker.notifySSREnd();
67
+ });
68
+ return readableStream;
69
+ };
70
+ ReactOnRails.serverRenderRSCReactComponent = (options) => {
71
+ try {
72
+ return streamServerRenderedComponent(options, streamRenderRSCComponent, handleError);
73
+ }
74
+ finally {
75
+ console.history = [];
76
+ }
77
+ };
78
+ ReactOnRails.isRSCBundle = true;
79
+ export * from 'react-on-rails/types';
80
+ export default ReactOnRails;
81
+ //# sourceMappingURL=ReactOnRailsRSC.js.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Custom error type for when there's an issue fetching or rendering a server component.
3
+ * This error includes information about the server component and the original error that occurred.
4
+ */
5
+ export declare class ServerComponentFetchError extends Error {
6
+ serverComponentName: string;
7
+ serverComponentProps: unknown;
8
+ originalError: Error;
9
+ constructor(message: string, componentName: string, componentProps: unknown, originalError: Error);
10
+ }
11
+ /**
12
+ * Type guard to check if an error is a ServerComponentFetchError
13
+ */
14
+ export declare function isServerComponentFetchError(error: unknown): error is ServerComponentFetchError;
15
+ //# sourceMappingURL=ServerComponentFetchError.d.ts.map
@@ -0,0 +1,33 @@
1
+ /*
2
+ * Copyright (c) 2025 Shakacode LLC
3
+ *
4
+ * This file is NOT licensed under the MIT (open source) license.
5
+ * It is part of the React on Rails Pro offering and is licensed separately.
6
+ *
7
+ * Unauthorized copying, modification, distribution, or use of this file,
8
+ * via any medium, is strictly prohibited without a valid license agreement
9
+ * from Shakacode LLC.
10
+ *
11
+ * For licensing terms, please see:
12
+ * https://github.com/shakacode/react_on_rails/blob/master/REACT-ON-RAILS-PRO-LICENSE.md
13
+ */
14
+ /**
15
+ * Custom error type for when there's an issue fetching or rendering a server component.
16
+ * This error includes information about the server component and the original error that occurred.
17
+ */
18
+ export class ServerComponentFetchError extends Error {
19
+ constructor(message, componentName, componentProps, originalError) {
20
+ super(message);
21
+ this.name = 'ServerComponentFetchError';
22
+ this.serverComponentName = componentName;
23
+ this.serverComponentProps = componentProps;
24
+ this.originalError = originalError;
25
+ }
26
+ }
27
+ /**
28
+ * Type guard to check if an error is a ServerComponentFetchError
29
+ */
30
+ export function isServerComponentFetchError(error) {
31
+ return error instanceof ServerComponentFetchError;
32
+ }
33
+ //# sourceMappingURL=ServerComponentFetchError.js.map
@@ -0,0 +1,59 @@
1
+ import type { Store, StoreGenerator } from 'react-on-rails/types';
2
+ /**
3
+ * Register a store generator, a function that takes props and returns a store.
4
+ * @param storeGenerators { name1: storeGenerator1, name2: storeGenerator2 }
5
+ * @public
6
+ */
7
+ export declare function register(storeGenerators: Record<string, StoreGenerator>): void;
8
+ /**
9
+ * Used by components to get the hydrated store which contains props.
10
+ * @param name
11
+ * @param throwIfMissing Defaults to true. Set to false to have this call return undefined if
12
+ * there is no store with the given name.
13
+ * @returns Redux Store, possibly hydrated
14
+ * @public
15
+ */
16
+ export declare function getStore(name: string, throwIfMissing?: boolean): Store | undefined;
17
+ /**
18
+ * Internally used function to get the store creator that was passed to `register`.
19
+ * @param name
20
+ * @returns storeCreator with given name
21
+ * @public
22
+ */
23
+ export declare const getStoreGenerator: (name: string) => StoreGenerator;
24
+ /**
25
+ * Internally used function to set the hydrated store after a Rails page is loaded.
26
+ * @param name
27
+ * @param store (not the storeGenerator, but the hydrated store)
28
+ */
29
+ export declare function setStore(name: string, store: Store): void;
30
+ /**
31
+ * Internally used function to completely clear hydratedStores Map.
32
+ * @public
33
+ */
34
+ export declare function clearHydratedStores(): void;
35
+ /**
36
+ * Get a Map containing all registered store generators. Useful for debugging.
37
+ * @returns Map where key is the component name and values are the store generators.
38
+ * @public
39
+ */
40
+ export declare const storeGenerators: () => Map<string, StoreGenerator>;
41
+ /**
42
+ * Get a Map containing all hydrated stores. Useful for debugging.
43
+ * @returns Map where key is the component name and values are the hydrated stores.
44
+ * @public
45
+ */
46
+ export declare const stores: () => Map<string, Store>;
47
+ /**
48
+ * Used by components to get the hydrated store, waiting for it to be hydrated if necessary.
49
+ * @param name Name of the store to wait for
50
+ * @returns Promise that resolves with the Store once hydrated
51
+ */
52
+ export declare const getOrWaitForStore: (name: string) => Promise<Store>;
53
+ /**
54
+ * Used by components to get the store generator, waiting for it to be registered if necessary.
55
+ * @param name Name of the store generator to wait for
56
+ * @returns Promise that resolves with the StoreGenerator once registered
57
+ */
58
+ export declare const getOrWaitForStoreGenerator: (name: string) => Promise<StoreGenerator>;
59
+ //# sourceMappingURL=StoreRegistry.d.ts.map