28
29
type ResolvedPayload<T> = {
30
_status: 1,
31
- _result: T,
31
+ _result: {default: T},
32
};
33
34
type RejectedPayload = {
53
const ctor = payload._result;
54
const thenable = ctor();
55
// Transition to the next state.
56
- const pending: PendingPayload = (payload: any);
57
- pending._status = Pending;
58
- pending._result = thenable;
56
+ // This might throw either because it's missing or throws. If so, we treat it
57
+ // as still uninitialized and try again next time. Which is the same as what
58
+ // happens if the ctor or any wrappers processing the ctor throws. This might
59
+ // end up fixing it if the resolution was a concurrency bug.
60
thenable.then(
61
moduleObject => {
61
- if (payload._status === Pending) {
62
- const defaultExport = moduleObject.default;
63
- if (__DEV__) {
64
- if (defaultExport === undefined) {
65
- console.error(
66
- 'lazy: Expected the result of a dynamic import() call. ' +
67
- 'Instead received: %s\n\nYour code should look like: \n ' +
68
- // Break up imports to avoid accidentally parsing them as dependencies.
69
- 'const MyComponent = lazy(() => imp' +
70
- "ort('./MyComponent'))",
71
- moduleObject,
72
- );
73
- }
74
- }
62
+ if (payload._status === Pending || payload._status === Uninitialized) {
63
// Transition to the next state.
64
const resolved: ResolvedPayload<T> = (payload: any);
65
resolved._status = Resolved;
78
- resolved._result = defaultExport;
66
+ resolved._result = moduleObject;
67
}
68
},
69
error => {
82
- if (payload._status === Pending) {
70
+ if (payload._status === Pending || payload._status === Uninitialized) {
71
// Transition to the next state.
72
const rejected: RejectedPayload = (payload: any);
73
rejected._status = Rejected;
75
}
76
},
77
);
78
+ if (payload._status === Uninitialized) {
79
+ // In case, we're still uninitialized, then we're waiting for the thenable
80
+ // to resolve. Set it as pending in the meantime.
81
+ const pending: PendingPayload = (payload: any);
82
+ pending._status = Pending;
83
+ pending._result = thenable;
84
+ }
85
}
86
if (payload._status === Resolved) {
92
- return payload._result;
87
+ const moduleObject = payload._result;
88
+ if (__DEV__) {
89
+ if (moduleObject === undefined) {
90
+ console.error(
91
+ 'lazy: Expected the result of a dynamic import() call. ' +
92
+ 'Instead received: %s\n\nYour code should look like: \n ' +
93
+ // Break up imports to avoid accidentally parsing them as dependencies.
94
+ 'const MyComponent = lazy(() => imp' +
95
+ "ort('./MyComponent'))\n\n" +
96
+ 'Did you accidentally put curly braces around the import?',
97
+ moduleObject,
98
+ );
99
+ }
100
+ }
101
+ if (__DEV__) {
102
+ if (!('default' in moduleObject)) {
103
+ console.error(
104
+ 'lazy: Expected the result of a dynamic import() call. ' +
105
+ 'Instead received: %s\n\nYour code should look like: \n ' +
106
+ // Break up imports to avoid accidentally parsing them as dependencies.
107
+ 'const MyComponent = lazy(() => imp' +
108
+ "ort('./MyComponent'))",
109
+ moduleObject,
110
+ );
111
+ }
112
+ }
113
+ return moduleObject.default;
114
} else {
115
throw payload._result;
116
}