Warning, /firebird/packages/firebird-ng/api/src/lib/batch-status.service.ts is written in an unsupported language. File is not indexed.
0001 /**
0002 * Publishes display readiness to `window.firebird` for batch tools:
0003 * `pyrobird screenshot` and other headless drivers await these flags
0004 * instead of sleeping a fixed time and racing the geometry load.
0005 *
0006 * window.firebird = {
0007 * geometryReady: geometry finished loading (or none is pending),
0008 * startupCommandsDone: the startup command queue ran to completion,
0009 * pendingLoads: number of in-flight geometry/event loads,
0010 * ready: everything above settled — safe to capture,
0011 * errors: messages of the loads and startup commands that
0012 * failed, oldest first; empty when nothing failed.
0013 * }
0014 *
0015 * A failed load still settles: `ready` turns true once nothing is pending,
0016 * and `errors` tells the batch tool the capture shows a failed state.
0017 */
0018
0019 import { Injectable, computed, effect, inject, signal } from '@angular/core';
0020 import { CommandBusService } from '@dexvis/app-features';
0021
0022 declare global {
0023 interface Window {
0024 firebird?: {
0025 geometryReady: boolean;
0026 startupCommandsDone: boolean;
0027 pendingLoads: number;
0028 ready: boolean;
0029 errors: string[];
0030 };
0031 }
0032 }
0033
0034 @Injectable({ providedIn: 'root' })
0035 export class BatchStatusService {
0036 private commandBus = inject(CommandBusService);
0037
0038 private pendingGeometry = signal(0);
0039 private pendingEvents = signal(0);
0040 private geometryLoadedOnce = signal(false);
0041
0042 /** Messages of failed loads and startup commands, oldest first. */
0043 readonly errors = signal<readonly string[]>([]);
0044
0045 readonly geometryReady = computed(() =>
0046 this.pendingGeometry() === 0 && (this.geometryLoadedOnce() || this.commandBus.startupCommandsDone()));
0047
0048 readonly ready = computed(() =>
0049 this.commandBus.startupCommandsDone()
0050 && this.pendingGeometry() === 0
0051 && this.pendingEvents() === 0);
0052
0053 constructor() {
0054 effect(() => {
0055 window.firebird = {
0056 geometryReady: this.geometryReady(),
0057 startupCommandsDone: this.commandBus.startupCommandsDone(),
0058 pendingLoads: this.pendingGeometry() + this.pendingEvents(),
0059 ready: this.ready(),
0060 errors: [...this.errors()],
0061 };
0062 });
0063 }
0064
0065 beginGeometryLoad(): void {
0066 this.pendingGeometry.update(n => n + 1);
0067 }
0068
0069 endGeometryLoad(success: boolean): void {
0070 this.pendingGeometry.update(n => Math.max(0, n - 1));
0071 if (success) {
0072 this.geometryLoadedOnce.set(true);
0073 }
0074 }
0075
0076 beginEventLoad(): void {
0077 this.pendingEvents.update(n => n + 1);
0078 }
0079
0080 endEventLoad(): void {
0081 this.pendingEvents.update(n => Math.max(0, n - 1));
0082 }
0083
0084 /** Records a failure for batch tools (`window.firebird.errors`). */
0085 addError(message: string): void {
0086 this.errors.update(errors => [...errors, message]);
0087 }
0088 }