UNPKG

prepack

Version:

Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.

189 lines (145 loc) 7.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createMockReactRelay = createMockReactRelay; var _index = require("../../values/index.js"); var _singletons = require("../../singletons.js"); var _utils = require("../prepack/utils.js"); var _index2 = require("../../methods/index.js"); var _invariant = _interopRequireDefault(require("../../invariant.js")); var _utils2 = require("../../react/utils.js"); var _parser = require("@babel/parser"); var _utils3 = require("./utils.js"); var _generator = require("../../utils/generator.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ let reactRelayCode = ` function createReactRelay(React) { function mapObject(obj, func) { var newObj = {}; Object.keys(obj).forEach(function(key) { newObj[key] = func(obj[key]); }); return newObj; } function isReactComponent(component) { return !!( component && typeof component.prototype === 'object' && component.prototype && component.prototype.isReactComponent ); } function getReactComponent(Component) { if (isReactComponent(Component)) { return Component; } else { return null; } } function getComponentName(Component) { let name; const ComponentClass = getReactComponent(Component); if (ComponentClass) { name = ComponentClass.displayName || ComponentClass.name; } else if (typeof Component === 'function') { name = Component.displayName || Component.name || 'StatelessComponent'; } else { name = 'ReactElement'; } return String(name); } function createFragmentContainer(Component, fragmentSpec) { var componentName = getComponentName(Component); var containerName = \`Relay(\${componentName})\`; return function(props, context) { var relay = context.relay; var { createFragmentSpecResolver, getFragment: getFragmentFromTag, } = relay.environment.unstable_internal; var fragments = mapObject(fragmentSpec, getFragmentFromTag); var resolver = createFragmentSpecResolver( relay, containerName, fragments, props, ); var relayProp = { isLoading: resolver.isLoading(), environment: relay.environment, }; var newProps = Object.assign({}, props, resolver.resolve(), { relay: relayProp, }); return React.createElement(Component, newProps); }; } return { createFragmentContainer, }; } `; let reactRelayAst = (0, _parser.parseExpression)(reactRelayCode, { plugins: ["flow"] }); function createReactRelayContainer(realm, reactRelay, containerName, reactRelayFirstRenderValue, relayRequireName) { // we create a ReactRelay container function that returns an abstract object // allowing us to reconstruct this ReactReact.createSomeContainer(...) again // we also pass a reactHint so the reconciler can properly deal with this (0, _utils3.addMockFunctionToObject)(realm, reactRelay, relayRequireName, containerName, (funcValue, args) => { let value = _index.AbstractValue.createTemporalFromBuildFunction(realm, _index.FunctionValue, [reactRelay, new _index.StringValue(realm, containerName), ...args], (0, _generator.createOperationDescriptor)("REACT_RELAY_MOCK_CONTAINER"), { skipInvariant: true, isPure: true }); (0, _invariant.default)(value instanceof _index.AbstractValue); let firstRenderContainerValue = (0, _index2.Get)(realm, reactRelayFirstRenderValue, containerName); let firstRenderValue = realm.intrinsics.undefined; if (firstRenderContainerValue instanceof _index.ECMAScriptSourceFunctionValue) { let firstRenderContainerValueCall = firstRenderContainerValue.$Call; (0, _invariant.default)(firstRenderContainerValueCall !== undefined); firstRenderValue = firstRenderContainerValueCall(realm.intrinsics.undefined, args); (0, _invariant.default)(firstRenderValue instanceof _index.ECMAScriptSourceFunctionValue); } realm.react.abstractHints.set(value, (0, _utils2.createReactHintObject)(reactRelay, containerName, args, firstRenderValue)); return value; }); } function createMockReactRelay(realm, relayRequireName) { let reactRelayFirstRenderFactory = _singletons.Environment.GetValue(realm, realm.$GlobalEnv.evaluate(reactRelayAst, false)); (0, _invariant.default)(reactRelayFirstRenderFactory instanceof _index.ECMAScriptSourceFunctionValue); let factory = reactRelayFirstRenderFactory.$Call; (0, _invariant.default)(factory !== undefined); (0, _invariant.default)(realm.fbLibraries.react instanceof _index.ObjectValue, "mock ReactRelay cannot be required before mock React"); let reactRelayFirstRenderValue = factory(realm.intrinsics.undefined, [realm.fbLibraries.react]); (0, _invariant.default)(reactRelayFirstRenderValue instanceof _index.ObjectValue); // we set refuseSerialization to true so we don't serialize the below properties straight away let reactRelay = new _index.ObjectValue(realm, realm.intrinsics.ObjectPrototype, `require("${relayRequireName}")`, true); // for QueryRenderer, we want to leave the component alone but process it's "render" prop let queryRendererComponent = (0, _utils.createAbstract)(realm, "function", `require("${relayRequireName}").QueryRenderer`); _singletons.Create.CreateDataPropertyOrThrow(realm, reactRelay, "QueryRenderer", queryRendererComponent); let graphql = (0, _utils.createAbstract)(realm, "function", `require("${relayRequireName}").graphql`); _singletons.Create.CreateDataPropertyOrThrow(realm, reactRelay, "graphql", graphql); let reactRelayContainers = ["createFragmentContainer", "createPaginationContainer", "createRefetchContainer"]; for (let reactRelayContainer of reactRelayContainers) { createReactRelayContainer(realm, reactRelay, reactRelayContainer, reactRelayFirstRenderValue, relayRequireName); } let commitLocalUpdate = (0, _utils.createAbstract)(realm, "function", `require("${relayRequireName}").commitLocalUpdate`); _singletons.Create.CreateDataPropertyOrThrow(realm, reactRelay, "commitLocalUpdate", commitLocalUpdate); let commitMutation = (0, _utils.createAbstract)(realm, "function", `require("${relayRequireName}").commitMutation`); _singletons.Create.CreateDataPropertyOrThrow(realm, reactRelay, "commitMutation", commitMutation); let fetchQuery = (0, _utils.createAbstract)(realm, "function", `require("${relayRequireName}").fetchQuery`); _singletons.Create.CreateDataPropertyOrThrow(realm, reactRelay, "fetchQuery", fetchQuery); let requestSubscription = (0, _utils.createAbstract)(realm, "function", `require("${relayRequireName}").requestSubscription`); _singletons.Create.CreateDataPropertyOrThrow(realm, reactRelay, "requestSubscription", requestSubscription); // we set refuseSerialization back to false reactRelay.refuseSerialization = false; reactRelay.makeFinal(); return reactRelay; } //# sourceMappingURL=relay-mocks.js.map