@react-native-harness/runtime 1.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc.js +23 -0
- package/LICENSE +20 -0
- package/README.md +7 -0
- package/assets/logo.png +0 -0
- package/assets/moduleSystem.flow.js +1062 -0
- package/dist/bundler/bundle.d.ts +2 -0
- package/dist/bundler/bundle.d.ts.map +1 -0
- package/dist/bundler/bundle.js +16 -0
- package/dist/bundler/dev-server.d.ts +2 -0
- package/dist/bundler/dev-server.d.ts.map +1 -0
- package/dist/bundler/dev-server.js +5 -0
- package/dist/bundler/errors.d.ts +10 -0
- package/dist/bundler/errors.d.ts.map +1 -0
- package/dist/bundler/errors.js +18 -0
- package/dist/bundler/evaluate.d.ts +2 -0
- package/dist/bundler/evaluate.d.ts.map +1 -0
- package/dist/bundler/evaluate.js +18 -0
- package/dist/bundler/index.d.ts +3 -0
- package/dist/bundler/index.d.ts.map +1 -0
- package/dist/bundler/index.js +2 -0
- package/dist/client/factory.d.ts +2 -0
- package/dist/client/factory.d.ts.map +1 -0
- package/dist/client/factory.js +41 -0
- package/dist/client/getDeviceDescriptor.d.ts +8 -0
- package/dist/client/getDeviceDescriptor.d.ts.map +1 -0
- package/dist/client/getDeviceDescriptor.js +20 -0
- package/dist/client/getWSServer.d.ts +2 -0
- package/dist/client/getWSServer.d.ts.map +1 -0
- package/dist/client/getWSServer.js +7 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +1 -0
- package/dist/collector/errors.d.ts +8 -0
- package/dist/collector/errors.d.ts.map +1 -0
- package/dist/collector/errors.js +20 -0
- package/dist/collector/factory.d.ts +3 -0
- package/dist/collector/factory.d.ts.map +1 -0
- package/dist/collector/factory.js +25 -0
- package/dist/collector/functions.d.ts +22 -0
- package/dist/collector/functions.d.ts.map +1 -0
- package/dist/collector/functions.js +271 -0
- package/dist/collector/index.d.ts +5 -0
- package/dist/collector/index.d.ts.map +1 -0
- package/dist/collector/index.js +3 -0
- package/dist/collector/types.d.ts +10 -0
- package/dist/collector/types.d.ts.map +1 -0
- package/dist/collector/types.js +1 -0
- package/dist/collector/validation.d.ts +4 -0
- package/dist/collector/validation.d.ts.map +1 -0
- package/dist/collector/validation.js +15 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +2 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +13 -0
- package/dist/expect/index.d.ts +9 -0
- package/dist/expect/index.d.ts.map +1 -0
- package/dist/expect/index.js +71 -0
- package/dist/expect/setup.d.ts +2 -0
- package/dist/expect/setup.d.ts.map +1 -0
- package/dist/expect/setup.js +5 -0
- package/dist/exports.d.ts +7 -0
- package/dist/exports.d.ts.map +1 -0
- package/dist/exports.js +6 -0
- package/dist/getEntryComponent.d.ts +6 -0
- package/dist/getEntryComponent.d.ts.map +1 -0
- package/dist/getEntryComponent.js +6 -0
- package/dist/globals.d.ts +5 -0
- package/dist/globals.d.ts.map +1 -0
- package/dist/globals.js +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/initialize.d.ts +2 -0
- package/dist/initialize.d.ts.map +1 -0
- package/dist/initialize.js +16 -0
- package/dist/logger.d.ts +6 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +14 -0
- package/dist/mock.d.ts +15 -0
- package/dist/mock.d.ts.map +1 -0
- package/dist/mock.js +37 -0
- package/dist/mocker/index.d.ts +2 -0
- package/dist/mocker/index.d.ts.map +1 -0
- package/dist/mocker/index.js +1 -0
- package/dist/mocker/registry.d.ts +7 -0
- package/dist/mocker/registry.d.ts.map +1 -0
- package/dist/mocker/registry.js +41 -0
- package/dist/mocker/types.d.ts +6 -0
- package/dist/mocker/types.d.ts.map +1 -0
- package/dist/mocker/types.js +1 -0
- package/dist/module.d.ts +3 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +19 -0
- package/dist/module.web.d.ts +2 -0
- package/dist/module.web.d.ts.map +1 -0
- package/dist/module.web.js +12 -0
- package/dist/rntl/client.d.ts +3 -0
- package/dist/rntl/client.d.ts.map +1 -0
- package/dist/rntl/client.js +8 -0
- package/dist/rntl/describe.d.ts +2 -0
- package/dist/rntl/describe.d.ts.map +1 -0
- package/dist/rntl/describe.js +1 -0
- package/dist/rntl/expect.d.ts +128 -0
- package/dist/rntl/expect.d.ts.map +1 -0
- package/dist/rntl/expect.js +670 -0
- package/dist/rntl/fn.d.ts +2 -0
- package/dist/rntl/fn.d.ts.map +1 -0
- package/dist/rntl/fn.js +1 -0
- package/dist/rntl/mock.d.ts +2 -0
- package/dist/rntl/mock.d.ts.map +1 -0
- package/dist/rntl/mock.js +1 -0
- package/dist/rntl/render.d.ts +4 -0
- package/dist/rntl/render.d.ts.map +1 -0
- package/dist/rntl/render.js +11 -0
- package/dist/rntl/screen.d.ts +45 -0
- package/dist/rntl/screen.d.ts.map +1 -0
- package/dist/rntl/screen.js +31 -0
- package/dist/rntl/spies.d.ts +45 -0
- package/dist/rntl/spies.d.ts.map +1 -0
- package/dist/rntl/spies.js +553 -0
- package/dist/rntl/userEvent.d.ts +22 -0
- package/dist/rntl/userEvent.d.ts.map +1 -0
- package/dist/rntl/userEvent.js +19 -0
- package/dist/runner/errors.d.ts +9 -0
- package/dist/runner/errors.d.ts.map +1 -0
- package/dist/runner/errors.js +23 -0
- package/dist/runner/factory.d.ts +3 -0
- package/dist/runner/factory.d.ts.map +1 -0
- package/dist/runner/factory.js +17 -0
- package/dist/runner/hooks.d.ts +4 -0
- package/dist/runner/hooks.d.ts.map +1 -0
- package/dist/runner/hooks.js +39 -0
- package/dist/runner/index.d.ts +4 -0
- package/dist/runner/index.d.ts.map +1 -0
- package/dist/runner/index.js +2 -0
- package/dist/runner/runSuite.d.ts +4 -0
- package/dist/runner/runSuite.d.ts.map +1 -0
- package/dist/runner/runSuite.js +147 -0
- package/dist/runner/types.d.ts +13 -0
- package/dist/runner/types.d.ts.map +1 -0
- package/dist/runner/types.js +1 -0
- package/dist/runner.d.ts +7 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +201 -0
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +44 -0
- package/dist/spy/index.d.ts +2 -0
- package/dist/spy/index.d.ts.map +1 -0
- package/dist/spy/index.js +2 -0
- package/dist/state.d.ts +25 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +37 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/dist/ui/ReadyScreen.d.ts +2 -0
- package/dist/ui/ReadyScreen.d.ts.map +1 -0
- package/dist/ui/ReadyScreen.js +110 -0
- package/dist/ui/UI.d.ts +13 -0
- package/dist/ui/UI.d.ts.map +1 -0
- package/dist/ui/UI.js +121 -0
- package/dist/ui/WrongEnvironmentScreen.d.ts +2 -0
- package/dist/ui/WrongEnvironmentScreen.d.ts.map +1 -0
- package/dist/ui/WrongEnvironmentScreen.js +87 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +3 -0
- package/dist/ui/state.d.ts +7 -0
- package/dist/ui/state.d.ts.map +1 -0
- package/dist/ui/state.js +6 -0
- package/dist/utils/dev-server.d.ts +2 -0
- package/dist/utils/dev-server.d.ts.map +1 -0
- package/dist/utils/dev-server.js +5 -0
- package/dist/utils/emitter.d.ts +16 -0
- package/dist/utils/emitter.d.ts.map +1 -0
- package/dist/utils/emitter.js +39 -0
- package/eslint.config.mjs +16 -0
- package/package.json +38 -0
- package/src/__tests__/collector.test.ts +553 -0
- package/src/__tests__/error-handling.test.ts +132 -0
- package/src/__tests__/expect.test.ts +619 -0
- package/src/__tests__/spy.test.ts +538 -0
- package/src/bundler/bundle.ts +19 -0
- package/src/bundler/errors.ts +16 -0
- package/src/bundler/evaluate.ts +25 -0
- package/src/bundler/index.ts +2 -0
- package/src/client/factory.ts +56 -0
- package/src/client/getDeviceDescriptor.ts +30 -0
- package/src/client/getWSServer.ts +9 -0
- package/src/client/index.ts +1 -0
- package/src/collector/errors.ts +27 -0
- package/src/collector/factory.ts +32 -0
- package/src/collector/functions.ts +376 -0
- package/src/collector/index.ts +12 -0
- package/src/collector/types.ts +15 -0
- package/src/collector/validation.ts +21 -0
- package/src/constants.ts +2 -0
- package/src/errors.ts +12 -0
- package/src/expect/index.ts +117 -0
- package/src/expect/setup.ts +10 -0
- package/src/globals.ts +5 -0
- package/src/index.ts +7 -0
- package/src/initialize.ts +22 -0
- package/src/mocker/index.ts +1 -0
- package/src/mocker/metro-require.d.ts +5 -0
- package/src/mocker/registry.ts +58 -0
- package/src/mocker/types.ts +6 -0
- package/src/react-native.d.ts +16 -0
- package/src/runner/errors.ts +31 -0
- package/src/runner/factory.ts +21 -0
- package/src/runner/hooks.ts +51 -0
- package/src/runner/index.ts +7 -0
- package/src/runner/runSuite.ts +201 -0
- package/src/runner/types.ts +19 -0
- package/src/spy/index.ts +2 -0
- package/src/ui/ReadyScreen.tsx +151 -0
- package/src/ui/WrongEnvironmentScreen.tsx +113 -0
- package/src/ui/index.ts +3 -0
- package/src/ui/state.ts +13 -0
- package/src/utils/dev-server.ts +6 -0
- package/src/utils/emitter.ts +64 -0
- package/tsconfig.json +16 -0
- package/tsconfig.lib.json +33 -0
- package/tsconfig.spec.json +30 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/types/global.d.ts +2 -0
- package/types/index.d.ts +1 -0
- package/vite.config.ts +27 -0
|
@@ -0,0 +1,1062 @@
|
|
|
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
|
+
* @format
|
|
9
|
+
* @oncall react_native
|
|
10
|
+
* @polyfill
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
/* eslint-disable no-bitwise */
|
|
16
|
+
|
|
17
|
+
declare var __DEV__: boolean;
|
|
18
|
+
declare var __METRO_GLOBAL_PREFIX__: string;
|
|
19
|
+
|
|
20
|
+
// A simpler $ArrayLike<T>. Not iterable and doesn't have a `length`.
|
|
21
|
+
// This is compatible with actual arrays as well as with objects that look like
|
|
22
|
+
// {0: 'value', 1: '...'}
|
|
23
|
+
type ArrayIndexable<T> = interface {
|
|
24
|
+
+[indexer: number]: T,
|
|
25
|
+
};
|
|
26
|
+
type DependencyMap = $ReadOnly<
|
|
27
|
+
ArrayIndexable<ModuleID> & {
|
|
28
|
+
paths?: { [id: ModuleID]: string },
|
|
29
|
+
}
|
|
30
|
+
>;
|
|
31
|
+
type InverseDependencyMap = { [key: ModuleID]: Array<ModuleID>, ... };
|
|
32
|
+
type Exports = any;
|
|
33
|
+
type FactoryFn = (
|
|
34
|
+
global: Object,
|
|
35
|
+
require: RequireFn,
|
|
36
|
+
metroImportDefault: RequireFn,
|
|
37
|
+
metroImportAll: RequireFn,
|
|
38
|
+
moduleObject: { exports: { ... }, ... },
|
|
39
|
+
exports: { ... },
|
|
40
|
+
dependencyMap: ?DependencyMap
|
|
41
|
+
) => void;
|
|
42
|
+
type HotModuleReloadingCallback = () => void;
|
|
43
|
+
type HotModuleReloadingData = {
|
|
44
|
+
_acceptCallback: ?HotModuleReloadingCallback,
|
|
45
|
+
_disposeCallback: ?HotModuleReloadingCallback,
|
|
46
|
+
_didAccept: boolean,
|
|
47
|
+
accept: (callback?: HotModuleReloadingCallback) => void,
|
|
48
|
+
dispose: (callback?: HotModuleReloadingCallback) => void,
|
|
49
|
+
};
|
|
50
|
+
type ModuleID = number;
|
|
51
|
+
type Module = {
|
|
52
|
+
id?: ModuleID,
|
|
53
|
+
exports: Exports,
|
|
54
|
+
hot?: HotModuleReloadingData,
|
|
55
|
+
...
|
|
56
|
+
};
|
|
57
|
+
type ModuleDefinition = {
|
|
58
|
+
dependencyMap: ?DependencyMap,
|
|
59
|
+
error?: any,
|
|
60
|
+
factory: FactoryFn,
|
|
61
|
+
hasError: boolean,
|
|
62
|
+
hot?: HotModuleReloadingData,
|
|
63
|
+
importedAll: any,
|
|
64
|
+
importedDefault: any,
|
|
65
|
+
isInitialized: boolean,
|
|
66
|
+
path?: string,
|
|
67
|
+
publicModule: Module,
|
|
68
|
+
verboseName?: string,
|
|
69
|
+
};
|
|
70
|
+
type ModuleList = Map<number, ModuleDefinition>;
|
|
71
|
+
export type RequireFn = (id: ModuleID | VerboseModuleNameForDev) => Exports;
|
|
72
|
+
export type DefineFn = (
|
|
73
|
+
factory: FactoryFn,
|
|
74
|
+
moduleId: number,
|
|
75
|
+
dependencyMap?: DependencyMap,
|
|
76
|
+
verboseName?: string,
|
|
77
|
+
inverseDependencies?: InverseDependencyMap
|
|
78
|
+
) => void;
|
|
79
|
+
|
|
80
|
+
type VerboseModuleNameForDev = string;
|
|
81
|
+
type ModuleDefiner = (moduleId: ModuleID) => void;
|
|
82
|
+
|
|
83
|
+
global.__r = (metroRequire: RequireFn);
|
|
84
|
+
global[`${__METRO_GLOBAL_PREFIX__}__d`] = (define: DefineFn);
|
|
85
|
+
global.__c = clear;
|
|
86
|
+
global.__registerSegment = registerSegment;
|
|
87
|
+
|
|
88
|
+
var modules = clear();
|
|
89
|
+
|
|
90
|
+
// Don't use a Symbol here, it would pull in an extra polyfill with all sorts of
|
|
91
|
+
// additional stuff (e.g. Array.from).
|
|
92
|
+
const EMPTY = {};
|
|
93
|
+
const CYCLE_DETECTED = {};
|
|
94
|
+
const { hasOwnProperty } = {};
|
|
95
|
+
|
|
96
|
+
if (__DEV__) {
|
|
97
|
+
global.$RefreshReg$ = global.$RefreshReg$ ?? (() => {});
|
|
98
|
+
global.$RefreshSig$ = global.$RefreshSig$ ?? (() => (type) => type);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function clear(): ModuleList {
|
|
102
|
+
modules = new Map();
|
|
103
|
+
|
|
104
|
+
// We return modules here so that we can assign an initial value to modules
|
|
105
|
+
// when defining it. Otherwise, we would have to do "let modules = null",
|
|
106
|
+
// which will force us to add "nullthrows" everywhere.
|
|
107
|
+
return modules;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (__DEV__) {
|
|
111
|
+
var verboseNamesToModuleIds: Map<string, number> = new Map();
|
|
112
|
+
var getModuleIdForVerboseName = (verboseName: string): number => {
|
|
113
|
+
const moduleId = verboseNamesToModuleIds.get(verboseName);
|
|
114
|
+
if (moduleId == null) {
|
|
115
|
+
throw new Error(`Unknown named module: "${verboseName}"`);
|
|
116
|
+
}
|
|
117
|
+
return moduleId;
|
|
118
|
+
};
|
|
119
|
+
var initializingModuleIds: Array<number> = [];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function define(
|
|
123
|
+
factory: FactoryFn,
|
|
124
|
+
moduleId: number,
|
|
125
|
+
dependencyMap?: DependencyMap
|
|
126
|
+
): void {
|
|
127
|
+
if (modules.has(moduleId)) {
|
|
128
|
+
if (__DEV__) {
|
|
129
|
+
// (We take `inverseDependencies` from `arguments` to avoid an unused
|
|
130
|
+
// named parameter in `define` in production.
|
|
131
|
+
const inverseDependencies = arguments[4];
|
|
132
|
+
|
|
133
|
+
// If the module has already been defined and the define method has been
|
|
134
|
+
// called with inverseDependencies, we can hot reload it.
|
|
135
|
+
if (inverseDependencies) {
|
|
136
|
+
global.__accept(moduleId, factory, dependencyMap, inverseDependencies);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// prevent repeated calls to `global.nativeRequire` to overwrite modules
|
|
141
|
+
// that are already loaded
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const mod: ModuleDefinition = {
|
|
146
|
+
dependencyMap,
|
|
147
|
+
factory,
|
|
148
|
+
hasError: false,
|
|
149
|
+
importedAll: EMPTY,
|
|
150
|
+
importedDefault: EMPTY,
|
|
151
|
+
isInitialized: false,
|
|
152
|
+
publicModule: { exports: {} },
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
modules.set(moduleId, mod);
|
|
156
|
+
|
|
157
|
+
if (__DEV__) {
|
|
158
|
+
// HMR
|
|
159
|
+
mod.hot = createHotReloadingObject();
|
|
160
|
+
|
|
161
|
+
// DEBUGGABLE MODULES NAMES
|
|
162
|
+
// we take `verboseName` from `arguments` to avoid an unused named parameter
|
|
163
|
+
// in `define` in production.
|
|
164
|
+
const verboseName: string | void = arguments[3];
|
|
165
|
+
if (verboseName) {
|
|
166
|
+
mod.verboseName = verboseName;
|
|
167
|
+
verboseNamesToModuleIds.set(verboseName, moduleId);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function metroRequire(
|
|
173
|
+
moduleId: ModuleID | VerboseModuleNameForDev | null,
|
|
174
|
+
maybeNameForDev?: string
|
|
175
|
+
): Exports {
|
|
176
|
+
// Unresolved optional dependencies are nulls in dependency maps
|
|
177
|
+
// eslint-disable-next-line lint/strictly-null
|
|
178
|
+
if (moduleId === null) {
|
|
179
|
+
if (__DEV__ && typeof maybeNameForDev === 'string') {
|
|
180
|
+
throw new Error("Cannot find module '" + maybeNameForDev + "'");
|
|
181
|
+
}
|
|
182
|
+
throw new Error('Cannot find module');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (__DEV__ && typeof moduleId === 'string') {
|
|
186
|
+
const verboseName = moduleId;
|
|
187
|
+
moduleId = getModuleIdForVerboseName(verboseName);
|
|
188
|
+
console.warn(
|
|
189
|
+
`Requiring module "${verboseName}" by name is only supported for ` +
|
|
190
|
+
'debugging purposes and will BREAK IN PRODUCTION!'
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
//$FlowFixMe: at this point we know that moduleId is a number
|
|
195
|
+
const moduleIdReallyIsNumber: number = moduleId;
|
|
196
|
+
|
|
197
|
+
if (__DEV__) {
|
|
198
|
+
const initializingIndex = initializingModuleIds.indexOf(
|
|
199
|
+
moduleIdReallyIsNumber
|
|
200
|
+
);
|
|
201
|
+
if (initializingIndex !== -1) {
|
|
202
|
+
const cycle = initializingModuleIds
|
|
203
|
+
.slice(initializingIndex)
|
|
204
|
+
.map((id: number) => modules.get(id)?.verboseName ?? '[unknown]');
|
|
205
|
+
if (shouldPrintRequireCycle(cycle)) {
|
|
206
|
+
cycle.push(cycle[0]); // We want to print A -> B -> A:
|
|
207
|
+
console.warn(
|
|
208
|
+
`Require cycle: ${cycle.join(' -> ')}\n\n` +
|
|
209
|
+
'Require cycles are allowed, but can result in uninitialized values. ' +
|
|
210
|
+
'Consider refactoring to remove the need for a cycle.'
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const module = modules.get(moduleIdReallyIsNumber);
|
|
217
|
+
|
|
218
|
+
return module && module.isInitialized
|
|
219
|
+
? module.publicModule.exports
|
|
220
|
+
: guardedLoadModule(moduleIdReallyIsNumber, module);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// We print require cycles unless they match a pattern in the
|
|
224
|
+
// `requireCycleIgnorePatterns` configuration.
|
|
225
|
+
function shouldPrintRequireCycle(modules: $ReadOnlyArray<?string>): boolean {
|
|
226
|
+
const regExps =
|
|
227
|
+
global[__METRO_GLOBAL_PREFIX__ + '__requireCycleIgnorePatterns'];
|
|
228
|
+
if (!Array.isArray(regExps)) {
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const isIgnored = (module: ?string) =>
|
|
233
|
+
module != null && regExps.some((regExp) => regExp.test(module));
|
|
234
|
+
|
|
235
|
+
// Print the cycle unless any part of it is ignored
|
|
236
|
+
return modules.every((module) => !isIgnored(module));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function metroImportDefault(
|
|
240
|
+
moduleId: ModuleID | VerboseModuleNameForDev
|
|
241
|
+
): any | Exports {
|
|
242
|
+
if (__DEV__ && typeof moduleId === 'string') {
|
|
243
|
+
const verboseName = moduleId;
|
|
244
|
+
moduleId = getModuleIdForVerboseName(verboseName);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
//$FlowFixMe: at this point we know that moduleId is a number
|
|
248
|
+
const moduleIdReallyIsNumber: number = moduleId;
|
|
249
|
+
|
|
250
|
+
const maybeInitializedModule = modules.get(moduleIdReallyIsNumber);
|
|
251
|
+
|
|
252
|
+
if (
|
|
253
|
+
maybeInitializedModule &&
|
|
254
|
+
maybeInitializedModule.importedDefault !== EMPTY
|
|
255
|
+
) {
|
|
256
|
+
return maybeInitializedModule.importedDefault;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const exports: Exports = global.__r(moduleIdReallyIsNumber);
|
|
260
|
+
const importedDefault: any | Exports =
|
|
261
|
+
exports && exports.__esModule ? exports.default : exports;
|
|
262
|
+
|
|
263
|
+
// $FlowFixMe[incompatible-type] The `metroRequire` call above would have thrown if modules[id] was null
|
|
264
|
+
const initializedModule: ModuleDefinition = modules.get(
|
|
265
|
+
moduleIdReallyIsNumber
|
|
266
|
+
);
|
|
267
|
+
return (initializedModule.importedDefault = importedDefault);
|
|
268
|
+
}
|
|
269
|
+
metroRequire.importDefault = metroImportDefault;
|
|
270
|
+
|
|
271
|
+
function metroImportAll(
|
|
272
|
+
moduleId: ModuleID | VerboseModuleNameForDev | number
|
|
273
|
+
): any | Exports | { [string]: any } {
|
|
274
|
+
if (__DEV__ && typeof moduleId === 'string') {
|
|
275
|
+
const verboseName = moduleId;
|
|
276
|
+
moduleId = getModuleIdForVerboseName(verboseName);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
//$FlowFixMe: at this point we know that moduleId is a number
|
|
280
|
+
const moduleIdReallyIsNumber: number = moduleId;
|
|
281
|
+
|
|
282
|
+
const maybeInitializedModule = modules.get(moduleIdReallyIsNumber);
|
|
283
|
+
|
|
284
|
+
if (maybeInitializedModule && maybeInitializedModule.importedAll !== EMPTY) {
|
|
285
|
+
return maybeInitializedModule.importedAll;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const exports: Exports = global.__r(moduleIdReallyIsNumber);
|
|
289
|
+
let importedAll: Exports | { [string]: any };
|
|
290
|
+
|
|
291
|
+
if (exports && exports.__esModule) {
|
|
292
|
+
importedAll = exports;
|
|
293
|
+
} else {
|
|
294
|
+
importedAll = ({}: { [string]: any });
|
|
295
|
+
|
|
296
|
+
// Refrain from using Object.assign, it has to work in ES3 environments.
|
|
297
|
+
if (exports) {
|
|
298
|
+
for (const key: string in exports) {
|
|
299
|
+
if (hasOwnProperty.call(exports, key)) {
|
|
300
|
+
importedAll[key] = exports[key];
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
importedAll.default = exports;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// $FlowFixMe[incompatible-type] The `metroRequire` call above would have thrown if modules[id] was null
|
|
309
|
+
const initializedModule: ModuleDefinition = modules.get(
|
|
310
|
+
moduleIdReallyIsNumber
|
|
311
|
+
);
|
|
312
|
+
return (initializedModule.importedAll = importedAll);
|
|
313
|
+
}
|
|
314
|
+
metroRequire.importAll = metroImportAll;
|
|
315
|
+
|
|
316
|
+
// The `require.context()` syntax is never executed in the runtime because it is converted
|
|
317
|
+
// to `require()` in `metro/src/ModuleGraph/worker/collectDependencies.js` after collecting
|
|
318
|
+
// dependencies. If the feature flag is not enabled then the conversion never takes place and this error is thrown (development only).
|
|
319
|
+
metroRequire.context = function fallbackRequireContext() {
|
|
320
|
+
if (__DEV__) {
|
|
321
|
+
throw new Error(
|
|
322
|
+
'The experimental Metro feature `require.context` is not enabled in your project.\nThis can be enabled by setting the `transformer.unstable_allowRequireContext` property to `true` in your Metro configuration.'
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
throw new Error(
|
|
326
|
+
'The experimental Metro feature `require.context` is not enabled in your project.'
|
|
327
|
+
);
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
// `require.resolveWeak()` is a compile-time primitive (see collectDependencies.js)
|
|
331
|
+
metroRequire.resolveWeak = function fallbackRequireResolveWeak() {
|
|
332
|
+
if (__DEV__) {
|
|
333
|
+
throw new Error(
|
|
334
|
+
'require.resolveWeak cannot be called dynamically. Ensure you are using the same version of `metro` and `metro-runtime`.'
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
throw new Error('require.resolveWeak cannot be called dynamically.');
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
let inGuard = false;
|
|
341
|
+
function guardedLoadModule(
|
|
342
|
+
moduleId: ModuleID,
|
|
343
|
+
module: ?ModuleDefinition
|
|
344
|
+
): Exports {
|
|
345
|
+
if (!inGuard && global.ErrorUtils) {
|
|
346
|
+
inGuard = true;
|
|
347
|
+
let returnValue;
|
|
348
|
+
try {
|
|
349
|
+
returnValue = loadModuleImplementation(moduleId, module);
|
|
350
|
+
} catch (e) {
|
|
351
|
+
// TODO: (moti) T48204692 Type this use of ErrorUtils.
|
|
352
|
+
global.ErrorUtils.reportFatalError(e);
|
|
353
|
+
}
|
|
354
|
+
inGuard = false;
|
|
355
|
+
return returnValue;
|
|
356
|
+
} else {
|
|
357
|
+
return loadModuleImplementation(moduleId, module);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const ID_MASK_SHIFT = 16;
|
|
362
|
+
const LOCAL_ID_MASK = ~0 >>> ID_MASK_SHIFT;
|
|
363
|
+
|
|
364
|
+
function unpackModuleId(moduleId: ModuleID): {
|
|
365
|
+
localId: number,
|
|
366
|
+
segmentId: number,
|
|
367
|
+
...
|
|
368
|
+
} {
|
|
369
|
+
const segmentId = moduleId >>> ID_MASK_SHIFT;
|
|
370
|
+
const localId = moduleId & LOCAL_ID_MASK;
|
|
371
|
+
return { segmentId, localId };
|
|
372
|
+
}
|
|
373
|
+
metroRequire.unpackModuleId = unpackModuleId;
|
|
374
|
+
|
|
375
|
+
function packModuleId(value: {
|
|
376
|
+
localId: number,
|
|
377
|
+
segmentId: number,
|
|
378
|
+
...
|
|
379
|
+
}): ModuleID {
|
|
380
|
+
return (value.segmentId << ID_MASK_SHIFT) + value.localId;
|
|
381
|
+
}
|
|
382
|
+
metroRequire.packModuleId = packModuleId;
|
|
383
|
+
|
|
384
|
+
const moduleDefinersBySegmentID: Array<?ModuleDefiner> = [];
|
|
385
|
+
const definingSegmentByModuleID: Map<ModuleID, number> = new Map();
|
|
386
|
+
|
|
387
|
+
function registerSegment(
|
|
388
|
+
segmentId: number,
|
|
389
|
+
moduleDefiner: ModuleDefiner,
|
|
390
|
+
moduleIds: ?$ReadOnlyArray<ModuleID>
|
|
391
|
+
): void {
|
|
392
|
+
moduleDefinersBySegmentID[segmentId] = moduleDefiner;
|
|
393
|
+
if (__DEV__) {
|
|
394
|
+
if (segmentId === 0 && moduleIds) {
|
|
395
|
+
throw new Error(
|
|
396
|
+
'registerSegment: Expected moduleIds to be null for main segment'
|
|
397
|
+
);
|
|
398
|
+
}
|
|
399
|
+
if (segmentId !== 0 && !moduleIds) {
|
|
400
|
+
throw new Error(
|
|
401
|
+
'registerSegment: Expected moduleIds to be passed for segment #' +
|
|
402
|
+
segmentId
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (moduleIds) {
|
|
407
|
+
moduleIds.forEach((moduleId) => {
|
|
408
|
+
if (!modules.has(moduleId) && !definingSegmentByModuleID.has(moduleId)) {
|
|
409
|
+
definingSegmentByModuleID.set(moduleId, segmentId);
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function loadModuleImplementation(
|
|
416
|
+
moduleId: ModuleID,
|
|
417
|
+
module: ?ModuleDefinition
|
|
418
|
+
): Exports {
|
|
419
|
+
if (!module && moduleDefinersBySegmentID.length > 0) {
|
|
420
|
+
const segmentId = definingSegmentByModuleID.get(moduleId) ?? 0;
|
|
421
|
+
const definer = moduleDefinersBySegmentID[segmentId];
|
|
422
|
+
if (definer != null) {
|
|
423
|
+
definer(moduleId);
|
|
424
|
+
module = modules.get(moduleId);
|
|
425
|
+
definingSegmentByModuleID.delete(moduleId);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const nativeRequire = global.nativeRequire;
|
|
430
|
+
if (!module && nativeRequire) {
|
|
431
|
+
const { segmentId, localId } = unpackModuleId(moduleId);
|
|
432
|
+
nativeRequire(localId, segmentId);
|
|
433
|
+
module = modules.get(moduleId);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (!module) {
|
|
437
|
+
throw unknownModuleError(moduleId);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (module.hasError) {
|
|
441
|
+
throw module.error;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (__DEV__) {
|
|
445
|
+
var Systrace = requireSystrace();
|
|
446
|
+
var Refresh = requireRefresh();
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// We must optimistically mark module as initialized before running the
|
|
450
|
+
// factory to keep any require cycles inside the factory from causing an
|
|
451
|
+
// infinite require loop.
|
|
452
|
+
module.isInitialized = true;
|
|
453
|
+
|
|
454
|
+
const { factory, dependencyMap } = module;
|
|
455
|
+
if (__DEV__) {
|
|
456
|
+
initializingModuleIds.push(moduleId);
|
|
457
|
+
}
|
|
458
|
+
try {
|
|
459
|
+
if (__DEV__) {
|
|
460
|
+
// $FlowFixMe: we know that __DEV__ is const and `Systrace` exists
|
|
461
|
+
Systrace.beginEvent('JS_require_' + (module.verboseName || moduleId));
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
const moduleObject: Module = module.publicModule;
|
|
465
|
+
|
|
466
|
+
if (__DEV__) {
|
|
467
|
+
moduleObject.hot = module.hot;
|
|
468
|
+
|
|
469
|
+
var prevRefreshReg = global.$RefreshReg$;
|
|
470
|
+
var prevRefreshSig = global.$RefreshSig$;
|
|
471
|
+
if (Refresh != null) {
|
|
472
|
+
const RefreshRuntime = Refresh;
|
|
473
|
+
global.$RefreshReg$ = (type, id) => {
|
|
474
|
+
// prefix the id with global prefix to enable multiple HMR clients
|
|
475
|
+
const prefixedModuleId =
|
|
476
|
+
__METRO_GLOBAL_PREFIX__ + ' ' + moduleId + ' ' + id;
|
|
477
|
+
RefreshRuntime.register(type, prefixedModuleId);
|
|
478
|
+
};
|
|
479
|
+
global.$RefreshSig$ =
|
|
480
|
+
RefreshRuntime.createSignatureFunctionForTransform;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
moduleObject.id = moduleId;
|
|
484
|
+
|
|
485
|
+
// keep args in sync with with defineModuleCode in
|
|
486
|
+
// metro/src/Resolver/index.js
|
|
487
|
+
// and metro/src/ModuleGraph/worker.js
|
|
488
|
+
factory(
|
|
489
|
+
global,
|
|
490
|
+
(...args) => global.__r(...args),
|
|
491
|
+
(...args) => global.__r.importDefault(...args),
|
|
492
|
+
(...args) => global.__r.importAll(...args),
|
|
493
|
+
moduleObject,
|
|
494
|
+
moduleObject.exports,
|
|
495
|
+
dependencyMap
|
|
496
|
+
);
|
|
497
|
+
|
|
498
|
+
// avoid removing factory in DEV mode as it breaks HMR
|
|
499
|
+
if (!__DEV__) {
|
|
500
|
+
// $FlowFixMe: This is only sound because we never access `factory` again
|
|
501
|
+
module.factory = undefined;
|
|
502
|
+
module.dependencyMap = undefined;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (__DEV__) {
|
|
506
|
+
// $FlowFixMe: we know that __DEV__ is const and `Systrace` exists
|
|
507
|
+
Systrace.endEvent();
|
|
508
|
+
|
|
509
|
+
if (Refresh != null) {
|
|
510
|
+
// prefix the id with global prefix to enable multiple HMR clients
|
|
511
|
+
const prefixedModuleId = __METRO_GLOBAL_PREFIX__ + ' ' + moduleId;
|
|
512
|
+
registerExportsForReactRefresh(
|
|
513
|
+
Refresh,
|
|
514
|
+
moduleObject.exports,
|
|
515
|
+
prefixedModuleId
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
return moduleObject.exports;
|
|
521
|
+
} catch (e) {
|
|
522
|
+
module.hasError = true;
|
|
523
|
+
module.error = e;
|
|
524
|
+
module.isInitialized = false;
|
|
525
|
+
module.publicModule.exports = undefined;
|
|
526
|
+
throw e;
|
|
527
|
+
} finally {
|
|
528
|
+
if (__DEV__) {
|
|
529
|
+
if (initializingModuleIds.pop() !== moduleId) {
|
|
530
|
+
throw new Error(
|
|
531
|
+
'initializingModuleIds is corrupt; something is terribly wrong'
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
global.$RefreshReg$ = prevRefreshReg;
|
|
535
|
+
global.$RefreshSig$ = prevRefreshSig;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
function unknownModuleError(id: ModuleID): Error {
|
|
541
|
+
let message = 'Requiring unknown module "' + id + '".';
|
|
542
|
+
if (__DEV__) {
|
|
543
|
+
message +=
|
|
544
|
+
' If you are sure the module exists, try restarting Metro. ' +
|
|
545
|
+
'You may also want to run `yarn` or `npm install`.';
|
|
546
|
+
}
|
|
547
|
+
return Error(message);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
if (__DEV__) {
|
|
551
|
+
// $FlowFixMe[prop-missing]
|
|
552
|
+
metroRequire.Systrace = {
|
|
553
|
+
beginEvent: (): void => {},
|
|
554
|
+
endEvent: (): void => {},
|
|
555
|
+
};
|
|
556
|
+
// $FlowFixMe[prop-missing]
|
|
557
|
+
metroRequire.getModules = (): ModuleList => {
|
|
558
|
+
return modules;
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
// HOT MODULE RELOADING
|
|
562
|
+
var createHotReloadingObject = function () {
|
|
563
|
+
const hot: HotModuleReloadingData = {
|
|
564
|
+
_acceptCallback: null,
|
|
565
|
+
_disposeCallback: null,
|
|
566
|
+
_didAccept: false,
|
|
567
|
+
accept: (callback?: HotModuleReloadingCallback): void => {
|
|
568
|
+
hot._didAccept = true;
|
|
569
|
+
hot._acceptCallback = callback;
|
|
570
|
+
},
|
|
571
|
+
dispose: (callback?: HotModuleReloadingCallback): void => {
|
|
572
|
+
hot._disposeCallback = callback;
|
|
573
|
+
},
|
|
574
|
+
};
|
|
575
|
+
return hot;
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
let reactRefreshTimeout: null | TimeoutID = null;
|
|
579
|
+
|
|
580
|
+
const metroHotUpdateModule = function (
|
|
581
|
+
id: ModuleID,
|
|
582
|
+
factory: FactoryFn,
|
|
583
|
+
dependencyMap: DependencyMap,
|
|
584
|
+
inverseDependencies: InverseDependencyMap
|
|
585
|
+
) {
|
|
586
|
+
const mod = modules.get(id);
|
|
587
|
+
if (!mod) {
|
|
588
|
+
/* $FlowFixMe[constant-condition] Error discovered during Constant
|
|
589
|
+
* Condition roll out. See https://fburl.com/workplace/1v97vimq. */
|
|
590
|
+
if (factory) {
|
|
591
|
+
// New modules are going to be handled by the define() method.
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
throw unknownModuleError(id);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
if (!mod.hasError && !mod.isInitialized) {
|
|
598
|
+
// The module hasn't actually been executed yet,
|
|
599
|
+
// so we can always safely replace it.
|
|
600
|
+
mod.factory = factory;
|
|
601
|
+
mod.dependencyMap = dependencyMap;
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
const Refresh = requireRefresh();
|
|
606
|
+
const refreshBoundaryIDs = new Set<ModuleID>();
|
|
607
|
+
|
|
608
|
+
// In this loop, we will traverse the dependency tree upwards from the
|
|
609
|
+
// changed module. Updates "bubble" up to the closest accepted parent.
|
|
610
|
+
//
|
|
611
|
+
// If we reach the module root and nothing along the way accepted the update,
|
|
612
|
+
// we know hot reload is going to fail. In that case we return false.
|
|
613
|
+
//
|
|
614
|
+
// The main purpose of this loop is to figure out whether it's safe to apply
|
|
615
|
+
// a hot update. It is only safe when the update was accepted somewhere
|
|
616
|
+
// along the way upwards for each of its parent dependency module chains.
|
|
617
|
+
//
|
|
618
|
+
// We perform a topological sort because we may discover the same
|
|
619
|
+
// module more than once in the list of things to re-execute, and
|
|
620
|
+
// we want to execute modules before modules that depend on them.
|
|
621
|
+
//
|
|
622
|
+
// If we didn't have this check, we'd risk re-evaluating modules that
|
|
623
|
+
// have side effects and lead to confusing and meaningless crashes.
|
|
624
|
+
|
|
625
|
+
let didBailOut = false;
|
|
626
|
+
let updatedModuleIDs;
|
|
627
|
+
try {
|
|
628
|
+
updatedModuleIDs = topologicalSort(
|
|
629
|
+
[id], // Start with the changed module and go upwards
|
|
630
|
+
(pendingID) => {
|
|
631
|
+
const pendingModule = modules.get(pendingID);
|
|
632
|
+
if (pendingModule == null) {
|
|
633
|
+
// Nothing to do.
|
|
634
|
+
return [];
|
|
635
|
+
}
|
|
636
|
+
const pendingHot = pendingModule.hot;
|
|
637
|
+
if (pendingHot == null) {
|
|
638
|
+
throw new Error(
|
|
639
|
+
'[Refresh] Expected module.hot to always exist in DEV.'
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
// A module can be accepted manually from within itself.
|
|
643
|
+
let canAccept = pendingHot._didAccept;
|
|
644
|
+
if (!canAccept && Refresh != null) {
|
|
645
|
+
// Or React Refresh may mark it accepted based on exports.
|
|
646
|
+
const isBoundary = isReactRefreshBoundary(
|
|
647
|
+
Refresh,
|
|
648
|
+
pendingModule.publicModule.exports
|
|
649
|
+
);
|
|
650
|
+
if (isBoundary) {
|
|
651
|
+
canAccept = true;
|
|
652
|
+
refreshBoundaryIDs.add(pendingID);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
if (canAccept) {
|
|
656
|
+
// Don't look at parents.
|
|
657
|
+
return [];
|
|
658
|
+
}
|
|
659
|
+
// If we bubble through the roof, there is no way to do a hot update.
|
|
660
|
+
// Bail out altogether. This is the failure case.
|
|
661
|
+
const parentIDs = inverseDependencies[pendingID];
|
|
662
|
+
if (parentIDs.length === 0) {
|
|
663
|
+
// Reload the app because the hot reload can't succeed.
|
|
664
|
+
// This should work both on web and React Native.
|
|
665
|
+
performFullRefresh('No root boundary', {
|
|
666
|
+
source: mod,
|
|
667
|
+
failed: pendingModule,
|
|
668
|
+
});
|
|
669
|
+
didBailOut = true;
|
|
670
|
+
return [];
|
|
671
|
+
}
|
|
672
|
+
// This module can't handle the update but maybe all its parents can?
|
|
673
|
+
// Put them all in the queue to run the same set of checks.
|
|
674
|
+
return parentIDs;
|
|
675
|
+
},
|
|
676
|
+
() => didBailOut // Should we stop?
|
|
677
|
+
).reverse();
|
|
678
|
+
} catch (e) {
|
|
679
|
+
if (e === CYCLE_DETECTED) {
|
|
680
|
+
performFullRefresh('Dependency cycle', {
|
|
681
|
+
source: mod,
|
|
682
|
+
});
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
throw e;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
if (didBailOut) {
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// If we reached here, it is likely that hot reload will be successful.
|
|
693
|
+
// Run the actual factories.
|
|
694
|
+
const seenModuleIDs = new Set<ModuleID>();
|
|
695
|
+
for (let i = 0; i < updatedModuleIDs.length; i++) {
|
|
696
|
+
const updatedID = updatedModuleIDs[i];
|
|
697
|
+
if (seenModuleIDs.has(updatedID)) {
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
seenModuleIDs.add(updatedID);
|
|
701
|
+
|
|
702
|
+
const updatedMod = modules.get(updatedID);
|
|
703
|
+
if (updatedMod == null) {
|
|
704
|
+
throw new Error('[Refresh] Expected to find the updated module.');
|
|
705
|
+
}
|
|
706
|
+
const prevExports = updatedMod.publicModule.exports;
|
|
707
|
+
const didError = runUpdatedModule(
|
|
708
|
+
updatedID,
|
|
709
|
+
updatedID === id ? factory : undefined,
|
|
710
|
+
updatedID === id ? dependencyMap : undefined
|
|
711
|
+
);
|
|
712
|
+
const nextExports = updatedMod.publicModule.exports;
|
|
713
|
+
|
|
714
|
+
if (didError) {
|
|
715
|
+
// The user was shown a redbox about module initialization.
|
|
716
|
+
// There's nothing for us to do here until it's fixed.
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
if (refreshBoundaryIDs.has(updatedID)) {
|
|
721
|
+
// Since we just executed the code for it, it's possible
|
|
722
|
+
// that the new exports make it ineligible for being a boundary.
|
|
723
|
+
const isNoLongerABoundary = !isReactRefreshBoundary(
|
|
724
|
+
Refresh,
|
|
725
|
+
nextExports
|
|
726
|
+
);
|
|
727
|
+
// It can also become ineligible if its exports are incompatible
|
|
728
|
+
// with the previous exports.
|
|
729
|
+
// For example, if you add/remove/change exports, we'll want
|
|
730
|
+
// to re-execute the importing modules, and force those components
|
|
731
|
+
// to re-render. Similarly, if you convert a class component
|
|
732
|
+
// to a function, we want to invalidate the boundary.
|
|
733
|
+
const didInvalidate = shouldInvalidateReactRefreshBoundary(
|
|
734
|
+
Refresh,
|
|
735
|
+
prevExports,
|
|
736
|
+
nextExports
|
|
737
|
+
);
|
|
738
|
+
if (isNoLongerABoundary || didInvalidate) {
|
|
739
|
+
// We'll be conservative. The only case in which we won't do a full
|
|
740
|
+
// reload is if all parent modules are also refresh boundaries.
|
|
741
|
+
// In that case we'll add them to the current queue.
|
|
742
|
+
const parentIDs = inverseDependencies[updatedID];
|
|
743
|
+
if (parentIDs.length === 0) {
|
|
744
|
+
// Looks like we bubbled to the root. Can't recover from that.
|
|
745
|
+
performFullRefresh(
|
|
746
|
+
isNoLongerABoundary
|
|
747
|
+
? 'No longer a boundary'
|
|
748
|
+
: 'Invalidated boundary',
|
|
749
|
+
{
|
|
750
|
+
source: mod,
|
|
751
|
+
failed: updatedMod,
|
|
752
|
+
}
|
|
753
|
+
);
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
// Schedule all parent refresh boundaries to re-run in this loop.
|
|
757
|
+
for (let j = 0; j < parentIDs.length; j++) {
|
|
758
|
+
const parentID = parentIDs[j];
|
|
759
|
+
const parentMod = modules.get(parentID);
|
|
760
|
+
if (parentMod == null) {
|
|
761
|
+
throw new Error('[Refresh] Expected to find parent module.');
|
|
762
|
+
}
|
|
763
|
+
const canAcceptParent = isReactRefreshBoundary(
|
|
764
|
+
Refresh,
|
|
765
|
+
parentMod.publicModule.exports
|
|
766
|
+
);
|
|
767
|
+
if (canAcceptParent) {
|
|
768
|
+
// All parents will have to re-run too.
|
|
769
|
+
refreshBoundaryIDs.add(parentID);
|
|
770
|
+
updatedModuleIDs.push(parentID);
|
|
771
|
+
} else {
|
|
772
|
+
performFullRefresh('Invalidated boundary', {
|
|
773
|
+
source: mod,
|
|
774
|
+
failed: parentMod,
|
|
775
|
+
});
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
if (Refresh != null) {
|
|
784
|
+
// Debounce a little in case there are multiple updates queued up.
|
|
785
|
+
// This is also useful because __accept may be called multiple times.
|
|
786
|
+
if (reactRefreshTimeout == null) {
|
|
787
|
+
reactRefreshTimeout = setTimeout(() => {
|
|
788
|
+
reactRefreshTimeout = null;
|
|
789
|
+
// Update React components.
|
|
790
|
+
Refresh.performReactRefresh();
|
|
791
|
+
}, 30);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
|
|
796
|
+
const topologicalSort = function <T>(
|
|
797
|
+
roots: Array<T>,
|
|
798
|
+
getEdges: (T) => Array<T>,
|
|
799
|
+
earlyStop: (T) => boolean
|
|
800
|
+
): Array<T> {
|
|
801
|
+
const result = [];
|
|
802
|
+
const visited = new Set<mixed>();
|
|
803
|
+
const stack = new Set<mixed>();
|
|
804
|
+
function traverseDependentNodes(node: T): void {
|
|
805
|
+
if (stack.has(node)) {
|
|
806
|
+
throw CYCLE_DETECTED;
|
|
807
|
+
}
|
|
808
|
+
if (visited.has(node)) {
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
visited.add(node);
|
|
812
|
+
stack.add(node);
|
|
813
|
+
const dependentNodes = getEdges(node);
|
|
814
|
+
if (earlyStop(node)) {
|
|
815
|
+
stack.delete(node);
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
dependentNodes.forEach((dependent) => {
|
|
819
|
+
traverseDependentNodes(dependent);
|
|
820
|
+
});
|
|
821
|
+
stack.delete(node);
|
|
822
|
+
result.push(node);
|
|
823
|
+
}
|
|
824
|
+
roots.forEach((root) => {
|
|
825
|
+
traverseDependentNodes(root);
|
|
826
|
+
});
|
|
827
|
+
return result;
|
|
828
|
+
};
|
|
829
|
+
|
|
830
|
+
const runUpdatedModule = function (
|
|
831
|
+
id: ModuleID,
|
|
832
|
+
factory?: FactoryFn,
|
|
833
|
+
dependencyMap?: DependencyMap
|
|
834
|
+
): boolean {
|
|
835
|
+
const mod = modules.get(id);
|
|
836
|
+
if (mod == null) {
|
|
837
|
+
throw new Error('[Refresh] Expected to find the module.');
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
const { hot } = mod;
|
|
841
|
+
if (!hot) {
|
|
842
|
+
throw new Error('[Refresh] Expected module.hot to always exist in DEV.');
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
if (hot._disposeCallback) {
|
|
846
|
+
try {
|
|
847
|
+
hot._disposeCallback();
|
|
848
|
+
} catch (error) {
|
|
849
|
+
console.error(
|
|
850
|
+
`Error while calling dispose handler for module ${id}: `,
|
|
851
|
+
error
|
|
852
|
+
);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
if (factory) {
|
|
857
|
+
mod.factory = factory;
|
|
858
|
+
}
|
|
859
|
+
if (dependencyMap) {
|
|
860
|
+
mod.dependencyMap = dependencyMap;
|
|
861
|
+
}
|
|
862
|
+
mod.hasError = false;
|
|
863
|
+
mod.error = undefined;
|
|
864
|
+
mod.importedAll = EMPTY;
|
|
865
|
+
mod.importedDefault = EMPTY;
|
|
866
|
+
mod.isInitialized = false;
|
|
867
|
+
const prevExports = mod.publicModule.exports;
|
|
868
|
+
mod.publicModule.exports = {};
|
|
869
|
+
hot._didAccept = false;
|
|
870
|
+
hot._acceptCallback = null;
|
|
871
|
+
hot._disposeCallback = null;
|
|
872
|
+
global.__r(id);
|
|
873
|
+
|
|
874
|
+
if (mod.hasError) {
|
|
875
|
+
// This error has already been reported via a redbox.
|
|
876
|
+
// We know it's likely a typo or some mistake that was just introduced.
|
|
877
|
+
// Our goal now is to keep the rest of the application working so that by
|
|
878
|
+
// the time user fixes the error, the app isn't completely destroyed
|
|
879
|
+
// underneath the redbox. So we'll revert the module object to the last
|
|
880
|
+
// successful export and stop propagating this update.
|
|
881
|
+
mod.hasError = false;
|
|
882
|
+
mod.isInitialized = true;
|
|
883
|
+
mod.error = null;
|
|
884
|
+
mod.publicModule.exports = prevExports;
|
|
885
|
+
// We errored. Stop the update.
|
|
886
|
+
return true;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
if (hot._acceptCallback) {
|
|
890
|
+
try {
|
|
891
|
+
hot._acceptCallback();
|
|
892
|
+
} catch (error) {
|
|
893
|
+
console.error(
|
|
894
|
+
`Error while calling accept handler for module ${id}: `,
|
|
895
|
+
error
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
// No error.
|
|
900
|
+
return false;
|
|
901
|
+
};
|
|
902
|
+
|
|
903
|
+
const performFullRefresh = (
|
|
904
|
+
reason: string,
|
|
905
|
+
modules: $ReadOnly<{
|
|
906
|
+
source?: ModuleDefinition,
|
|
907
|
+
failed?: ModuleDefinition,
|
|
908
|
+
}>
|
|
909
|
+
) => {
|
|
910
|
+
/* global window */
|
|
911
|
+
if (
|
|
912
|
+
typeof window !== 'undefined' &&
|
|
913
|
+
window.location != null &&
|
|
914
|
+
// $FlowFixMe[method-unbinding]
|
|
915
|
+
typeof window.location.reload === 'function'
|
|
916
|
+
) {
|
|
917
|
+
window.location.reload();
|
|
918
|
+
} else {
|
|
919
|
+
const Refresh = requireRefresh();
|
|
920
|
+
if (Refresh != null) {
|
|
921
|
+
const sourceName = modules.source?.verboseName ?? 'unknown';
|
|
922
|
+
const failedName = modules.failed?.verboseName ?? 'unknown';
|
|
923
|
+
Refresh.performFullRefresh(
|
|
924
|
+
`Fast Refresh - ${reason} <${sourceName}> <${failedName}>`
|
|
925
|
+
);
|
|
926
|
+
} else {
|
|
927
|
+
console.warn('Could not reload the application after an edit.');
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
|
|
932
|
+
// Modules that only export components become React Refresh boundaries.
|
|
933
|
+
var isReactRefreshBoundary = function (
|
|
934
|
+
Refresh: any,
|
|
935
|
+
moduleExports: Exports
|
|
936
|
+
): boolean {
|
|
937
|
+
if (Refresh.isLikelyComponentType(moduleExports)) {
|
|
938
|
+
return true;
|
|
939
|
+
}
|
|
940
|
+
if (moduleExports == null || typeof moduleExports !== 'object') {
|
|
941
|
+
// Exit if we can't iterate over exports.
|
|
942
|
+
return false;
|
|
943
|
+
}
|
|
944
|
+
let hasExports = false;
|
|
945
|
+
let areAllExportsComponents = true;
|
|
946
|
+
for (const key in moduleExports) {
|
|
947
|
+
hasExports = true;
|
|
948
|
+
if (key === '__esModule') {
|
|
949
|
+
continue;
|
|
950
|
+
}
|
|
951
|
+
const desc = Object.getOwnPropertyDescriptor<any>(moduleExports, key);
|
|
952
|
+
if (desc && desc.get) {
|
|
953
|
+
// Don't invoke getters as they may have side effects.
|
|
954
|
+
return false;
|
|
955
|
+
}
|
|
956
|
+
const exportValue = moduleExports[key];
|
|
957
|
+
if (!Refresh.isLikelyComponentType(exportValue)) {
|
|
958
|
+
areAllExportsComponents = false;
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
return hasExports && areAllExportsComponents;
|
|
962
|
+
};
|
|
963
|
+
|
|
964
|
+
var shouldInvalidateReactRefreshBoundary = (
|
|
965
|
+
Refresh: any,
|
|
966
|
+
prevExports: Exports,
|
|
967
|
+
nextExports: Exports
|
|
968
|
+
) => {
|
|
969
|
+
const prevSignature = getRefreshBoundarySignature(Refresh, prevExports);
|
|
970
|
+
const nextSignature = getRefreshBoundarySignature(Refresh, nextExports);
|
|
971
|
+
if (prevSignature.length !== nextSignature.length) {
|
|
972
|
+
return true;
|
|
973
|
+
}
|
|
974
|
+
for (let i = 0; i < nextSignature.length; i++) {
|
|
975
|
+
if (prevSignature[i] !== nextSignature[i]) {
|
|
976
|
+
return true;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
return false;
|
|
980
|
+
};
|
|
981
|
+
|
|
982
|
+
// When this signature changes, it's unsafe to stop at this refresh boundary.
|
|
983
|
+
var getRefreshBoundarySignature = (
|
|
984
|
+
Refresh: any,
|
|
985
|
+
moduleExports: Exports
|
|
986
|
+
): Array<mixed> => {
|
|
987
|
+
const signature = [];
|
|
988
|
+
signature.push(Refresh.getFamilyByType(moduleExports));
|
|
989
|
+
if (moduleExports == null || typeof moduleExports !== 'object') {
|
|
990
|
+
// Exit if we can't iterate over exports.
|
|
991
|
+
// (This is important for legacy environments.)
|
|
992
|
+
return signature;
|
|
993
|
+
}
|
|
994
|
+
for (const key in moduleExports) {
|
|
995
|
+
if (key === '__esModule') {
|
|
996
|
+
continue;
|
|
997
|
+
}
|
|
998
|
+
const desc = Object.getOwnPropertyDescriptor<any>(moduleExports, key);
|
|
999
|
+
if (desc && desc.get) {
|
|
1000
|
+
continue;
|
|
1001
|
+
}
|
|
1002
|
+
const exportValue = moduleExports[key];
|
|
1003
|
+
signature.push(key);
|
|
1004
|
+
signature.push(Refresh.getFamilyByType(exportValue));
|
|
1005
|
+
}
|
|
1006
|
+
return signature;
|
|
1007
|
+
};
|
|
1008
|
+
|
|
1009
|
+
var registerExportsForReactRefresh = (
|
|
1010
|
+
Refresh: any,
|
|
1011
|
+
moduleExports: Exports,
|
|
1012
|
+
moduleID: string
|
|
1013
|
+
) => {
|
|
1014
|
+
Refresh.register(moduleExports, moduleID + ' %exports%');
|
|
1015
|
+
if (moduleExports == null || typeof moduleExports !== 'object') {
|
|
1016
|
+
// Exit if we can't iterate over exports.
|
|
1017
|
+
// (This is important for legacy environments.)
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
for (const key in moduleExports) {
|
|
1021
|
+
const desc = Object.getOwnPropertyDescriptor<any>(moduleExports, key);
|
|
1022
|
+
if (desc && desc.get) {
|
|
1023
|
+
// Don't invoke getters as they may have side effects.
|
|
1024
|
+
continue;
|
|
1025
|
+
}
|
|
1026
|
+
const exportValue = moduleExports[key];
|
|
1027
|
+
const typeID = moduleID + ' %exports% ' + key;
|
|
1028
|
+
Refresh.register(exportValue, typeID);
|
|
1029
|
+
}
|
|
1030
|
+
};
|
|
1031
|
+
|
|
1032
|
+
global.__accept = metroHotUpdateModule;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
if (__DEV__) {
|
|
1036
|
+
// The metro require polyfill can not have module dependencies.
|
|
1037
|
+
// The Systrace and ReactRefresh dependencies are, therefore, made publicly
|
|
1038
|
+
// available. Ideally, the dependency would be inversed in a way that
|
|
1039
|
+
// Systrace / ReactRefresh could integrate into Metro rather than
|
|
1040
|
+
// having to make them publicly available.
|
|
1041
|
+
|
|
1042
|
+
var requireSystrace = function requireSystrace() {
|
|
1043
|
+
return (
|
|
1044
|
+
// $FlowFixMe[prop-missing]
|
|
1045
|
+
global[__METRO_GLOBAL_PREFIX__ + '__SYSTRACE'] || metroRequire.Systrace
|
|
1046
|
+
);
|
|
1047
|
+
};
|
|
1048
|
+
|
|
1049
|
+
var requireRefresh = function requireRefresh() {
|
|
1050
|
+
// __METRO_GLOBAL_PREFIX__ and global.__METRO_GLOBAL_PREFIX__ differ from
|
|
1051
|
+
// each other when multiple module systems are used - e.g, in the context
|
|
1052
|
+
// of Module Federation, the first one would refer to the local prefix
|
|
1053
|
+
// defined at the top of the bundle, while the other always refers to the
|
|
1054
|
+
// one coming from the Host
|
|
1055
|
+
return (
|
|
1056
|
+
global[__METRO_GLOBAL_PREFIX__ + '__ReactRefresh'] ||
|
|
1057
|
+
global[global.__METRO_GLOBAL_PREFIX__ + '__ReactRefresh'] ||
|
|
1058
|
+
// $FlowFixMe[prop-missing]
|
|
1059
|
+
metroRequire.Refresh
|
|
1060
|
+
);
|
|
1061
|
+
};
|
|
1062
|
+
}
|