Skip to content

Commit

Permalink
Breaking change: integrate state/manifest update logic.
Browse files Browse the repository at this point in the history
`Service`s now include the logic for state updates (generating
messages/highlighting car numbers) and manifest updates (deep equality
check, additional metadata) that were previously exported as
`processStateUpdate` and `processManifestUpdate`. Those two methods are
no longer needed by clients and have been removed.

Additionally, `Service`s no longer take event handlers in the
constructor; instead `Service` extends `EventEmitter`, and its events
can be subscribed to in the usual way (e.g. `serviceInstance.on(event,
handler)`). The new `Events` enumeration lists the types of events that
may be emitted.
  • Loading branch information
jamesremuscat committed Apr 14, 2023
1 parent 29776c9 commit 9eee3c3
Showing 1 changed file with 66 additions and 44 deletions.
110 changes: 66 additions & 44 deletions src/services.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import deepEqual from 'deep-equal';

import { EventEmitter } from './eventEmitter.js';
import { generateMessages } from './messages/index.js';

export const SERVICE_PROVIDERS = [];
Expand Down Expand Up @@ -29,56 +30,77 @@ export const mapServiceProvider = (source) => {
}
};

export const processStateUpdate = (oldState, updatedState) => {
const newState = { ...oldState, ...updatedState };

const newMessages = generateMessages(newState.manifest, oldState, newState).concat(
updatedState.extraMessages || []
);
export const Events = {
MANIFEST_CHANGE: 'manifestChange',
SESSION_CHANGE: 'sessionChange',
STATE_CHANGE: 'stateChange'
};

const highlight = [];
newMessages.forEach(
nm => {
if (nm.length >= 5) {
highlight.push(nm[4]);
}
}
);
newState.highlight = highlight;
export class Service extends EventEmitter {
constructor(service) {
super();
this.service = service;

newState.messages = [
...newMessages,
...(oldState?.messages || [])
].slice(0, 100);
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);

newState.lastUpdated = Date.now();
delete newState.extraMessages;
this.onManifestChange = this.onManifestChange.bind(this);
this.onSessionChange = this.onSessionChange.bind(this);
this.onStateChange = this.onStateChange.bind(this);

return newState;
};
this._prevState = {};
}

// Adds start time and UUID to the manifest, and if a deep equality check fails,
// calls `callback` with the new manifest.
export const processManifestUpdate = (oldManifest, newManifest, startTime, uuid, callback) => {
const newManifestWithStartTime = {
...newManifest,
startTime,
uuid
};

if (!deepEqual(newManifestWithStartTime, oldManifest)) {
callback(newManifestWithStartTime);
onSessionChange() {
this.service = {
...this.service,
currentSessionIndex: (this.service.currentSessionIndex || 0) + 1
};
this.emit(Events.SESSION_CHANGE, this.service.currentSessionIndex);
}
};

export class Service {
constructor(onStateChange, onManifestChange, service) {
this.onManifestChange = onManifestChange;
this.onStateChange = onStateChange;
this.service = service;
onStateChange(updatedState) {
const newState = { ...this._prevState, ...updatedState };

this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
const newMessages = generateMessages(newState.manifest, this._prevState, newState).concat(
updatedState.extraMessages || []
);

const highlight = [];
newMessages.forEach(
nm => {
if (nm.length >= 5) {
highlight.push(nm[4]);
}
}
);
newState.highlight = highlight;

newState.messages = [
...newMessages,
...(this._prevState?.messages || [])
].slice(0, 100);

newState.lastUpdated = Date.now();
delete newState.extraMessages;

this.emit(Events.STATE_CHANGE, newState);
this._prevState = newState;
}

// Adds start time and UUID to the manifest, and if a deep equality check fails,
// emits an event with the new manifest then updates our state.
onManifestChange(newManifest) {
const newManifestWithStartTime = {
...newManifest,
startTime: this.service.startTime,
uuid: this.service.uuid
};

if (!deepEqual(newManifestWithStartTime, this._prevState.manifest)) {
this.emit(Events.MANIFEST_CHANGE, newManifestWithStartTime);
this.onStateChange({ manifest: newManifestWithStartTime });
}
}

start(connectionService) {
Expand All @@ -89,8 +111,8 @@ export class Service {
}

export class HTTPPollingService extends Service {
constructor(url, pollInterval, onStateChange, onManifestChange, service) {
super(onStateChange, onManifestChange, service);
constructor(url, pollInterval, service) {
super(service);
this.url = url;
this.pollInterval = pollInterval;
this.handleResponse = this.handleResponse.bind(this);
Expand Down

0 comments on commit 9eee3c3

Please # to comment.