77 * @flow
88 */
99
10- import type { Source , StringDecoder } from './ReactFlightClientHostConfig' ;
11-
12- import {
13- supportsBinaryStreams ,
14- createStringDecoder ,
15- readPartialStringChunk ,
16- readFinalStringChunk ,
17- } from './ReactFlightClientHostConfig' ;
18-
1910export type ReactModelRoot < T > = { |
2011 model : T ,
2112| } ;
2213
23- type JSONValue =
14+ export type JSONValue =
2415 | number
2516 | null
2617 | boolean
2718 | string
28- | { [ key : string ] : JSONValue , ...} ;
19+ | { [ key : string ] : JSONValue }
20+ | Array < JSONValue > ;
2921
3022const PENDING = 0 ;
3123const RESOLVED = 1 ;
@@ -48,39 +40,23 @@ type ErroredChunk = {|
4840| } ;
4941type Chunk = PendingChunk | ResolvedChunk | ErroredChunk ;
5042
51- type OpaqueResponseWithoutDecoder = {
52- source : Source ,
43+ export type Response = {
5344 partialRow : string ,
5445 modelRoot : ReactModelRoot < any > ,
5546 chunks : Map < number , Chunk> ,
56- fromJSON : ( key : string , value : JSONValue ) => any ,
57- ...
5847} ;
5948
60- type OpaqueResponse = OpaqueResponseWithoutDecoder & {
61- stringDecoder : StringDecoder ,
62- ...
63- } ;
64-
65- export function createResponse ( source : Source ) : OpaqueResponse {
49+ export function createResponse ( ) : Response {
6650 let modelRoot : ReactModelRoot < any > = ( { } : any ) ;
6751 let rootChunk : Chunk = createPendingChunk ( ) ;
6852 definePendingProperty ( modelRoot , 'model' , rootChunk ) ;
6953 let chunks : Map < number , Chunk > = new Map ( ) ;
7054 chunks . set ( 0 , rootChunk ) ;
71-
72- let response : OpaqueResponse = ( ( {
73- source,
55+ let response = {
7456 partialRow : '' ,
7557 modelRoot,
7658 chunks : chunks ,
77- fromJSON : function ( key , value ) {
78- return parseFromJSON ( response , this , key , value ) ;
79- } ,
80- } : OpaqueResponseWithoutDecoder ) : any ) ;
81- if ( supportsBinaryStreams ) {
82- response . stringDecoder = createStringDecoder ( ) ;
83- }
59+ } ;
8460 return response ;
8561}
8662
@@ -138,10 +114,7 @@ function resolveChunk(chunk: Chunk, value: mixed): void {
138114
139115// Report that any missing chunks in the model is now going to throw this
140116// error upon read. Also notify any pending promises.
141- export function reportGlobalError (
142- response : OpaqueResponse ,
143- error : Error ,
144- ) : void {
117+ export function reportGlobalError ( response : Response , error : Error ) : void {
145118 response . chunks . forEach ( chunk => {
146119 // If this chunk was already resolved or errored, it won't
147120 // trigger an error but if it wasn't then we need to
@@ -168,8 +141,8 @@ function definePendingProperty(
168141 } ) ;
169142}
170143
171- function parseFromJSON (
172- response : OpaqueResponse ,
144+ export function parseModelFromJSON (
145+ response : Response ,
173146 targetObj : Object ,
174147 key : string ,
175148 value : JSONValue ,
@@ -195,12 +168,11 @@ function parseFromJSON(
195168 return value ;
196169}
197170
198- function resolveJSONRow (
199- response : OpaqueResponse ,
171+ export function resolveModelChunk < T > (
172+ response : Response ,
200173 id : number ,
201- json : string ,
174+ model : T ,
202175) : void {
203- let model = JSON . parse ( json , response . fromJSON ) ;
204176 let chunks = response . chunks ;
205177 let chunk = chunks . get ( id ) ;
206178 if ( ! chunk ) {
@@ -210,88 +182,31 @@ function resolveJSONRow(
210182 }
211183}
212184
213- function processFullRow ( response : OpaqueResponse , row : string ) : void {
214- if ( row === '' ) {
215- return ;
216- }
217- let tag = row [ 0 ] ;
218- switch ( tag ) {
219- case 'J' : {
220- let colon = row . indexOf ( ':' , 1 ) ;
221- let id = parseInt ( row . substring ( 1 , colon ) , 16 ) ;
222- let json = row . substring ( colon + 1 ) ;
223- resolveJSONRow ( response , id , json ) ;
224- return ;
225- }
226- case 'E' : {
227- let colon = row . indexOf ( ':' , 1 ) ;
228- let id = parseInt ( row . substring ( 1 , colon ) , 16 ) ;
229- let json = row . substring ( colon + 1 ) ;
230- let errorInfo = JSON . parse ( json ) ;
231- let error = new Error ( errorInfo . message ) ;
232- error . stack = errorInfo . stack ;
233- let chunks = response . chunks ;
234- let chunk = chunks . get ( id ) ;
235- if ( ! chunk ) {
236- chunks . set ( id , createErrorChunk ( error ) ) ;
237- } else {
238- triggerErrorOnChunk ( chunk , error ) ;
239- }
240- return ;
241- }
242- default : {
243- // Assume this is the root model.
244- resolveJSONRow ( response , 0 , row ) ;
245- return ;
246- }
247- }
248- }
249-
250- export function processStringChunk (
251- response : OpaqueResponse ,
252- chunk : string ,
253- offset : number ,
254- ) : void {
255- let linebreak = chunk . indexOf ( '\n' , offset ) ;
256- while ( linebreak > - 1 ) {
257- let fullrow = response . partialRow + chunk . substring ( offset , linebreak ) ;
258- processFullRow ( response , fullrow ) ;
259- response . partialRow = '' ;
260- offset = linebreak + 1 ;
261- linebreak = chunk . indexOf ( '\n' , offset ) ;
262- }
263- response . partialRow += chunk . substring ( offset ) ;
264- }
265-
266- export function processBinaryChunk (
267- response : OpaqueResponse ,
268- chunk : Uint8Array ,
185+ export function resolveErrorChunk (
186+ response : Response ,
187+ id : number ,
188+ message : string ,
189+ stack : string ,
269190) : void {
270- if ( ! supportsBinaryStreams ) {
271- throw new Error ( "This environment don't support binary chunks." ) ;
272- }
273- let stringDecoder = response . stringDecoder ;
274- let linebreak = chunk . indexOf ( 10 ) ; // newline
275- while ( linebreak > - 1 ) {
276- let fullrow =
277- response . partialRow +
278- readFinalStringChunk ( stringDecoder , chunk . subarray ( 0 , linebreak ) ) ;
279- processFullRow ( response , fullrow ) ;
280- response . partialRow = '' ;
281- chunk = chunk . subarray ( linebreak + 1 ) ;
282- linebreak = chunk . indexOf ( 10 ) ; // newline
191+ let error = new Error ( message ) ;
192+ error . stack = stack ;
193+ let chunks = response . chunks ;
194+ let chunk = chunks . get ( id ) ;
195+ if ( ! chunk ) {
196+ chunks . set ( id , createErrorChunk ( error ) ) ;
197+ } else {
198+ triggerErrorOnChunk ( chunk , error ) ;
283199 }
284- response . partialRow += readPartialStringChunk ( stringDecoder , chunk ) ;
285200}
286201
287- export function complete ( response : OpaqueResponse ) : void {
202+ export function close ( response : Response ) : void {
288203 // In case there are any remaining unresolved chunks, they won't
289204 // be resolved now. So we need to issue an error to those.
290205 // Ideally we should be able to early bail out if we kept a
291206 // ref count of pending chunks.
292207 reportGlobalError ( response , new Error ( 'Connection closed.' ) ) ;
293208}
294209
295- export function getModelRoot < T > ( response : OpaqueResponse ) : ReactModelRoot < T > {
210+ export function getModelRoot < T > ( response : Response ) : ReactModelRoot < T > {
296211 return response . modelRoot ;
297212}
0 commit comments