-
Notifications
You must be signed in to change notification settings - Fork 47.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Inline scripts and external runtime may require divergent implementations (or hand optimizations for code size). Since we do not need a bundle time fork, I split this to two different modules.
- Loading branch information
Showing
9 changed files
with
249 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ct-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInlineClientRenderBoundary.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
.../react-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInlineCompleteBoundary.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...-bindings/src/server/fizz-instruction-set/ReactDOMFizzInlineCompleteBoundaryWithStyles.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...s/react-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInlineCompleteSegment.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
...dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInstructionSetExternalRuntime.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/* eslint-disable dot-notation */ | ||
|
||
// Instruction set for the Fizz external runtime | ||
|
||
import { | ||
clientRenderBoundary, | ||
completeBoundary, | ||
completeSegment, | ||
LOADED, | ||
ERRORED, | ||
} from './ReactDOMFizzInstructionSetShared'; | ||
|
||
export {clientRenderBoundary, completeBoundary, completeSegment}; | ||
|
||
const resourceMap = new Map(); | ||
|
||
// This function is almost identical to the version used by inline scripts | ||
// (ReactDOMFizzInstructionSetInlineSource), with the exception of how we read | ||
// completeBoundary and resourceMap | ||
export function completeBoundaryWithStyles( | ||
suspenseBoundaryID, | ||
contentID, | ||
styles, | ||
) { | ||
const precedences = new Map(); | ||
const thisDocument = document; | ||
let lastResource, node; | ||
|
||
// Seed the precedence list with existing resources | ||
const nodes = thisDocument.querySelectorAll( | ||
'link[data-precedence],style[data-precedence]', | ||
); | ||
for (let i = 0; (node = nodes[i++]); ) { | ||
precedences.set(node.dataset['precedence'], (lastResource = node)); | ||
} | ||
|
||
let i = 0; | ||
const dependencies = []; | ||
let style, href, precedence, attr, loadingState, resourceEl; | ||
|
||
function setStatus(s) { | ||
this['s'] = s; | ||
} | ||
|
||
while ((style = styles[i++])) { | ||
let j = 0; | ||
href = style[j++]; | ||
// We check if this resource is already in our resourceMap and reuse it if so. | ||
// If it is already loaded we don't return it as a depenendency since there is nothing | ||
// to wait for | ||
loadingState = resourceMap.get(href); | ||
if (loadingState) { | ||
if (loadingState['s'] !== 'l') { | ||
dependencies.push(loadingState); | ||
} | ||
continue; | ||
} | ||
|
||
// We construct our new resource element, looping over remaining attributes if any | ||
// setting them to the Element. | ||
resourceEl = thisDocument.createElement('link'); | ||
resourceEl.href = href; | ||
resourceEl.rel = 'stylesheet'; | ||
resourceEl.dataset['precedence'] = precedence = style[j++]; | ||
while ((attr = style[j++])) { | ||
resourceEl.setAttribute(attr, style[j++]); | ||
} | ||
|
||
// We stash a pending promise in our map by href which will resolve or reject | ||
// when the underlying resource loads or errors. We add it to the dependencies | ||
// array to be returned. | ||
loadingState = resourceEl['_p'] = new Promise((re, rj) => { | ||
resourceEl.onload = re; | ||
resourceEl.onerror = rj; | ||
}); | ||
loadingState.then( | ||
setStatus.bind(loadingState, LOADED), | ||
setStatus.bind(loadingState, ERRORED), | ||
); | ||
resourceMap.set(href, loadingState); | ||
dependencies.push(loadingState); | ||
|
||
// The prior style resource is the last one placed at a given | ||
// precedence or the last resource itself which may be null. | ||
// We grab this value and then update the last resource for this | ||
// precedence to be the inserted element, updating the lastResource | ||
// pointer if needed. | ||
const prior = precedences.get(precedence) || lastResource; | ||
if (prior === lastResource) { | ||
lastResource = resourceEl; | ||
} | ||
precedences.set(precedence, resourceEl); | ||
|
||
// Finally, we insert the newly constructed instance at an appropriate location | ||
// in the Document. | ||
if (prior) { | ||
prior.parentNode.insertBefore(resourceEl, prior.nextSibling); | ||
} else { | ||
const head = thisDocument.head; | ||
head.insertBefore(resourceEl, head.firstChild); | ||
} | ||
} | ||
|
||
Promise.all(dependencies).then( | ||
completeBoundary.bind(null, suspenseBoundaryID, contentID, ''), | ||
completeBoundary.bind( | ||
null, | ||
suspenseBoundaryID, | ||
contentID, | ||
'Resource failed to load', | ||
), | ||
); | ||
} |
116 changes: 116 additions & 0 deletions
116
...ct-dom-bindings/src/server/fizz-instruction-set/ReactDOMFizzInstructionSetInlineSource.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* eslint-disable dot-notation */ | ||
|
||
// Instruction set for Fizz inline scripts. | ||
// DO NOT DIRECTLY IMPORT THIS FILE. This is the source for the compiled and | ||
// minified code in ReactDOMFizzInstructionSetInlineCodeStrings. | ||
|
||
import { | ||
clientRenderBoundary, | ||
completeBoundary, | ||
completeSegment, | ||
LOADED, | ||
ERRORED, | ||
} from './ReactDOMFizzInstructionSetShared'; | ||
|
||
export {clientRenderBoundary, completeBoundary, completeSegment}; | ||
|
||
// This function is almost identical to the version used by the external | ||
// runtime (ReactDOMFizzInstructionSetExternalRuntime), with the exception of | ||
// how we read completeBoundaryImpl and resourceMap | ||
export function completeBoundaryWithStyles( | ||
suspenseBoundaryID, | ||
contentID, | ||
styles, | ||
) { | ||
const completeBoundaryImpl = window['$RC']; | ||
const resourceMap = window['$RM']; | ||
|
||
const precedences = new Map(); | ||
const thisDocument = document; | ||
let lastResource, node; | ||
|
||
// Seed the precedence list with existing resources | ||
const nodes = thisDocument.querySelectorAll( | ||
'link[data-precedence],style[data-precedence]', | ||
); | ||
for (let i = 0; (node = nodes[i++]); ) { | ||
precedences.set(node.dataset['precedence'], (lastResource = node)); | ||
} | ||
|
||
let i = 0; | ||
const dependencies = []; | ||
let style, href, precedence, attr, loadingState, resourceEl; | ||
|
||
function setStatus(s) { | ||
this['s'] = s; | ||
} | ||
|
||
while ((style = styles[i++])) { | ||
let j = 0; | ||
href = style[j++]; | ||
// We check if this resource is already in our resourceMap and reuse it if so. | ||
// If it is already loaded we don't return it as a depenendency since there is nothing | ||
// to wait for | ||
loadingState = resourceMap.get(href); | ||
if (loadingState) { | ||
if (loadingState['s'] !== 'l') { | ||
dependencies.push(loadingState); | ||
} | ||
continue; | ||
} | ||
|
||
// We construct our new resource element, looping over remaining attributes if any | ||
// setting them to the Element. | ||
resourceEl = thisDocument.createElement('link'); | ||
resourceEl.href = href; | ||
resourceEl.rel = 'stylesheet'; | ||
resourceEl.dataset['precedence'] = precedence = style[j++]; | ||
while ((attr = style[j++])) { | ||
resourceEl.setAttribute(attr, style[j++]); | ||
} | ||
|
||
// We stash a pending promise in our map by href which will resolve or reject | ||
// when the underlying resource loads or errors. We add it to the dependencies | ||
// array to be returned. | ||
loadingState = resourceEl['_p'] = new Promise((re, rj) => { | ||
resourceEl.onload = re; | ||
resourceEl.onerror = rj; | ||
}); | ||
loadingState.then( | ||
setStatus.bind(loadingState, LOADED), | ||
setStatus.bind(loadingState, ERRORED), | ||
); | ||
resourceMap.set(href, loadingState); | ||
dependencies.push(loadingState); | ||
|
||
// The prior style resource is the last one placed at a given | ||
// precedence or the last resource itself which may be null. | ||
// We grab this value and then update the last resource for this | ||
// precedence to be the inserted element, updating the lastResource | ||
// pointer if needed. | ||
const prior = precedences.get(precedence) || lastResource; | ||
if (prior === lastResource) { | ||
lastResource = resourceEl; | ||
} | ||
precedences.set(precedence, resourceEl); | ||
|
||
// Finally, we insert the newly constructed instance at an appropriate location | ||
// in the Document. | ||
if (prior) { | ||
prior.parentNode.insertBefore(resourceEl, prior.nextSibling); | ||
} else { | ||
const head = thisDocument.head; | ||
head.insertBefore(resourceEl, head.firstChild); | ||
} | ||
} | ||
|
||
Promise.all(dependencies).then( | ||
completeBoundaryImpl.bind(null, suspenseBoundaryID, contentID, ''), | ||
completeBoundaryImpl.bind( | ||
null, | ||
suspenseBoundaryID, | ||
contentID, | ||
'Resource failed to load', | ||
), | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.