import { Dispatch } from "./program"; export class Services { private readonly dispatch: Dispatch; private readonly services: Array>; private readonly env: Record; constructor(dispatch: Dispatch, env: Record) { this.dispatch = dispatch; this.services = []; this.env = env; } public handleRequests(requests: ReadonlyArray>) { for (const request of requests) { const service = this.service(request.service); service.handleRequest(request.request); } } public updateSubscriptions(subscriptions: ReadonlyArray>) { // Ensure all services are setup for (const subscription of subscriptions) { this.service(subscription.service); } // For each service update their subscriptions for (const service of this.services) { service.updateSubscriptions(subscriptions .filter((subscription) => subscription.service === service.constructor) .map((subscription) => subscription.subscription)); } } private service(Type: ServiceClass): Service { for (const s of this.services) { if (s.constructor === Type) { return s; } } const env = Type.id !== undefined ? this.env[Type.id] : {}; const service = new Type(this.dispatch, env); this.services.push(service); return service; } } /** Types */ export interface Service { handleRequest(request: ServiceReq): void; updateSubscriptions(subscriptions: ReadonlyArray): void; } export interface Req { service: ServiceClass; request: ServiceReq; } export interface Sub { service: ServiceClass; subscription: ServiceSub; } export interface ServiceClass { readonly id?: string; new(dispatch: Dispatch, env: any): Service; }