fix schema loading race

This commit is contained in:
Joel Wetzell
2026-05-06 16:56:32 -05:00
parent 67c4df49a8
commit 998d3adce6
2 changed files with 30 additions and 18 deletions
+4 -4
View File
@@ -1,6 +1,6 @@
import { computed, effect, inject, Injectable, signal } from '@angular/core';
import { cloneDeep, isEqual } from 'lodash-es';
import { Config, ConfigError, ModuleError, RouteError } from '../models/config';
import { Config, ConfigError, ModuleConfig, ModuleError, RouteConfig, RouteError } from '../models/config';
import { SchemaService } from './schema';
import { HttpClient } from '@angular/common/http';
import { SettingsService } from './settings';
@@ -14,7 +14,7 @@ export class ConfigService {
if (config === undefined) {
return false;
}
return this.schemaService.validate(config);
return this.schemaService.validate(this.schemaService.configSchemaId, config);
});
currentlyShownConfig = signal<Config | undefined>(undefined);
runningConfig = signal<Config | undefined>(undefined);
@@ -59,7 +59,7 @@ export class ConfigService {
}
this.http.get<Config>(configUrl.toString()).subscribe({
next: (config) => {
if (this.schemaService.validate(config)) {
if (this.schemaService.validate(this.schemaService.configSchemaId, config)) {
this.updateCurrentlyShownConfig(config);
this.runningConfig.set(cloneDeep(config));
} else {
@@ -75,7 +75,7 @@ export class ConfigService {
}
uploadConfig(config: Config) {
if (this.schemaService.validate(config)) {
if (this.schemaService.validate(this.schemaService.configSchemaId,config)) {
this.updateCurrentlyShownConfig(config);
const configUrl = this.settingsService.configUrl();
if (!configUrl) {
+26 -14
View File
@@ -25,6 +25,12 @@ export class SchemaService {
routesSchema = signal<JSONSchemaType<RouteConfig[]> | undefined>(undefined);
processorsSchema = signal<JSONSchemaType<ProcessorConfig[]> | undefined>(undefined);
// TODO(jwetzell): populate from loaded schemas
configSchemaId = 'https://showbridge.io/config.schema.json';
modulesSchemaId = 'https://showbridge.io/modules.schema.json';
routesSchemaId = 'https://showbridge.io/routes.schema.json';
processorsSchemaId = 'https://showbridge.io/processors.schema.json';
schemasLoaded = computed(() => {
return (
this.configSchema() !== undefined &&
@@ -63,10 +69,7 @@ export class SchemaService {
}
break;
case 'closed':
this.ajv.removeSchema(this.configSchema()!);
this.ajv.removeSchema(this.modulesSchema()!);
this.ajv.removeSchema(this.routesSchema()!);
this.ajv.removeSchema(this.processorsSchema()!);
this.resetAjv();
this.configSchema.set(undefined);
this.modulesSchema.set(undefined);
this.routesSchema.set(undefined);
@@ -74,15 +77,13 @@ export class SchemaService {
break;
}
});
}
effect(() => {
if (this.schemasLoaded()) {
this.ajv.addSchema(this.modulesSchema()!);
this.ajv.addSchema(this.routesSchema()!);
this.ajv.addSchema(this.processorsSchema()!);
this.ajv.compile(this.configSchema()!);
}
});
resetAjv() {
this.ajv.removeSchema(this.configSchema()!);
this.ajv.removeSchema(this.modulesSchema()!);
this.ajv.removeSchema(this.routesSchema()!);
this.ajv.removeSchema(this.processorsSchema()!);
}
loadConfigSchema() {
@@ -117,9 +118,9 @@ export class SchemaService {
});
}
validate(data: any): boolean {
validate(schemaId: string, data: any): boolean {
if (this.schemasLoaded() && this.ajv) {
this.ajv.validate('https://showbridge.io/config.schema.json', data);
this.ajv.validate(schemaId, data);
if (this.ajv.errors) {
console.error('validation errors', this.ajv.errors);
const errorPaths = new Set(
@@ -196,21 +197,32 @@ export class SchemaService {
return paramsTemplate;
}
addSchemaToAjv(schema: SomeJSONSchema) {
if (this.ajv.getSchema(schema.$id!)) {
this.ajv.removeSchema(schema.$id!);
}
this.ajv.addSchema(schema);
}
setConfigSchema(schema: JSONSchemaType<Config>) {
this.addSchemaToAjv(schema);
this.configSchema.set(schema);
}
setModulesSchema(schema: JSONSchemaType<ModuleConfig[]>) {
this.addSchemaToAjv(schema);
this.modulesSchema.set(schema);
this.moduleTypes = [];
this.populateModuleTypes();
}
setRoutesSchema(schema: JSONSchemaType<RouteConfig[]>) {
this.addSchemaToAjv(schema);
this.routesSchema.set(schema);
}
setProcessorsSchema(schema: JSONSchemaType<ProcessorConfig[]>) {
this.addSchemaToAjv(schema);
this.processorsSchema.set(schema);
this.processorTypes = [];
this.populateProcessorTypes();