134
},
135
};
136
137
-const proxyHandlers = {
138
- get: function (
139
- target: Function,
140
- name: string,
141
- receiver: Proxy<Function>,
142
- ): $FlowFixMe {
143
- switch (name) {
144
- // These names are read by the Flight runtime if you end up using the exports object.
145
- case '$$typeof':
146
- return target.$$typeof;
147
- case '$$id':
148
- return target.$$id;
149
- case '$$async':
150
- return target.$$async;
151
- case 'name':
152
- return target.name;
153
- // We need to special case this because createElement reads it if we pass this
154
- // reference.
155
- case 'defaultProps':
156
- return undefined;
157
- // Avoid this attempting to be serialized.
158
- case 'toJSON':
159
- return undefined;
160
- case Symbol.toPrimitive:
161
- // $FlowFixMe[prop-missing]
162
- return Object.prototype[Symbol.toPrimitive];
163
- case '__esModule':
164
- // Something is conditionally checking which export to use. We'll pretend to be
165
- // an ESM compat module but then we'll check again on the client.
166
- const moduleId = target.$$id;
167
- target.default = registerClientReferenceImpl(
168
- (function () {
169
- throw new Error(
170
- `Attempted to call the default export of ${moduleId} from the server ` +
171
- `but it's on the client. It's not possible to invoke a client function from ` +
172
- `the server, it can only be rendered as a Component or passed to props of a ` +
173
- `Client Component.`,
174
- );
175
- }: any),
176
- target.$$id + '#',
177
- target.$$async,
178
- );
179
- return true;
180
- case 'then':
181
- if (target.then) {
182
- // Use a cached value
183
- return target.then;
184
- }
185
- if (!target.$$async) {
186
- // If this module is expected to return a Promise (such as an AsyncModule) then
187
- // we should resolve that with a client reference that unwraps the Promise on
188
- // the client.
189
-
190
- const clientReference: ClientReference<any> =
191
- registerClientReferenceImpl(({}: any), target.$$id, true);
192
- const proxy = new Proxy(clientReference, proxyHandlers);
193
-
194
- // Treat this as a resolved Promise for React's use()
195
- target.status = 'fulfilled';
196
- target.value = proxy;
197
-
198
- const then = (target.then = registerClientReferenceImpl(
199
- (function then(resolve, reject: any) {
200
- // Expose to React.
201
- return Promise.resolve(resolve(proxy));
202
- }: any),
203
- // If this is not used as a Promise but is treated as a reference to a `.then`
204
- // export then we should treat it as a reference to that name.
205
- target.$$id + '#then',
206
- false,
207
- ));
208
- return then;
209
- } else {
210
- // Since typeof .then === 'function' is a feature test we'd continue recursing
211
- // indefinitely if we return a function. Instead, we return an object reference
212
- // if we check further.
213
- return undefined;
214
- }
215
- }
216
- let cachedReference = target[name];
217
- if (!cachedReference) {
218
- const reference: ClientReference<any> = registerClientReferenceImpl(
137
+function getReference(target: Function, name: string): $FlowFixMe {
138
+ switch (name) {
139
+ // These names are read by the Flight runtime if you end up using the exports object.
140
+ case '$$typeof':
141
+ return target.$$typeof;
142
+ case '$$id':
143
+ return target.$$id;
144
+ case '$$async':
145
+ return target.$$async;
146
+ case 'name':
147
+ return target.name;
148
+ // We need to special case this because createElement reads it if we pass this
149
+ // reference.
150
+ case 'defaultProps':
151
+ return undefined;
152
+ // Avoid this attempting to be serialized.
153
+ case 'toJSON':
154
+ return undefined;
155
+ case Symbol.toPrimitive:
156
+ // $FlowFixMe[prop-missing]
157
+ return Object.prototype[Symbol.toPrimitive];
158
+ case '__esModule':
159
+ // Something is conditionally checking which export to use. We'll pretend to be
160
+ // an ESM compat module but then we'll check again on the client.
161
+ const moduleId = target.$$id;
162
+ target.default = registerClientReferenceImpl(
163
(function () {
164
throw new Error(
221
- // eslint-disable-next-line react-internal/safe-string-coercion
222
- `Attempted to call ${String(name)}() from the server but ${String(
223
- name,
224
- )} is on the client. ` +
225
- `It's not possible to invoke a client function from the server, it can ` +
226
- `only be rendered as a Component or passed to props of a Client Component.`,
165
+ `Attempted to call the default export of ${moduleId} from the server ` +
166
+ `but it's on the client. It's not possible to invoke a client function from ` +
167
+ `the server, it can only be rendered as a Component or passed to props of a ` +
168
+ `Client Component.`,
169
);
170
}: any),
229
- target.$$id + '#' + name,
171
+ target.$$id + '#',
172
target.$$async,
173
);
232
- Object.defineProperty((reference: any), 'name', {value: name});
233
- cachedReference = target[name] = new Proxy(reference, deepProxyHandlers);
174
+ return true;
175
+ case 'then':
176
+ if (target.then) {
177
+ // Use a cached value
178
+ return target.then;
179
+ }
180
+ if (!target.$$async) {
181
+ // If this module is expected to return a Promise (such as an AsyncModule) then
182
+ // we should resolve that with a client reference that unwraps the Promise on
183
+ // the client.
184
+
185
+ const clientReference: ClientReference<any> =
186
+ registerClientReferenceImpl(({}: any), target.$$id, true);
187
+ const proxy = new Proxy(clientReference, proxyHandlers);
188
+
189
+ // Treat this as a resolved Promise for React's use()
190
+ target.status = 'fulfilled';
191
+ target.value = proxy;
192
+
193
+ const then = (target.then = registerClientReferenceImpl(
194
+ (function then(resolve, reject: any) {
195
+ // Expose to React.
196
+ return Promise.resolve(resolve(proxy));
197
+ }: any),
198
+ // If this is not used as a Promise but is treated as a reference to a `.then`
199
+ // export then we should treat it as a reference to that name.
200
+ target.$$id + '#then',
201
+ false,
202
+ ));
203
+ return then;
204
+ } else {
205
+ // Since typeof .then === 'function' is a feature test we'd continue recursing
206
+ // indefinitely if we return a function. Instead, we return an object reference
207
+ // if we check further.
208
+ return undefined;
209
+ }
210
+ }
211
+ let cachedReference = target[name];
212
+ if (!cachedReference) {
213
+ const reference: ClientReference<any> = registerClientReferenceImpl(
214
+ (function () {
215
+ throw new Error(
216
+ // eslint-disable-next-line react-internal/safe-string-coercion
217
+ `Attempted to call ${String(name)}() from the server but ${String(
218
+ name,
219
+ )} is on the client. ` +
220
+ `It's not possible to invoke a client function from the server, it can ` +
221
+ `only be rendered as a Component or passed to props of a Client Component.`,
222
+ );
223
+ }: any),
224
+ target.$$id + '#' + name,
225
+ target.$$async,
226
+ );
227
+ Object.defineProperty((reference: any), 'name', {value: name});
228
+ cachedReference = target[name] = new Proxy(reference, deepProxyHandlers);
229
+ }
230
+ return cachedReference;
231
+}
232
+
233
+const proxyHandlers = {
234
+ get: function (
235
+ target: Function,
236
+ name: string,
237
+ receiver: Proxy<Function>,
238
+ ): $FlowFixMe {
239
+ return getReference(target, name);
240
+ },
241
+ getOwnPropertyDescriptor: function (
242
+ target: Function,
243
+ name: string,
244
+ ): $FlowFixMe {
245
+ let descriptor = Object.getOwnPropertyDescriptor(target, name);
246
+ if (!descriptor) {
247
+ descriptor = {
248
+ value: getReference(target, name),
249
+ writable: false,
250
+ configurable: false,
251
+ enumerable: false,
252
+ };
253
+ Object.defineProperty(target, name, descriptor);
254
}
235
- return cachedReference;
255
+ return descriptor;
256
},
257
getPrototypeOf(target: Function): Object {
258
// Pretend to be a Promise in case anyone asks.