actual/packages/loot-core/src/server/app.js
Tom French dc53a74459
Separate external, monorepo and internal imports (#237)
* style: enforce ordering of imports

* style: sort imports in loot-core

* style: sort imports in desktop-client

* style: sort imports in loot-design

* style: manual fixes
2022-09-02 12:43:37 +01:00

72 lines
1.6 KiB
JavaScript

import mitt from 'mitt';
import { captureException } from '../platform/exceptions';
// This is a simple helper abstraction for defining methods exposed to
// the client. It doesn't do much, but checks for naming conflicts and
// makes it cleaner to combine methods. We call a group of related
// methods an "app".
class App {
constructor() {
this.handlers = {};
this.services = [];
this.events = mitt();
this.unlistenServices = [];
}
method(name, func) {
if (this.handlers[name] != null) {
throw new Error(
'Conflicting method name, names must be globally unique: ' + name
);
}
this.handlers[name] = func;
}
service(func) {
this.services.push(func);
}
combine(...apps) {
for (let app of apps) {
Object.keys(app.handlers).forEach(name => {
this.method(name, app.handlers[name]);
});
app.services.forEach(service => {
this.service(service);
});
for (let [name, listeners] of app.events.all.entries()) {
for (let listener of listeners) {
this.events.on(name, listener);
}
}
}
}
startServices() {
if (this.unlistenServices.length > 0) {
captureException(
new Error(
'App: startServices called while services are already running'
)
);
}
this.unlistenServices = this.services.map(service => service());
}
stopServices() {
this.unlistenServices.forEach(unlisten => {
if (unlisten) {
unlisten();
}
});
this.unlistenServices = [];
}
}
export function createApp() {
return new App();
}