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. /**
    
  11.  * This is a renderer of React that doesn't have a render target output.
    
  12.  * It is useful to demonstrate the internals of the reconciler in isolation
    
  13.  * and for testing semantics of reconciliation separate from the host
    
  14.  * environment.
    
  15.  */
    
  16. 
    
  17. import type {ReactClientValue} from 'react-server/src/ReactFlightServer';
    
  18. import type {ServerContextJSONValue} from 'shared/ReactTypes';
    
  19. 
    
  20. import {saveModule} from 'react-noop-renderer/flight-modules';
    
  21. 
    
  22. import ReactFlightServer from 'react-server/flight';
    
  23. 
    
  24. type Destination = Array<Uint8Array>;
    
  25. 
    
  26. const textEncoder = new TextEncoder();
    
  27. 
    
  28. const ReactNoopFlightServer = ReactFlightServer({
    
  29.   scheduleWork(callback: () => void) {
    
  30.     callback();
    
  31.   },
    
  32.   beginWriting(destination: Destination): void {},
    
  33.   writeChunk(destination: Destination, chunk: string): void {
    
  34.     destination.push(chunk);
    
  35.   },
    
  36.   writeChunkAndReturn(destination: Destination, chunk: string): boolean {
    
  37.     destination.push(chunk);
    
  38.     return true;
    
  39.   },
    
  40.   completeWriting(destination: Destination): void {},
    
  41.   close(destination: Destination): void {},
    
  42.   closeWithError(destination: Destination, error: mixed): void {},
    
  43.   flushBuffered(destination: Destination): void {},
    
  44.   stringToChunk(content: string): Uint8Array {
    
  45.     return textEncoder.encode(content);
    
  46.   },
    
  47.   stringToPrecomputedChunk(content: string): Uint8Array {
    
  48.     return textEncoder.encode(content);
    
  49.   },
    
  50.   clonePrecomputedChunk(chunk: Uint8Array): Uint8Array {
    
  51.     return chunk;
    
  52.   },
    
  53.   isClientReference(reference: Object): boolean {
    
  54.     return reference.$$typeof === Symbol.for('react.client.reference');
    
  55.   },
    
  56.   isServerReference(reference: Object): boolean {
    
  57.     return reference.$$typeof === Symbol.for('react.server.reference');
    
  58.   },
    
  59.   getClientReferenceKey(reference: Object): Object {
    
  60.     return reference;
    
  61.   },
    
  62.   resolveClientReferenceMetadata(
    
  63.     config: void,
    
  64.     reference: {$$typeof: symbol, value: any},
    
  65.   ) {
    
  66.     return saveModule(reference.value);
    
  67.   },
    
  68.   prepareHostDispatcher() {},
    
  69. });
    
  70. 
    
  71. type Options = {
    
  72.   onError?: (error: mixed) => void,
    
  73.   context?: Array<[string, ServerContextJSONValue]>,
    
  74.   identifierPrefix?: string,
    
  75. };
    
  76. 
    
  77. function render(model: ReactClientValue, options?: Options): Destination {
    
  78.   const destination: Destination = [];
    
  79.   const bundlerConfig = undefined;
    
  80.   const request = ReactNoopFlightServer.createRequest(
    
  81.     model,
    
  82.     bundlerConfig,
    
  83.     options ? options.onError : undefined,
    
  84.     options ? options.context : undefined,
    
  85.     options ? options.identifierPrefix : undefined,
    
  86.   );
    
  87.   ReactNoopFlightServer.startWork(request);
    
  88.   ReactNoopFlightServer.startFlowing(request, destination);
    
  89.   return destination;
    
  90. }
    
  91. 
    
  92. export {render};