Repository: facebook/react
File: packages/react-html/src/ReactHTMLServer.js (JavaScript)

Code before:
  | bigint
  | $AsyncIterable<ReactMarkupNodeList, ReactMarkupNodeList, void>
  | $AsyncIterator<ReactMarkupNodeList, ReactMarkupNodeList, void>
  | Iterable<ReactMarkupNodeList>
  | Iterator<ReactMarkupNodeList>
  | Array<ReactMarkupNodeList>
  | Promise<ReactMarkupNodeList>; // Thenable<ReactMarkupNodeList>

type MarkupOptions = {
  identifierPrefix?: string,
  signal?: AbortSignal,
};

function noServerCallOrFormAction() {
  throw new Error(
    'renderToMarkup should not have emitted Server References. This is a bug in React.',
  );
}

export function renderToMarkup(
  children: ReactMarkupNodeList,
  options?: MarkupOptions,
): Promise<string> {
  return new Promise((resolve, reject) => {
    const textEncoder = new TextEncoder();
    const flightDestination = {
      push(chunk: string | null): boolean {
        if (chunk !== null) {
          // TODO: Legacy should not use binary streams.
          processFlightBinaryChunk(flightResponse, textEncoder.encode(chunk));
        } else {
          closeFlight(flightResponse);
        }
        return true;
      },
      destroy(error: mixed): void {
        abortFizz(fizzRequest, error);
        reject(error);
      },
    };
    let buffer = '';
    const fizzDestination = {
      // $FlowFixMe[missing-local-annot]
      push(chunk) {
        if (chunk !== null) {
          buffer += chunk;
        } else {
          // null indicates that we finished
          resolve(buffer);
        }
        return true;

Review comment (suggestion):
We currently only encode strings in these streams because there's no reason to send any binary data to the "client". However, if we enabled Blobs to be used inside e.g. `<img src>` as planned, then there would be reason to do that and we can enable the stream config to allow pushing raw binary chunks and receive them here using processBinaryChunk.

Code after:
  | bigint
  | $AsyncIterable<ReactMarkupNodeList, ReactMarkupNodeList, void>
  | $AsyncIterator<ReactMarkupNodeList, ReactMarkupNodeList, void>
  | Iterable<ReactMarkupNodeList>
  | Iterator<ReactMarkupNodeList>
  | Array<ReactMarkupNodeList>
  | Promise<ReactMarkupNodeList>; // Thenable<ReactMarkupNodeList>

type MarkupOptions = {
  identifierPrefix?: string,
  signal?: AbortSignal,
};

function noServerCallOrFormAction() {
  throw new Error(
    'renderToMarkup should not have emitted Server References. This is a bug in React.',
  );
}

export function renderToMarkup(
  children: ReactMarkupNodeList,
  options?: MarkupOptions,
): Promise<string> {
  return new Promise((resolve, reject) => {
    const flightDestination = {
      push(chunk: string | null): boolean {
        if (chunk !== null) {
          processFlightStringChunk(flightResponse, chunk);
        } else {
          closeFlight(flightResponse);
        }
        return true;
      },
      destroy(error: mixed): void {
        abortFizz(fizzRequest, error);
        reject(error);
      },
    };
    let buffer = '';
    const fizzDestination = {
      // $FlowFixMe[missing-local-annot]
      push(chunk) {
        if (chunk !== null) {
          buffer += chunk;
        } else {
          // null indicates that we finished
          resolve(buffer);
        }
        return true;
      },
      // $FlowFixMe[missing-local-annot]