diff --git a/packages/js/client/src/PolywrapClient.ts b/packages/js/client/src/PolywrapClient.ts index f66bf6cb94..1a59871523 100644 --- a/packages/js/client/src/PolywrapClient.ts +++ b/packages/js/client/src/PolywrapClient.ts @@ -39,6 +39,7 @@ import { RunOptions, GetManifestOptions, SimpleCache, + executeMaybeAsyncFunction, } from "@polywrap/core-js"; import { msgpackEncode, msgpackDecode } from "@polywrap/msgpack-js"; import { WrapManifest } from "@polywrap/wrap-manifest-types-js"; @@ -481,7 +482,9 @@ export class PolywrapClient implements Client { // Update cache for all URIs in the chain if (cacheWrite && wrapper) { const uris = uriHistory.getResolutionPath().stack.map((x) => x.sourceUri); - this._wrapperCache.set(uris, wrapper); + await executeMaybeAsyncFunction( + this._wrapperCache.set.bind(this._wrapperCache, uris, wrapper) + ); } if (shouldClearContext) { diff --git a/packages/js/core/src/__tests__/MaybeAsync.spec.ts b/packages/js/core/src/__tests__/MaybeAsync.spec.ts index b49e19e7b5..24ec6374fc 100644 --- a/packages/js/core/src/__tests__/MaybeAsync.spec.ts +++ b/packages/js/core/src/__tests__/MaybeAsync.spec.ts @@ -4,15 +4,37 @@ import { isPromise, } from ".."; +class ClassInstance { + constructor(private _prop: string) {} + + normalMethod(arg: string): string { + return this._prop + arg; + } + + async asyncMethod(arg: string): Promise { + await new Promise((resolve) => + setTimeout(resolve, 200) + ); + + return this._prop + arg; + } +} + describe("MaybeAsync", () => { const promise: MaybeAsync = new Promise((resolve, reject) => { return "" }); - const testFunction = (args: unknown[]) => { return "" }; - const testFunctionReturnPromise = (args: unknown[]) => new Promise((resolve, reject) => { return "" }); + const testFunction = (args: unknown[]) => { return "foo" }; + const testFunctionReturnPromise = (args: unknown[]) => new Promise((resolve) => { resolve("foo") }); - it("sanity", () => { + it("sanity", async () => { expect(isPromise(promise)).toBe(true); - expect(executeMaybeAsyncFunction(testFunction)).toBeDefined(); - expect(executeMaybeAsyncFunction(testFunctionReturnPromise)).toBeDefined(); + expect(await executeMaybeAsyncFunction(testFunction)).toBe("foo"); + expect(await executeMaybeAsyncFunction(testFunctionReturnPromise)).toBe("foo"); }); + + it("works with class instances", async () => { + const instance = new ClassInstance("bar"); + expect(await executeMaybeAsyncFunction(instance.normalMethod.bind(instance, "foo"))).toBe("barfoo") + expect(await executeMaybeAsyncFunction(instance.asyncMethod.bind(instance, "foo"))).toBe("barfoo") + }) }); diff --git a/packages/js/core/src/types/WrapperCache.ts b/packages/js/core/src/types/WrapperCache.ts index 05e5a79e76..4b9c4cc32b 100644 --- a/packages/js/core/src/types/WrapperCache.ts +++ b/packages/js/core/src/types/WrapperCache.ts @@ -1,8 +1,8 @@ -import { Uri, Wrapper } from "."; +import { Uri, Wrapper, MaybeAsync } from "."; export interface WrapperCache { - get(uri: Uri): Wrapper | undefined; - has(uri: Uri): boolean; - set(uris: Uri[], wrapper: Wrapper): void; - set(uri: Uri, wrapper: Wrapper): void; + get(uri: Uri): MaybeAsync; + has(uri: Uri): MaybeAsync; + set(uris: Uri[], wrapper: Wrapper): MaybeAsync; + set(uri: Uri, wrapper: Wrapper): MaybeAsync; } diff --git a/packages/js/core/src/uri-resolution/resolvers/cache/CacheResolver.ts b/packages/js/core/src/uri-resolution/resolvers/cache/CacheResolver.ts index b2e6aa3bb2..667efba413 100644 --- a/packages/js/core/src/uri-resolution/resolvers/cache/CacheResolver.ts +++ b/packages/js/core/src/uri-resolution/resolvers/cache/CacheResolver.ts @@ -1,4 +1,10 @@ -import { Uri, Client, WrapperCache } from "../../../types"; +import { + Uri, + Client, + WrapperCache, + executeMaybeAsyncFunction, + Wrapper, +} from "../../../types"; import { UriResolver, UriResolutionResult } from "../../core"; export class CacheResolver implements UriResolver { @@ -11,7 +17,9 @@ export class CacheResolver implements UriResolver { client: Client, cache: WrapperCache ): Promise { - const wrapper = cache.get(uri); + const wrapper = await executeMaybeAsyncFunction( + cache.get.bind(cache, uri) + ); return Promise.resolve({ uri: uri, diff --git a/packages/js/core/src/uri-resolution/resolvers/extendable/ExtendableUriResolver.ts b/packages/js/core/src/uri-resolution/resolvers/extendable/ExtendableUriResolver.ts index e18eaca513..85b46a588f 100644 --- a/packages/js/core/src/uri-resolution/resolvers/extendable/ExtendableUriResolver.ts +++ b/packages/js/core/src/uri-resolution/resolvers/extendable/ExtendableUriResolver.ts @@ -4,6 +4,7 @@ import { WrapperCache, getImplementations, coreInterfaceUris, + executeMaybeAsyncFunction, } from "../../.."; import { CreateWrapperFunc } from "./types/CreateWrapperFunc"; import { UriResolutionResult } from "../../core/types/UriResolutionResult"; @@ -105,7 +106,11 @@ export class ExtendableUriResolver implements UriResolver { const implementationsToLoad = new Queue(); for (const implementationUri of implementationUris) { - if (!cache.has(implementationUri)) { + if ( + !(await executeMaybeAsyncFunction( + cache.has.bind(cache, implementationUri) + )) + ) { implementationsToLoad.enqueue(implementationUri); } } @@ -148,7 +153,7 @@ export class ExtendableUriResolver implements UriResolver { }; } } else { - cache.set(implementationUri, wrapper); + await cache.set(implementationUri, wrapper); loadedImplementations.push(implementationUri.uri); failedAttempts = 0; }