/** * 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. * * @polyfill * @flow * @format */ 'use strict'; /* eslint-disable no-bitwise */ declare var __DEV__: boolean; type DependencyMap = Array<ModuleID>; type Exports = any; type FactoryFn = ( global: Object, require: RequireFn, metroImportDefault: RequireFn, metroImportAll: RequireFn, moduleObject: {exports: {}}, exports: {}, dependencyMap: ?DependencyMap, ) => void; type HotModuleReloadingCallback = () => void; type HotModuleReloadingData = {| acceptCallback: ?HotModuleReloadingCallback, accept: (callback: HotModuleReloadingCallback) => void, disposeCallback: ?HotModuleReloadingCallback, dispose: (callback: HotModuleReloadingCallback) => void, |}; type ModuleID = number; type Module = { id?: ModuleID, exports: Exports, hot?: HotModuleReloadingData, }; type ModuleDefinition = {| dependencyMap: ?DependencyMap, error?: any, factory: FactoryFn, hasError: boolean, hot?: HotModuleReloadingData, importedAll: any, importedDefault: any, isInitialized: boolean, path?: string, publicModule: Module, verboseName?: string, |}; type PatchedModules = {[ModuleID]: boolean}; type RequireFn = (id: ModuleID | VerboseModuleNameForDev) => Exports; type VerboseModuleNameForDev = string; global.__r = metroRequire; global.__d = define; global.__c = clear; global.__registerSegment = registerSegment; var modules = clear(); // Don't use a Symbol here, it would pull in an extra polyfill with all sorts of // additional stuff (e.g. Array.from). const EMPTY = {}; const {hasOwnProperty} = {}; function clear() { modules = (Object.create(null): { [number]: ModuleDefinition, __proto__: null, }); // We return modules here so that we can assign an initial value to modules // when defining it. Otherwise, we would have to do "let modules = null", // which will force us to add "nullthrows" everywhere. return modules; } if (__DEV__) { var verboseNamesToModuleIds: { [key: string]: number, __proto__: null, } = Object.create(null); var initializingModuleIds: Array<number> = []; } function define( factory: FactoryFn, moduleId: number, dependencyMap?: DependencyMap, ) { if (modules[moduleId] != null) { if (__DEV__) { // (We take `inverseDependencies` from `arguments` to avoid an unused // named parameter in `define` in production. const inverseDependencies = arguments[4]; // If the module has already been defined and the define method has been // called with inverseDependencies, we can hot reload it. if (inverseDependencies) { global.__accept(moduleId, factory, dependencyMap, inverseDependencies); } } // prevent repeated calls to `global.nativeRequire` to overwrite modules // that are already loaded return; } modules[moduleId] = { dependencyMap, factory, hasError: false, importedAll: EMPTY, importedDefault: EMPTY, isInitialized: false, publicModule: {exports: {}}, }; if (__DEV__) { // HMR modules[moduleId].hot = createHotReloadingObject(); // DEBUGGABLE MODULES NAMES // we take `verboseName` from `arguments` to avoid an unused named parameter // in `define` in production. const verboseName: string | void = arguments[3]; if (verboseName) { modules[moduleId].verboseName = verboseName; verboseNamesToModuleIds[verboseName] = moduleId; } } } function metroRequire(moduleId: ModuleID | VerboseModuleNameForDev) { if (__DEV__ && typeof moduleId === 'string') { const verboseName = moduleId; moduleId = verboseNamesToModuleIds[verboseName]; if (moduleId == null) { throw new Error(`Unknown named module: "${verboseName}"`); } else { console.warn( `Requiring module "${verboseName}" by name is only supported for ` + 'debugging purposes and will BREAK IN PRODUCTION!', ); } } //$FlowFixMe: at this point we know that moduleId is a number const moduleIdReallyIsNumber: number = moduleId; if (__DEV__) { const initializingIndex = initializingModuleIds.indexOf( moduleIdReallyIsNumber, ); if (initializingIndex !== -1) { const cycle = initializingModuleIds .slice(initializingIndex) .map(id => modules[id].verboseName); // We want to show A -> B -> A: cycle.push(cycle[0]); console.warn( `Require cycle: ${cycle.join(' -> ')}\n\n` + 'Require cycles are allowed, but can result in uninitialized values. ' + 'Consider refactoring to remove the need for a cycle.', ); } } const module = modules[moduleIdReallyIsNumber]; return module && module.isInitialized ? module.publicModule.exports : guardedLoadModule(moduleIdReallyIsNumber, module); } function metroImportDefault(moduleId: ModuleID | VerboseModuleNameForDev) { if (__DEV__ && typeof moduleId === 'string') { const verboseName = moduleId; moduleId = verboseNamesToModuleIds[verboseName]; } //$FlowFixMe: at this point we know that moduleId is a number const moduleIdReallyIsNumber: number = moduleId; if ( modules[moduleIdReallyIsNumber] && modules[moduleIdReallyIsNumber].importedDefault !== EMPTY ) { return modules[moduleIdReallyIsNumber].importedDefault; } const exports = metroRequire(moduleIdReallyIsNumber); const importedDefault = exports && exports.__esModule ? exports.default : exports; return (modules[moduleIdReallyIsNumber].importedDefault = importedDefault); } metroRequire.importDefault = metroImportDefault; function metroImportAll(moduleId) { if (__DEV__ && typeof moduleId === 'string') { const verboseName = moduleId; moduleId = verboseNamesToModuleIds[verboseName]; } //$FlowFixMe: at this point we know that moduleId is a number const moduleIdReallyIsNumber: number = moduleId; if ( modules[moduleIdReallyIsNumber] && modules[moduleIdReallyIsNumber].importedAll !== EMPTY ) { return modules[moduleIdReallyIsNumber].importedAll; } const exports = metroRequire(moduleIdReallyIsNumber); let importedAll; if (exports && exports.__esModule) { importedAll = exports; } else { importedAll = {}; // Refrain from using Object.assign, it has to work in ES3 environments. if (exports) { for (const key in exports) { if (hasOwnProperty.call(exports, key)) { importedAll[key] = exports[key]; } } } importedAll.default = exports; } return (modules[moduleIdReallyIsNumber].importedAll = importedAll); } metroRequire.importAll = metroImportAll; let inGuard = false; function guardedLoadModule(moduleId: ModuleID, module) { if (!inGuard && global.ErrorUtils) { inGuard = true; let returnValue; try { returnValue = loadModuleImplementation(moduleId, module); } catch (e) { global.ErrorUtils.reportFatalError(e); } inGuard = false; return returnValue; } else { return loadModuleImplementation(moduleId, module); } } const ID_MASK_SHIFT = 16; const LOCAL_ID_MASK = ~0 >>> ID_MASK_SHIFT; function unpackModuleId( moduleId: ModuleID, ): {segmentId: number, localId: number} { const segmentId = moduleId >>> ID_MASK_SHIFT; const localId = moduleId & LOCAL_ID_MASK; return {segmentId, localId}; } metroRequire.unpackModuleId = unpackModuleId; function packModuleId(value: {segmentId: number, localId: number}): ModuleID { return (value.segmentId << ID_MASK_SHIFT) + value.localId; } metroRequire.packModuleId = packModuleId; const hooks = []; function registerHook(cb: (number, {}) => void) { const hook = {cb}; hooks.push(hook); return { release: () => { for (let i = 0; i < hooks.length; ++i) { if (hooks[i] === hook) { hooks.splice(i, 1); break; } } }, }; } metroRequire.registerHook = registerHook; const moduleDefinersBySegmentID = []; function registerSegment(segmentID, moduleDefiner) { moduleDefinersBySegmentID[segmentID] = moduleDefiner; } function loadModuleImplementation(moduleId, module) { if (!module && moduleDefinersBySegmentID.length > 0) { const {segmentId, localId} = unpackModuleId(moduleId); const definer = moduleDefinersBySegmentID[segmentId]; if (definer != null) { definer(localId); module = modules[moduleId]; } } const nativeRequire = global.nativeRequire; if (!module && nativeRequire) { const {segmentId, localId} = unpackModuleId(moduleId); nativeRequire(localId, segmentId); module = modules[moduleId]; } if (!module) { throw unknownModuleError(moduleId); } if (module.hasError) { throw moduleThrewError(moduleId, module.error); } // `metroRequire` calls into the require polyfill itself are not analyzed and // replaced so that they use numeric module IDs. // The systrace module will expose itself on the metroRequire function so that // it can be used here. // TODO(davidaurelio) Scan polyfills for dependencies, too (t9759686) if (__DEV__) { var {Systrace} = metroRequire; } // We must optimistically mark module as initialized before running the // factory to keep any require cycles inside the factory from causing an // infinite require loop. module.isInitialized = true; const {factory, dependencyMap} = module; if (__DEV__) { initializingModuleIds.push(moduleId); } try { if (__DEV__) { // $FlowFixMe: we know that __DEV__ is const and `Systrace` exists Systrace.beginEvent('JS_require_' + (module.verboseName || moduleId)); } const moduleObject: Module = module.publicModule; if (__DEV__) { if (module.hot) { moduleObject.hot = module.hot; } } moduleObject.id = moduleId; if (hooks.length > 0) { for (let i = 0; i < hooks.length; ++i) { hooks[i].cb(moduleId, moduleObject); } } // keep args in sync with with defineModuleCode in // metro/src/Resolver/index.js // and metro/src/ModuleGraph/worker.js factory( global, metroRequire, metroImportDefault, metroImportAll, moduleObject, moduleObject.exports, dependencyMap, ); // avoid removing factory in DEV mode as it breaks HMR if (!__DEV__) { // $FlowFixMe: This is only sound because we never access `factory` again module.factory = undefined; module.dependencyMap = undefined; } if (__DEV__) { // $FlowFixMe: we know that __DEV__ is const and `Systrace` exists Systrace.endEvent(); } return moduleObject.exports; } catch (e) { module.hasError = true; module.error = e; module.isInitialized = false; module.publicModule.exports = undefined; throw e; } finally { if (__DEV__) { if (initializingModuleIds.pop() !== moduleId) { throw new Error( 'initializingModuleIds is corrupt; something is terribly wrong', ); } } } } function unknownModuleError(id) { let message = 'Requiring unknown module "' + id + '".'; if (__DEV__) { message += 'If you are sure the module is there, try restarting Metro Bundler. ' + 'You may also want to run `yarn`, or `npm install` (depending on your environment).'; } return Error(message); } function moduleThrewError(id, error: any) { const displayName = (__DEV__ && modules[id] && modules[id].verboseName) || id; return Error( 'Requiring module "' + displayName + '", which threw an exception: ' + error, ); } if (__DEV__) { metroRequire.Systrace = {beginEvent: () => {}, endEvent: () => {}}; metroRequire.getModules = () => { return modules; }; // HOT MODULE RELOADING var createHotReloadingObject = function() { const hot: HotModuleReloadingData = { acceptCallback: null, accept: callback => { hot.acceptCallback = callback; }, disposeCallback: null, dispose: callback => { hot.disposeCallback = callback; }, }; return hot; }; const metroAcceptAll = function( dependentModules, inverseDependencies, patchedModules, ) { if (!dependentModules || dependentModules.length === 0) { return true; } const notAccepted = dependentModules.filter( module => !metroAccept( module, /*factory*/ undefined, /*dependencyMap*/ undefined, inverseDependencies, patchedModules, ), ); const parents = []; for (let i = 0; i < notAccepted.length; i++) { // if the module has no parents then the change cannot be hot loaded if (inverseDependencies[notAccepted[i]].length === 0) { return false; } parents.push.apply(parents, inverseDependencies[notAccepted[i]]); } return parents.length == 0; }; const metroAccept = function( id: ModuleID, factory?: FactoryFn, dependencyMap?: DependencyMap, inverseDependencies: {[key: ModuleID]: Array<ModuleID>}, patchedModules: PatchedModules = {}, ) { if (id in patchedModules) { // Do not patch the same module more that once during an update. return true; } patchedModules[id] = true; const mod = modules[id]; if (!mod && factory) { // New modules are going to be handled by the define() method. return true; } const {hot} = mod; if (!hot) { console.warn( 'Cannot accept module because Hot Module Replacement ' + 'API was not installed.', ); return false; } if (hot.disposeCallback) { try { hot.disposeCallback(); } catch (error) { console.error( `Error while calling dispose handler for module ${id}: `, error, ); } } // replace and initialize factory if (factory) { mod.factory = factory; } if (dependencyMap) { mod.dependencyMap = dependencyMap; } mod.hasError = false; mod.isInitialized = false; metroRequire(id); if (hot.acceptCallback) { try { hot.acceptCallback(); return true; } catch (error) { console.error( `Error while calling accept handler for module ${id}: `, error, ); } } // need to have inverseDependencies to bubble up accept if (!inverseDependencies) { throw new Error('Undefined `inverseDependencies`'); } // accept parent modules recursively up until all siblings are accepted return metroAcceptAll( inverseDependencies[id], inverseDependencies, patchedModules, ); }; global.__accept = metroAccept; }