-
Notifications
You must be signed in to change notification settings - Fork 47k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract Fizz instruction set to build macro (#25457)
We're adding an option to Fizz to support an alternate output format that doesn't rely on inline script tags (see #25437). The two outputs will share the same "instruction set" of functions. These functions are currently inlined into the source file; to make this a bit more maintainable, and eventually have a single source of truth, in preparation for the new option, this commit moves the instruction set to a separate files that are imported. In the future, we could improve this further by running Closure on the instruction set and generating it at build time. This isn't an urgent improvement, though, because we rarely modify the instruction set. Co-authored-by: Mofei Zhang <feifei0@fb.com> Co-authored-by: Mofei Zhang <feifei0@fb.com>
- Loading branch information
Showing
5 changed files
with
256 additions
and
213 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
38 changes: 38 additions & 0 deletions
38
packages/react-dom-bindings/src/server/fizz-instruction-set/clientRenderFunctionString.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,38 @@ | ||
// Instruction Set | ||
|
||
// The following code is the source scripts that we then minify and inline below, | ||
// with renamed function names that we hope don't collide: | ||
|
||
// const COMMENT_NODE = 8; | ||
// const SUSPENSE_START_DATA = '$'; | ||
// const SUSPENSE_END_DATA = '/$'; | ||
// const SUSPENSE_PENDING_START_DATA = '$?'; | ||
// const SUSPENSE_FALLBACK_START_DATA = '$!'; | ||
// const LOADED = 'l'; | ||
// const ERRORED = 'e'; | ||
|
||
// function clientRenderBoundary(suspenseBoundaryID, errorDigest, errorMsg, errorComponentStack) { | ||
// // Find the fallback's first element. | ||
// const suspenseIdNode = document.getElementById(suspenseBoundaryID); | ||
// if (!suspenseIdNode) { | ||
// // The user must have already navigated away from this tree. | ||
// // E.g. because the parent was hydrated. | ||
// return; | ||
// } | ||
// // Find the boundary around the fallback. This is always the previous node. | ||
// const suspenseNode = suspenseIdNode.previousSibling; | ||
// // Tag it to be client rendered. | ||
// suspenseNode.data = SUSPENSE_FALLBACK_START_DATA; | ||
// // assign error metadata to first sibling | ||
// let dataset = suspenseIdNode.dataset; | ||
// if (errorDigest) dataset.dgst = errorDigest; | ||
// if (errorMsg) dataset.msg = errorMsg; | ||
// if (errorComponentStack) dataset.stck = errorComponentStack; | ||
// // Tell React to retry it if the parent already hydrated. | ||
// if (suspenseNode._reactRetry) { | ||
// suspenseNode._reactRetry(); | ||
// } | ||
// } | ||
|
||
// TODO: Generate this file with a build step. | ||
export default 'function $RX(b,c,d,e){var a=document.getElementById(b);a&&(b=a.previousSibling,b.data="$!",a=a.dataset,c&&(a.dgst=c),d&&(a.msg=d),e&&(a.stck=e),b._reactRetry&&b._reactRetry())}'; |
82 changes: 82 additions & 0 deletions
82
...ages/react-dom-bindings/src/server/fizz-instruction-set/completeBoundaryFunctionString.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,82 @@ | ||
// Instruction Set | ||
|
||
// The following code is the source scripts that we then minify and inline below, | ||
// with renamed function names that we hope don't collide: | ||
|
||
// const COMMENT_NODE = 8; | ||
// const SUSPENSE_START_DATA = '$'; | ||
// const SUSPENSE_END_DATA = '/$'; | ||
// const SUSPENSE_PENDING_START_DATA = '$?'; | ||
// const SUSPENSE_FALLBACK_START_DATA = '$!'; | ||
// const LOADED = 'l'; | ||
// const ERRORED = 'e'; | ||
|
||
// function completeBoundary(suspenseBoundaryID, contentID, errorDigest) { | ||
// const contentNode = document.getElementById(contentID); | ||
// // We'll detach the content node so that regardless of what happens next we don't leave in the tree. | ||
// // This might also help by not causing recalcing each time we move a child from here to the target. | ||
// contentNode.parentNode.removeChild(contentNode); | ||
|
||
// // Find the fallback's first element. | ||
// const suspenseIdNode = document.getElementById(suspenseBoundaryID); | ||
// if (!suspenseIdNode) { | ||
// // The user must have already navigated away from this tree. | ||
// // E.g. because the parent was hydrated. That's fine there's nothing to do | ||
// // but we have to make sure that we already deleted the container node. | ||
// return; | ||
// } | ||
// // Find the boundary around the fallback. This is always the previous node. | ||
// const suspenseNode = suspenseIdNode.previousSibling; | ||
|
||
// if (!errorDigest) { | ||
// // Clear all the existing children. This is complicated because | ||
// // there can be embedded Suspense boundaries in the fallback. | ||
// // This is similar to clearSuspenseBoundary in ReactDOMHostConfig. | ||
// // TODO: We could avoid this if we never emitted suspense boundaries in fallback trees. | ||
// // They never hydrate anyway. However, currently we support incrementally loading the fallback. | ||
// const parentInstance = suspenseNode.parentNode; | ||
// let node = suspenseNode.nextSibling; | ||
// let depth = 0; | ||
// do { | ||
// if (node && node.nodeType === COMMENT_NODE) { | ||
// const data = node.data; | ||
// if (data === SUSPENSE_END_DATA) { | ||
// if (depth === 0) { | ||
// break; | ||
// } else { | ||
// depth--; | ||
// } | ||
// } else if ( | ||
// data === SUSPENSE_START_DATA || | ||
// data === SUSPENSE_PENDING_START_DATA || | ||
// data === SUSPENSE_FALLBACK_START_DATA | ||
// ) { | ||
// depth++; | ||
// } | ||
// } | ||
|
||
// const nextNode = node.nextSibling; | ||
// parentInstance.removeChild(node); | ||
// node = nextNode; | ||
// } while (node); | ||
|
||
// const endOfBoundary = node; | ||
|
||
// // Insert all the children from the contentNode between the start and end of suspense boundary. | ||
// while (contentNode.firstChild) { | ||
// parentInstance.insertBefore(contentNode.firstChild, endOfBoundary); | ||
// } | ||
|
||
// suspenseNode.data = SUSPENSE_START_DATA; | ||
// } else { | ||
// suspenseNode.data = SUSPENSE_FALLBACK_START_DATA; | ||
// suspenseIdNode.setAttribute('data-dgst', errorDigest) | ||
// } | ||
|
||
// if (suspenseNode._reactRetry) { | ||
// suspenseNode._reactRetry(); | ||
// } | ||
// } | ||
|
||
// TODO: Generate this file with a build step. | ||
export default 'function $RC(b,c,d){c=document.getElementById(c);c.parentNode.removeChild(c);var a=document.getElementById(b);if(a){b=a.previousSibling;if(d)b.data="$!",a.setAttribute("data-dgst",d);else{d=b.parentNode;a=b.nextSibling;var e=0;do{if(a&&a.nodeType===8){var h=a.data;if(h==="/$")if(0===e)break;else e--;else h!=="$"&&h!=="$?"&&h!=="$!"||e++}h=a.nextSibling;d.removeChild(a);a=h}while(a);for(;c.firstChild;)d.insertBefore(c.firstChild,a);b.data="$"}b._reactRetry&&b._reactRetry()}}'; |
31 changes: 31 additions & 0 deletions
31
packages/react-dom-bindings/src/server/fizz-instruction-set/completeSegmentFunctionString.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,31 @@ | ||
// Instruction Set | ||
|
||
// The following code is the source scripts that we then minify and inline below, | ||
// with renamed function names that we hope don't collide: | ||
|
||
// const COMMENT_NODE = 8; | ||
// const SUSPENSE_START_DATA = '$'; | ||
// const SUSPENSE_END_DATA = '/$'; | ||
// const SUSPENSE_PENDING_START_DATA = '$?'; | ||
// const SUSPENSE_FALLBACK_START_DATA = '$!'; | ||
// const LOADED = 'l'; | ||
// const ERRORED = 'e'; | ||
|
||
// function completeSegment(containerID, placeholderID) { | ||
// const segmentContainer = document.getElementById(containerID); | ||
// const placeholderNode = document.getElementById(placeholderID); | ||
// // We always expect both nodes to exist here because, while we might | ||
// // have navigated away from the main tree, we still expect the detached | ||
// // tree to exist. | ||
// segmentContainer.parentNode.removeChild(segmentContainer); | ||
// while (segmentContainer.firstChild) { | ||
// placeholderNode.parentNode.insertBefore( | ||
// segmentContainer.firstChild, | ||
// placeholderNode, | ||
// ); | ||
// } | ||
// placeholderNode.parentNode.removeChild(placeholderNode); | ||
// } | ||
|
||
// TODO: Generate this file with a build step. | ||
export default 'function $RS(a,b){a=document.getElementById(a);b=document.getElementById(b);for(a.parentNode.removeChild(a);a.firstChild;)b.parentNode.insertBefore(a.firstChild,b);b.parentNode.removeChild(b)}'; |
Oops, something went wrong.