diff --git a/packages/host/app/resources/card-resource.ts b/packages/host/app/resources/card-resource.ts index ec51c7f4ce..b3d2873412 100644 --- a/packages/host/app/resources/card-resource.ts +++ b/packages/host/app/resources/card-resource.ts @@ -220,6 +220,14 @@ export class CardResource extends Resource { }, ); + 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; @@ -288,14 +296,7 @@ export class CardResource extends Resource { // 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); } diff --git a/packages/host/tests/acceptance/code-submode-test.ts b/packages/host/tests/acceptance/code-submode-test.ts index 0e180eb819..8a4a1b4464 100644 --- a/packages/host/tests/acceptance/code-submode-test.ts +++ b/packages/host/tests/acceptance/code-submode-test.ts @@ -1626,6 +1626,100 @@ module('Acceptance | code submode tests', function (_hooks) { .includesText('FadhlanXXX'); }); + test('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 { + + }; + }; + `; + 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('card preview live updates with error', async function (assert) { let expectedEvents = [ {