Files
react/packages/react-server-native-relay/src/ReactFlightNativeRelayClientHostConfig.js
T
Luna Ruan 9f338e5d77 clone json obj in react native flight client host config parser (#20474)
As per Seb's comment in #20465, we need to do the same thing in React Native as we do in Relay.

When `parseModel` suspends because of missing dependencies, it will exit and retry to parse later. However, in the relay implementation, the model is an object that we modify in place when we parse it, so when we we retry, part of the model might be parsed already into React elements, which will error because the parsing code expect a Flight model. This diff clones instead of mutating the original model, which fixes this error.
2020-12-16 11:53:51 -08:00

68 lines
1.7 KiB
JavaScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import type {JSONValue, ResponseBase} from 'react-client/src/ReactFlightClient';
import type JSResourceReference from 'JSResourceReference';
export type ModuleReference<T> = JSResourceReference<T>;
import {
parseModelString,
parseModelTuple,
} from 'react-client/src/ReactFlightClient';
export {
resolveModuleReference,
preloadModule,
requireModule,
} from 'ReactFlightNativeRelayClientIntegration';
export type {ModuleMetaData} from 'ReactFlightNativeRelayClientIntegration';
export type UninitializedModel = JSONValue;
export type Response = ResponseBase;
function parseModelRecursively(response: Response, parentObj, value) {
if (typeof value === 'string') {
return parseModelString(response, parentObj, value);
}
if (typeof value === 'object' && value !== null) {
if (Array.isArray(value)) {
const parsedValue = [];
for (let i = 0; i < value.length; i++) {
(parsedValue: any)[i] = parseModelRecursively(
response,
value,
value[i],
);
}
return parseModelTuple(response, parsedValue);
} else {
const parsedValue = {};
for (const innerKey in value) {
(parsedValue: any)[innerKey] = parseModelRecursively(
response,
value,
value[innerKey],
);
}
return parsedValue;
}
}
return value;
}
const dummy = {};
export function parseModel<T>(response: Response, json: UninitializedModel): T {
return (parseModelRecursively(response, dummy, json): any);
}