Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 33 additions & 7 deletions packages/host/tests/helpers/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ interface TestAdapterContents {
}

let shimmedModuleIndicator = '// this file is shimmed';
let sharedCardApiModule: CardAPI | undefined;
let sharedCardApiImport: Promise<CardAPI> | undefined;

export class TestRealmAdapter implements RealmAdapter {
#files: Dir = { kind: 'directory', contents: {} };
Expand Down Expand Up @@ -142,10 +144,7 @@ export class TestRealmAdapter implements RealmAdapter {
if (!this.#loader) {
throw new Error('bug: loader needs to be set in test adapter');
}

let cardApi = await this.#loader.import<CardAPI>(
`${baseRealm.url}card-api`,
);
let cardApi = await getSharedCardApi(this.#loader);
for (let { content, url } of this.#potentialModulesAndInstances) {
if (cardApi.isCard(content)) {
cardApi.setCardAsSavedForTest(
Expand All @@ -167,6 +166,9 @@ export class TestRealmAdapter implements RealmAdapter {
setLoader(loader: Loader) {
// Should remove this once CS-6720 is finished
this.#loader = loader;
if (sharedCardApiModule) {
shimSharedCardApi(loader, sharedCardApiModule);
}
this.prepareInstances();
}

Expand Down Expand Up @@ -258,9 +260,7 @@ export class TestRealmAdapter implements RealmAdapter {
if (value instanceof Uint8Array) {
fileRefContent = value;
} else if (path.endsWith('.json')) {
let cardApi = await this.#loader.import<CardAPI>(
`${baseRealm.url}card-api`,
);
let cardApi = await getSharedCardApi(this.#loader);
if (cardApi.isCard(value)) {
let doc = cardApi.serializeCard(value);
fileRefContent = JSON.stringify(doc);
Expand Down Expand Up @@ -459,3 +459,29 @@ export class TestRealmAdapter implements RealmAdapter {
};
}
}

async function getSharedCardApi(loader: Loader): Promise<CardAPI> {
if (sharedCardApiModule) {
shimSharedCardApi(loader, sharedCardApiModule);
return sharedCardApiModule;
}
Comment on lines +464 to +467

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep card-api module loader-scoped

Returning a previously imported sharedCardApiModule for every new Loader makes later adapters execute card-api code with the first loader's import.meta.loader, because card-api closes over that value (myLoader() in packages/base/card-api.gts) and uses it for runtime imports (for example in createFromSerialized / override loading). In multi-realm tests, this can resolve modules through the wrong loader and miss per-loader shims established in prepareInstances, leading to incorrect or failed card deserialization in subsequent adapters.

Useful? React with 👍 / 👎.

if (!sharedCardApiImport) {
sharedCardApiImport = loader
.import<CardAPI>(`${baseRealm.url}card-api`)
.then((cardApi) => {
sharedCardApiModule = cardApi;
return cardApi;
})
.catch((error) => {
sharedCardApiImport = undefined;
throw error;
});
}
let cardApi = await sharedCardApiImport;
shimSharedCardApi(loader, cardApi);
return cardApi;
}

function shimSharedCardApi(loader: Loader, cardApi: CardAPI): void {
loader.shimModule(`${baseRealm.url}card-api`, cardApi as Record<string, any>);
}
Loading