1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @flow
    
  8.  */
    
  9. 
    
  10. import type {
    
  11.   ResumableState,
    
  12.   BoundaryResources,
    
  13.   StyleQueue,
    
  14.   Resource,
    
  15. } from './ReactFizzConfigDOM';
    
  16. 
    
  17. import {
    
  18.   createRenderState as createRenderStateImpl,
    
  19.   pushTextInstance as pushTextInstanceImpl,
    
  20.   pushSegmentFinale as pushSegmentFinaleImpl,
    
  21.   writeStartCompletedSuspenseBoundary as writeStartCompletedSuspenseBoundaryImpl,
    
  22.   writeStartClientRenderedSuspenseBoundary as writeStartClientRenderedSuspenseBoundaryImpl,
    
  23.   writeEndCompletedSuspenseBoundary as writeEndCompletedSuspenseBoundaryImpl,
    
  24.   writeEndClientRenderedSuspenseBoundary as writeEndClientRenderedSuspenseBoundaryImpl,
    
  25. } from './ReactFizzConfigDOM';
    
  26. 
    
  27. import type {
    
  28.   Destination,
    
  29.   Chunk,
    
  30.   PrecomputedChunk,
    
  31. } from 'react-server/src/ReactServerStreamConfig';
    
  32. 
    
  33. import type {FormStatus} from '../shared/ReactDOMFormActions';
    
  34. 
    
  35. import {NotPending} from '../shared/ReactDOMFormActions';
    
  36. 
    
  37. export const isPrimaryRenderer = false;
    
  38. 
    
  39. export type RenderState = {
    
  40.   // Keep this in sync with ReactFizzConfigDOM
    
  41.   placeholderPrefix: PrecomputedChunk,
    
  42.   segmentPrefix: PrecomputedChunk,
    
  43.   boundaryPrefix: PrecomputedChunk,
    
  44.   startInlineScript: PrecomputedChunk,
    
  45.   htmlChunks: null | Array<Chunk | PrecomputedChunk>,
    
  46.   headChunks: null | Array<Chunk | PrecomputedChunk>,
    
  47.   externalRuntimeScript: null | any,
    
  48.   bootstrapChunks: Array<Chunk | PrecomputedChunk>,
    
  49.   charsetChunks: Array<Chunk | PrecomputedChunk>,
    
  50.   preconnectChunks: Array<Chunk | PrecomputedChunk>,
    
  51.   importMapChunks: Array<Chunk | PrecomputedChunk>,
    
  52.   preloadChunks: Array<Chunk | PrecomputedChunk>,
    
  53.   hoistableChunks: Array<Chunk | PrecomputedChunk>,
    
  54.   preconnects: Set<Resource>,
    
  55.   fontPreloads: Set<Resource>,
    
  56.   highImagePreloads: Set<Resource>,
    
  57.   // usedImagePreloads: Set<Resource>,
    
  58.   styles: Map<string, StyleQueue>,
    
  59.   bootstrapScripts: Set<Resource>,
    
  60.   scripts: Set<Resource>,
    
  61.   bulkPreloads: Set<Resource>,
    
  62.   preloads: {
    
  63.     images: Map<string, Resource>,
    
  64.     stylesheets: Map<string, Resource>,
    
  65.     scripts: Map<string, Resource>,
    
  66.     moduleScripts: Map<string, Resource>,
    
  67.   },
    
  68.   boundaryResources: ?BoundaryResources,
    
  69.   stylesToHoist: boolean,
    
  70.   // This is an extra field for the legacy renderer
    
  71.   generateStaticMarkup: boolean,
    
  72. };
    
  73. 
    
  74. export function createRenderState(
    
  75.   resumableState: ResumableState,
    
  76.   generateStaticMarkup: boolean,
    
  77. ): RenderState {
    
  78.   const renderState = createRenderStateImpl(
    
  79.     resumableState,
    
  80.     undefined,
    
  81.     undefined,
    
  82.     undefined,
    
  83.     undefined,
    
  84.     undefined,
    
  85.     undefined,
    
  86.   );
    
  87.   return {
    
  88.     // Keep this in sync with ReactFizzConfigDOM
    
  89.     placeholderPrefix: renderState.placeholderPrefix,
    
  90.     segmentPrefix: renderState.segmentPrefix,
    
  91.     boundaryPrefix: renderState.boundaryPrefix,
    
  92.     startInlineScript: renderState.startInlineScript,
    
  93.     htmlChunks: renderState.htmlChunks,
    
  94.     headChunks: renderState.headChunks,
    
  95.     externalRuntimeScript: renderState.externalRuntimeScript,
    
  96.     bootstrapChunks: renderState.bootstrapChunks,
    
  97.     charsetChunks: renderState.charsetChunks,
    
  98.     preconnectChunks: renderState.preconnectChunks,
    
  99.     importMapChunks: renderState.importMapChunks,
    
  100.     preloadChunks: renderState.preloadChunks,
    
  101.     hoistableChunks: renderState.hoistableChunks,
    
  102.     preconnects: renderState.preconnects,
    
  103.     fontPreloads: renderState.fontPreloads,
    
  104.     highImagePreloads: renderState.highImagePreloads,
    
  105.     // usedImagePreloads: renderState.usedImagePreloads,
    
  106.     styles: renderState.styles,
    
  107.     bootstrapScripts: renderState.bootstrapScripts,
    
  108.     scripts: renderState.scripts,
    
  109.     bulkPreloads: renderState.bulkPreloads,
    
  110.     preloads: renderState.preloads,
    
  111.     boundaryResources: renderState.boundaryResources,
    
  112.     stylesToHoist: renderState.stylesToHoist,
    
  113. 
    
  114.     // This is an extra field for the legacy renderer
    
  115.     generateStaticMarkup,
    
  116.   };
    
  117. }
    
  118. 
    
  119. import {
    
  120.   stringToChunk,
    
  121.   stringToPrecomputedChunk,
    
  122. } from 'react-server/src/ReactServerStreamConfig';
    
  123. 
    
  124. // this chunk is empty on purpose because we do not want to emit the DOCTYPE in legacy mode
    
  125. export const doctypeChunk: PrecomputedChunk = stringToPrecomputedChunk('');
    
  126. 
    
  127. export type {
    
  128.   ResumableState,
    
  129.   BoundaryResources,
    
  130.   FormatContext,
    
  131. } from './ReactFizzConfigDOM';
    
  132. 
    
  133. export {
    
  134.   getChildFormatContext,
    
  135.   makeId,
    
  136.   pushStartInstance,
    
  137.   pushEndInstance,
    
  138.   pushStartCompletedSuspenseBoundary,
    
  139.   pushEndCompletedSuspenseBoundary,
    
  140.   pushFormStateMarkerIsMatching,
    
  141.   pushFormStateMarkerIsNotMatching,
    
  142.   writeStartSegment,
    
  143.   writeEndSegment,
    
  144.   writeCompletedSegmentInstruction,
    
  145.   writeCompletedBoundaryInstruction,
    
  146.   writeClientRenderBoundaryInstruction,
    
  147.   writeStartPendingSuspenseBoundary,
    
  148.   writeEndPendingSuspenseBoundary,
    
  149.   writeResourcesForBoundary,
    
  150.   writePlaceholder,
    
  151.   writeCompletedRoot,
    
  152.   createRootFormatContext,
    
  153.   createResumableState,
    
  154.   createBoundaryResources,
    
  155.   writePreamble,
    
  156.   writeHoistables,
    
  157.   writePostamble,
    
  158.   hoistResources,
    
  159.   setCurrentlyRenderingBoundaryResourcesTarget,
    
  160.   prepareHostDispatcher,
    
  161.   resetResumableState,
    
  162. } from './ReactFizzConfigDOM';
    
  163. 
    
  164. import escapeTextForBrowser from './escapeTextForBrowser';
    
  165. 
    
  166. export function pushTextInstance(
    
  167.   target: Array<Chunk | PrecomputedChunk>,
    
  168.   text: string,
    
  169.   renderState: RenderState,
    
  170.   textEmbedded: boolean,
    
  171. ): boolean {
    
  172.   if (renderState.generateStaticMarkup) {
    
  173.     target.push(stringToChunk(escapeTextForBrowser(text)));
    
  174.     return false;
    
  175.   } else {
    
  176.     return pushTextInstanceImpl(target, text, renderState, textEmbedded);
    
  177.   }
    
  178. }
    
  179. 
    
  180. export function pushSegmentFinale(
    
  181.   target: Array<Chunk | PrecomputedChunk>,
    
  182.   renderState: RenderState,
    
  183.   lastPushedText: boolean,
    
  184.   textEmbedded: boolean,
    
  185. ): void {
    
  186.   if (renderState.generateStaticMarkup) {
    
  187.     return;
    
  188.   } else {
    
  189.     return pushSegmentFinaleImpl(
    
  190.       target,
    
  191.       renderState,
    
  192.       lastPushedText,
    
  193.       textEmbedded,
    
  194.     );
    
  195.   }
    
  196. }
    
  197. 
    
  198. export function writeStartCompletedSuspenseBoundary(
    
  199.   destination: Destination,
    
  200.   renderState: RenderState,
    
  201. ): boolean {
    
  202.   if (renderState.generateStaticMarkup) {
    
  203.     // A completed boundary is done and doesn't need a representation in the HTML
    
  204.     // if we're not going to be hydrating it.
    
  205.     return true;
    
  206.   }
    
  207.   return writeStartCompletedSuspenseBoundaryImpl(destination, renderState);
    
  208. }
    
  209. export function writeStartClientRenderedSuspenseBoundary(
    
  210.   destination: Destination,
    
  211.   renderState: RenderState,
    
  212.   // flushing these error arguments are not currently supported in this legacy streaming format.
    
  213.   errorDigest: ?string,
    
  214.   errorMessage: ?string,
    
  215.   errorComponentStack: ?string,
    
  216. ): boolean {
    
  217.   if (renderState.generateStaticMarkup) {
    
  218.     // A client rendered boundary is done and doesn't need a representation in the HTML
    
  219.     // since we'll never hydrate it. This is arguably an error in static generation.
    
  220.     return true;
    
  221.   }
    
  222.   return writeStartClientRenderedSuspenseBoundaryImpl(
    
  223.     destination,
    
  224.     renderState,
    
  225.     errorDigest,
    
  226.     errorMessage,
    
  227.     errorComponentStack,
    
  228.   );
    
  229. }
    
  230. export function writeEndCompletedSuspenseBoundary(
    
  231.   destination: Destination,
    
  232.   renderState: RenderState,
    
  233. ): boolean {
    
  234.   if (renderState.generateStaticMarkup) {
    
  235.     return true;
    
  236.   }
    
  237.   return writeEndCompletedSuspenseBoundaryImpl(destination, renderState);
    
  238. }
    
  239. export function writeEndClientRenderedSuspenseBoundary(
    
  240.   destination: Destination,
    
  241.   renderState: RenderState,
    
  242. ): boolean {
    
  243.   if (renderState.generateStaticMarkup) {
    
  244.     return true;
    
  245.   }
    
  246.   return writeEndClientRenderedSuspenseBoundaryImpl(destination, renderState);
    
  247. }
    
  248. 
    
  249. export type TransitionStatus = FormStatus;
    
  250. export const NotPendingTransition: TransitionStatus = NotPending;