@@ -233,7 +233,7 @@ export default function createClient(clientOptions) {
233
233
} ;
234
234
}
235
235
236
- class UrlCallForwarder {
236
+ class PathCallForwarder {
237
237
constructor ( client , url ) {
238
238
this . client = client ;
239
239
this . url = url ;
@@ -265,17 +265,42 @@ class UrlCallForwarder {
265
265
}
266
266
}
267
267
268
- const clientProxyHandler = {
268
+ class PathClientProxyHandler {
269
+ constructor ( ) {
270
+ this . client = null ;
271
+ }
272
+
269
273
// Assume the property is an URL.
270
- get : ( coreClient , url ) => new UrlCallForwarder ( coreClient , url ) ,
271
- } ;
274
+ get ( coreClient , url ) {
275
+ const forwarder = new PathCallForwarder ( coreClient , url ) ;
276
+ this . client [ url ] = forwarder ;
277
+ return forwarder ;
278
+ }
279
+ }
272
280
273
281
/**
274
282
* Wrap openapi-fetch client to support a path based API.
275
283
* @type {import("./index.js").wrapAsPathBasedClient }
276
284
*/
277
285
export function wrapAsPathBasedClient ( coreClient ) {
278
- return new Proxy ( coreClient , clientProxyHandler ) ;
286
+ const handler = new PathClientProxyHandler ( ) ;
287
+ const proxy = new Proxy ( coreClient , handler ) ;
288
+
289
+ // Put the proxy on the prototype chain of the actual client.
290
+ // This means if we do not have a memoized PathCallForwarder,
291
+ // we fall back to the proxy to synthesize it.
292
+ // However, the proxy itself is not on the hot-path (if we fetch the same
293
+ // endpoint multiple times, only the first call will hit the proxy).
294
+ function Client ( ) { }
295
+ Client . prototype = proxy ;
296
+
297
+ const client = new Client ( ) ;
298
+
299
+ // Feed the client back to the proxy handler so it can store the generated
300
+ // PathCallForwarder.
301
+ handler . client = client ;
302
+
303
+ return client ;
279
304
}
280
305
281
306
/**
0 commit comments