import { IElementParams, IGlobalObject, IElementContext } from "./types"; import { IPartialObserver } from "./types/subscriptions"; import { createProcessor } from "."; import { Processor } from "./Processor"; import { tick } from "./execute/tick"; import { applyEvent } from "./execute/applyEvent"; export interface ISubscriptionConfig { params: IElementParams; observer?: IPartialObserver; globalObject: IGlobalObject; contexts?: IElementContext[]; } export class Subscription { protected isClosed = false; protected processor: Processor; constructor(protected config: ISubscriptionConfig) { this.processor = createProcessor(this.config.params); this.run(); } unsubscribe() { this.isClosed = true; } protected async run() { const processor = this.processor; const observer = this.config.observer; const rootElementId = processor.getRootElementId(); const error = observer && observer.error; const callbacksManager = processor.locator.callbacksManager; const rootElementState = processor.getElementStateById(rootElementId); rootElementState.contexts = this.config.contexts ? [...this.config.contexts] : []; rootElementState.observer = { next: observer && observer.next ? callbacksManager.addCallback(observer.next)[0] : undefined, error: error ? callbacksManager.addCallback(error)[0] : undefined, complete: observer && observer.complete ? callbacksManager.addCallback(observer.complete)[0] : undefined, }; let nextElementId = rootElementId; while (!this.isClosed) { tick(nextElementId, this.config.globalObject, this.processor); let isNeedRestart = false; do { const event = await processor.locator.eventsManager.next(); isNeedRestart = applyEvent(processor, event); nextElementId = event.elementId; } while (!isNeedRestart); } } }