@@ -130,11 +130,8 @@ export type ResponseState = {
130130 startInlineScript : PrecomputedChunk ,
131131 instructions : InstructionState ,
132132
133- // state for outputting CSP nonce
134- nonce : string | void ,
135-
136133 // state for data streaming format
137- externalRuntimeConfig : BootstrapScriptDescriptor | null ,
134+ externalRuntimeScript : null | ExternalRuntimeScript ,
138135
139136 // preamble and postamble chunks and state
140137 htmlChunks : null | Array < Chunk | PrecomputedChunk > ,
@@ -196,6 +193,10 @@ export type BootstrapScriptDescriptor = {
196193 src : string ,
197194 integrity ?: string ,
198195} ;
196+ export type ExternalRuntimeScript = {
197+ src : string ,
198+ chunks : Array < Chunk | PrecomputedChunk > ,
199+ } ;
199200// Allows us to keep track of what we've already written so we can refer back to it.
200201// if passed externalRuntimeConfig and the enableFizzExternalRuntime feature flag
201202// is set, the server will send instructions via data attributes (instead of inline scripts)
@@ -215,7 +216,7 @@ export function createResponseState(
215216 '<script nonce="' + escapeTextForBrowser ( nonce ) + '">' ,
216217 ) ;
217218 const bootstrapChunks : Array < Chunk | PrecomputedChunk > = [ ] ;
218- let externalRuntimeDesc = null ;
219+ let externalRuntimeScript : null | ExternalRuntimeScript = null ;
219220 let streamingFormat = ScriptStreamingFormat ;
220221 if ( bootstrapScriptContent !== undefined ) {
221222 bootstrapChunks . push (
@@ -233,12 +234,27 @@ export function createResponseState(
233234 if ( externalRuntimeConfig !== undefined ) {
234235 streamingFormat = DataStreamingFormat ;
235236 if ( typeof externalRuntimeConfig === 'string' ) {
236- externalRuntimeDesc = {
237+ externalRuntimeScript = {
237238 src : externalRuntimeConfig ,
238- integrity : undefined ,
239+ chunks : [ ] ,
239240 } ;
241+ pushScriptImpl ( externalRuntimeScript . chunks , {
242+ src : externalRuntimeConfig ,
243+ async : true ,
244+ integrity : undefined ,
245+ nonce : nonce ,
246+ } ) ;
240247 } else {
241- externalRuntimeDesc = externalRuntimeConfig ;
248+ externalRuntimeScript = {
249+ src : externalRuntimeConfig . src ,
250+ chunks : [ ] ,
251+ } ;
252+ pushScriptImpl ( externalRuntimeScript . chunks , {
253+ src : externalRuntimeConfig . src ,
254+ async : true ,
255+ integrity : externalRuntimeConfig . integrity ,
256+ nonce : nonce ,
257+ } ) ;
242258 }
243259 }
244260 }
@@ -307,7 +323,7 @@ export function createResponseState(
307323 streamingFormat ,
308324 startInlineScript : inlineScriptWithNonce ,
309325 instructions : NothingSent ,
310- externalRuntimeConfig : externalRuntimeDesc ,
326+ externalRuntimeScript ,
311327 htmlChunks : null ,
312328 headChunks : null ,
313329 hasBody : false ,
@@ -1293,7 +1309,7 @@ function injectFormReplayingRuntime(responseState: ResponseState): void {
12931309 // to emit anything. It's always used.
12941310 if (
12951311 ( responseState . instructions & SentFormReplayingRuntime ) === NothingSent &&
1296- ( ! enableFizzExternalRuntime || ! responseState . externalRuntimeConfig )
1312+ ( ! enableFizzExternalRuntime || ! responseState . externalRuntimeScript )
12971313 ) {
12981314 responseState . instructions |= SentFormReplayingRuntime ;
12991315 responseState . bootstrapChunks . unshift (
@@ -4078,15 +4094,15 @@ export function writePreamble(
40784094 if (
40794095 enableFizzExternalRuntime &&
40804096 ! willFlushAllSegments &&
4081- responseState . externalRuntimeConfig
4097+ responseState . externalRuntimeScript
40824098 ) {
40834099 // If the root segment is incomplete due to suspended tasks
40844100 // (e.g. willFlushAllSegments = false) and we are using data
40854101 // streaming format, ensure the external runtime is sent.
40864102 // (User code could choose to send this even earlier by calling
40874103 // preinit(...), if they know they will suspend).
4088- const { src , integrity } = responseState . externalRuntimeConfig ;
4089- internalPreinitScript ( resources , src , integrity , responseState . nonce ) ;
4104+ const { src , chunks } = responseState . externalRuntimeScript ;
4105+ internalPreinitScript ( resources , src , chunks ) ;
40904106 }
40914107
40924108 const htmlChunks = responseState . htmlChunks ;
@@ -5362,32 +5378,22 @@ function preinit(href: string, options: PreinitOptions): void {
53625378 }
53635379}
53645380
5365- // This method is trusted. It must only be called from within this codebase and it assumes the arguments
5366- // conform to the types because no user input is being passed in. It also assumes that it is being called as
5367- // part of a work or flush loop and therefore does not need to request Fizz to flush Resources.
53685381function internalPreinitScript (
53695382 resources : Resources ,
53705383 src : string ,
5371- integrity : ?string ,
5372- nonce : ?string ,
5384+ chunks : Array < Chunk | PrecomputedChunk > ,
53735385) : void {
53745386 const key = getResourceKey ( 'script' , src ) ;
53755387 let resource = resources . scriptsMap . get ( key ) ;
53765388 if ( ! resource ) {
53775389 resource = {
53785390 type : 'script' ,
5379- chunks : [ ] ,
5391+ chunks,
53805392 state : NoState ,
53815393 props : null ,
53825394 } ;
53835395 resources . scriptsMap . set ( key , resource ) ;
53845396 resources . scripts . add ( resource ) ;
5385- pushScriptImpl ( resource . chunks , {
5386- async : true ,
5387- src,
5388- integrity,
5389- nonce,
5390- } ) ;
53915397 }
53925398 return ;
53935399}
0 commit comments