Skip to content

Commit

Permalink
Merge pull request #2114 from cardstack/cs-7950-preview-live-update-w…
Browse files Browse the repository at this point in the history
…hen-module-changes

Fix bug where card preview does not live update when there are changes in module
  • Loading branch information
lukemelia authored Feb 4, 2025
2 parents 3c6ff53 + 94d8b4a commit 28a5621
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 8 deletions.
17 changes: 9 additions & 8 deletions packages/host/app/resources/card-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,14 @@ export class CardResource extends Resource<Args> {
},
);

private reloadLiveModel = restartableTask(async (url: string) => {
let subscribers = liveCardIdentityContext.subscribers(url);
liveCardIdentityContext.delete(url);
let cardOrError = await this.getCard(url);
await this.updateCardInstance(cardOrError);
liveCardIdentityContext.update(url, this._card, subscribers);
});

private subscribeToRealm(cardOrId: CardDef | string) {
let card: CardDef | undefined;
let id: string;
Expand Down Expand Up @@ -288,14 +296,7 @@ export class CardResource extends Resource<Args> {
// code before re-running the card as well as clear out the
// identity context as the card has a new implementation
this.resetLoader();
let subscribers = liveCardIdentityContext.subscribers(card.id);
liveCardIdentityContext.delete(card.id);
this.loadStaticModel.perform(card.id);
liveCardIdentityContext.update(
card.id,
this._card,
subscribers,
);
this.reloadLiveModel.perform(card.id);
} else {
this.reload.perform(card);
}
Expand Down
94 changes: 94 additions & 0 deletions packages/host/tests/acceptance/code-submode-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1626,6 +1626,100 @@ module('Acceptance | code submode tests', function (_hooks) {
.includesText('FadhlanXXX');
});

test<TestContextWithSSE>('card preview live updates when there is a change in module', async function (assert) {
const personGts = `
import { contains, containsMany, field, linksTo, linksToMany, CardDef, Component } from "https://cardstack.com/base/card-api";
import StringCard from "https://cardstack.com/base/string";
import { Friend } from './friend';
import { Pet } from "./pet";
import { Address } from './address';
import { Trips } from './trips';
export class Person extends CardDef {
static displayName = 'Person';
@field firstName = contains(StringCard);
@field lastName = contains(StringCard);
@field title = contains(StringCard, {
computeVia: function (this: Person) {
return [this.firstName, this.lastName].filter(Boolean).join(' ');
},
});
@field pet = linksTo(Pet);
@field friends = linksToMany(Friend);
@field address = containsMany(StringCard);
@field addressDetail = contains(Address);
@field trips = contains(Trips);
static isolated = class Isolated extends Component<typeof this> {
<template>
<div data-test-person>
Hello <@fields.firstName />
</div>
<style scoped>
div {
color: blue;
}
</style>
</template>
};
};
`;
const getElementColor = (selector: string) => {
let element = document.querySelector(selector);
if (!element) {
return;
}
return window.getComputedStyle(element).color;
};
let expectedEvents = [
{
type: 'index',
data: {
type: 'incremental-index-initiation',
realmURL: testRealmURL,
updatedFile: `${testRealmURL}person.gts`,
},
},
{
type: 'index',
data: {
type: 'incremental',
invalidations: [`${testRealmURL}person.gts`],
},
},
];
await visitOperatorMode({
stacks: [],
submode: 'code',
codePath: `${testRealmURL}Person/1.json`,
});
await waitFor('[data-test-card-resource-loaded]');
assert.dom('[data-test-person]').containsText('First name: Hassan');
assert.strictEqual(
getElementColor('[data-test-person]'),
'rgb(0, 128, 0)',
);

await this.expectEvents({
assert,
realm,
expectedEvents,
callback: async () => await realm.write('person.gts', personGts),
});
assert.dom('[data-test-person]').includesText('Hello Hassan');
assert.strictEqual(
getElementColor('[data-test-person]'),
'rgb(0, 0, 255)',
);

await click('[data-test-file-browser-toggle]');
await click('[data-test-file="Person/1.json"]');
assert.dom('[data-test-person]').includesText('Hello Hassan');
assert.strictEqual(
getElementColor('[data-test-person]'),
'rgb(0, 0, 255)',
);
});

test<TestContextWithSSE>('card preview live updates with error', async function (assert) {
let expectedEvents = [
{
Expand Down

0 comments on commit 28a5621

Please sign in to comment.