11import { PassThrough } from 'stream' ;
2- import { RailsContext , RSCPayloadStreamInfo , RSCPayloadCallback } from './types/index.ts' ;
2+ import {
3+ RailsContextWithServerComponentCapabilities ,
4+ RSCPayloadStreamInfo ,
5+ RSCPayloadCallback ,
6+ } from './types/index.ts' ;
37
48declare global {
59 function generateRSCPayload (
610 componentName : string ,
711 props : unknown ,
8- railsContext : RailsContext ,
12+ railsContext : RailsContextWithServerComponentCapabilities ,
913 ) : Promise < NodeJS . ReadableStream > ;
1014}
1115
12- const mapRailsContextToRSCPayloadStreams = new Map < RailsContext , RSCPayloadStreamInfo [ ] > ( ) ;
16+ const mapRailsContextToRSCPayloadStreams = new Map < string , RSCPayloadStreamInfo [ ] > ( ) ;
1317
14- const rscPayloadCallbacks = new Map < RailsContext , Array < RSCPayloadCallback > > ( ) ;
18+ const rscPayloadCallbacks = new Map < string , Array < RSCPayloadCallback > > ( ) ;
1519
1620/**
1721 * Registers a callback to be executed when RSC payloads are generated.
@@ -27,13 +31,17 @@ const rscPayloadCallbacks = new Map<RailsContext, Array<RSCPayloadCallback>>();
2731 * @param railsContext - Context for the current request
2832 * @param callback - Function to call when an RSC payload is generated
2933 */
30- export const onRSCPayloadGenerated = ( railsContext : RailsContext , callback : RSCPayloadCallback ) => {
31- const callbacks = rscPayloadCallbacks . get ( railsContext ) || [ ] ;
34+ export const onRSCPayloadGenerated = (
35+ railsContext : RailsContextWithServerComponentCapabilities ,
36+ callback : RSCPayloadCallback ,
37+ ) => {
38+ const { renderRequestId } = railsContext . componentSpecificMetadata ;
39+ const callbacks = rscPayloadCallbacks . get ( renderRequestId ) || [ ] ;
3240 callbacks . push ( callback ) ;
33- rscPayloadCallbacks . set ( railsContext , callbacks ) ;
41+ rscPayloadCallbacks . set ( renderRequestId , callbacks ) ;
3442
3543 // Call callback for any existing streams for this context
36- const existingStreams = mapRailsContextToRSCPayloadStreams . get ( railsContext ) || [ ] ;
44+ const existingStreams = mapRailsContextToRSCPayloadStreams . get ( renderRequestId ) || [ ] ;
3745 existingStreams . forEach ( ( streamInfo ) => callback ( streamInfo ) ) ;
3846} ;
3947
@@ -56,7 +64,7 @@ export const onRSCPayloadGenerated = (railsContext: RailsContext, callback: RSCP
5664export const getRSCPayloadStream = async (
5765 componentName : string ,
5866 props : unknown ,
59- railsContext : RailsContext ,
67+ railsContext : RailsContextWithServerComponentCapabilities ,
6068) : Promise < NodeJS . ReadableStream > => {
6169 if ( typeof generateRSCPayload !== 'function' ) {
6270 throw new Error (
@@ -66,8 +74,9 @@ export const getRSCPayloadStream = async (
6674 ) ;
6775 }
6876
77+ const { renderRequestId } = railsContext . componentSpecificMetadata ;
6978 const stream = await generateRSCPayload ( componentName , props , railsContext ) ;
70- const streams = mapRailsContextToRSCPayloadStreams . get ( railsContext ) ?? [ ] ;
79+ const streams = mapRailsContextToRSCPayloadStreams . get ( renderRequestId ) ?? [ ] ;
7180 const stream1 = new PassThrough ( ) ;
7281 stream . pipe ( stream1 ) ;
7382 const stream2 = new PassThrough ( ) ;
@@ -79,25 +88,29 @@ export const getRSCPayloadStream = async (
7988 stream : stream2 ,
8089 } ;
8190 streams . push ( streamInfo ) ;
82- mapRailsContextToRSCPayloadStreams . set ( railsContext , streams ) ;
91+ mapRailsContextToRSCPayloadStreams . set ( renderRequestId , streams ) ;
8392
8493 // Notify callbacks about the new stream in a sync manner to maintain proper hydration timing
8594 // as described in the comment above onRSCPayloadGenerated
86- const callbacks = rscPayloadCallbacks . get ( railsContext ) || [ ] ;
95+ const callbacks = rscPayloadCallbacks . get ( renderRequestId ) || [ ] ;
8796 callbacks . forEach ( ( callback ) => callback ( streamInfo ) ) ;
8897
8998 return stream1 ;
9099} ;
91100
92101export const getRSCPayloadStreams = (
93- railsContext : RailsContext ,
102+ railsContext : RailsContextWithServerComponentCapabilities ,
94103) : {
95104 componentName : string ;
96105 props : unknown ;
97106 stream : NodeJS . ReadableStream ;
98- } [ ] => mapRailsContextToRSCPayloadStreams . get ( railsContext ) ?? [ ] ;
107+ } [ ] => {
108+ const { renderRequestId } = railsContext . componentSpecificMetadata ;
109+ return mapRailsContextToRSCPayloadStreams . get ( renderRequestId ) ?? [ ] ;
110+ } ;
99111
100- export const clearRSCPayloadStreams = ( railsContext : RailsContext ) => {
101- mapRailsContextToRSCPayloadStreams . delete ( railsContext ) ;
102- rscPayloadCallbacks . delete ( railsContext ) ;
112+ export const clearRSCPayloadStreams = ( railsContext : RailsContextWithServerComponentCapabilities ) => {
113+ const { renderRequestId } = railsContext . componentSpecificMetadata ;
114+ mapRailsContextToRSCPayloadStreams . delete ( renderRequestId ) ;
115+ rscPayloadCallbacks . delete ( renderRequestId ) ;
103116} ;
0 commit comments