Skip to content
Merged
Show file tree
Hide file tree
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
32 changes: 32 additions & 0 deletions src/__tests__/frameworkContract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,38 @@ describe('Template method pattern', () => {
expect(liveData.length).toBe(1);
});

test('getLiveData threads its scope argument through to buildLiveData', async () => {
let received: ReadonlySet<string> | undefined | 'unset' = 'unset';

@destinationController({ category: 'Test' })
class TestScopedPark extends Destination {
constructor(options?: DestinationConstructor) {
super(options);
}

protected async buildEntityList(): Promise<Entity[]> { return []; }

protected async buildLiveData(scope?: ReadonlySet<string>): Promise<LiveData[]> {
received = scope;
return [];
}

protected async buildSchedules(): Promise<EntitySchedule[]> { return []; }
async getDestinations(): Promise<Entity[]> { return []; }
}

const park = new TestScopedPark();

// Scoped call (streaming push) — buildLiveData must receive the same set.
const scope = new Set(['ride1', 'ride2']);
await park.getLiveData(scope);
expect(received).toBe(scope);

// No-arg call (poll/REST) — buildLiveData receives undefined (full snapshot).
await park.getLiveData();
expect(received).toBeUndefined();
});

test('framework strips undefined values from live data, entities, and schedules', async () => {
// Guards against the collector's hashObject() which rejects undefined.
// Parks sometimes produce undefined via patterns like
Expand Down
15 changes: 12 additions & 3 deletions src/destination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -953,12 +953,17 @@ export abstract class Destination {
* **To provide live data, implement buildLiveData() instead.**
*
* @final This method is final and should not be overridden.
* @param scope Optional set of published entity ids to limit the build to.
* Streaming (push) destinations pass the ids whose source docs changed this
* fire so the build is emit-per-changed-entity rather than a full snapshot.
* Undefined (the default, and all poll/REST destinations) builds everything.
* Passed through to buildLiveData(); subclasses that ignore it stay full-snapshot.
* @returns {LiveData[]} List of live data for entities
*/
@trace()
async getLiveData(): Promise<LiveData[]> {
async getLiveData(scope?: ReadonlySet<string>): Promise<LiveData[]> {
await this.init();
const data = await this.buildLiveData();
const data = await this.buildLiveData(scope);
// Sanitise waitTime values — must be a finite number or null/undefined.
// Catches bugs like waitTime:"" which crash downstream integer columns.
for (const entry of data) {
Expand Down Expand Up @@ -1005,9 +1010,13 @@ export abstract class Destination {
* Subclasses should override this method to return live data (wait times,
* operating status, showtimes, etc.) for their entities.
*
* @param scope Optional set of published entity ids to limit the build to
* (see getLiveData). Streaming destinations may honour it to build only the
* changed entities; an override that ignores it returns the full snapshot.
* @returns {LiveData[]} List of live data for entities
*/
protected async buildLiveData(): Promise<LiveData[]> {
protected async buildLiveData(scope?: ReadonlySet<string>): Promise<LiveData[]> {
void scope;
throw new Error("buildLiveData not implemented.");
}

Expand Down
Loading