UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

160 lines 5.71 kB
export class RuntimeIntegrityError extends Error { findings; constructor(findings) { super(formatRuntimeIntegrityFailure(findings)); this.name = "RuntimeIntegrityError"; this.findings = findings; } } export function defineRuntimeManifest(input) { return { listeners: input.listeners ?? [], schedules: input.schedules ?? [], tasks: input.tasks ?? [], outbox: { events: input.outbox?.events ?? [], jobs: input.outbox?.jobs ?? [], }, }; } export function defineRuntimeRegistries(input) { return { listeners: input.listeners ?? [], schedules: input.schedules ?? [], tasks: input.tasks ?? [], outbox: input.outbox, }; } export function inspectRuntimeIntegrity(manifest, registries) { const configs = [ { artifact: "listener", label: "listener", manifestNames: namesFromDefinitions(manifest.listeners), registryNames: namesFromDefinitions(registries.listeners), missingCode: "missing_listener_registration", registryDescription: "runtime registries.listeners", }, { artifact: "schedule", label: "schedule", manifestNames: namesFromDefinitions(manifest.schedules), registryNames: namesFromDefinitions(registries.schedules), missingCode: "missing_schedule_registration", registryDescription: "runtime registries.schedules", }, { artifact: "task", label: "task", manifestNames: namesFromDefinitions(manifest.tasks), registryNames: namesFromDefinitions(registries.tasks), missingCode: "missing_task_registration", registryDescription: "runtime registries.tasks", }, { artifact: "outboxEvent", label: "outbox event", manifestNames: namesFromDefinitions(manifest.outbox.events), registryNames: namesFromMap(registries.outbox?.events), missingCode: "missing_outbox_event_registration", registryDescription: "runtime registries.outbox.events", }, { artifact: "outboxJob", label: "outbox job", manifestNames: namesFromDefinitions(manifest.outbox.jobs), registryNames: namesFromMap(registries.outbox?.jobs), missingCode: "missing_outbox_job_registration", registryDescription: "runtime registries.outbox.jobs", }, ]; const findings = configs.flatMap((config) => inspectArtifactIntegrity(config)); return { ok: findings.length === 0, findings, }; } export function createRuntimeIntegrity(options) { const mode = options.mode ?? "error"; const logger = options.logger ?? console; return { kind: "runtime-integrity", check() { const result = inspectRuntimeIntegrity(options.manifest, options.registries); if (result.ok) return result; if (mode === "warn") { logger.warn(`[beignet] ${formatRuntimeIntegrityFailure(result.findings)}`); return result; } throw new RuntimeIntegrityError(result.findings); }, }; } export function runRuntimeIntegrityCheck(check) { return check?.check(); } function inspectArtifactIntegrity(config) { const findings = []; const manifestDuplicates = duplicateNames(config.manifestNames); const registryDuplicates = duplicateNames(config.registryNames); for (const name of manifestDuplicates) { findings.push({ code: "duplicate_runtime_manifest_entry", artifact: config.artifact, name, location: "manifest", message: `Duplicate ${config.label} "${name}" in runtime manifest.`, }); } for (const name of registryDuplicates) { findings.push({ code: "duplicate_runtime_registry_entry", artifact: config.artifact, name, location: "registry", message: `Duplicate ${config.label} "${name}" in ${config.registryDescription}.`, }); } const registryNameSet = new Set(config.registryNames); for (const name of uniqueNames(config.manifestNames)) { if (registryNameSet.has(name)) continue; findings.push({ code: config.missingCode, artifact: config.artifact, name, message: `Missing ${config.label} registration "${name}": declared in runtime manifest but not present in ${config.registryDescription}.`, }); } return findings; } function namesFromDefinitions(definitions) { return (definitions ?? []).map((definition) => definition.name); } function namesFromMap(definitions) { return [...(definitions?.keys() ?? [])]; } function duplicateNames(names) { const seen = new Set(); const duplicates = new Set(); for (const name of names) { if (seen.has(name)) { duplicates.add(name); continue; } seen.add(name); } return [...duplicates].sort(); } function uniqueNames(names) { return [...new Set(names)].sort(); } function formatRuntimeIntegrityFailure(findings) { const summary = `Runtime integrity check failed with ${findings.length} finding${findings.length === 1 ? "" : "s"}.`; const details = findings .map((finding) => `- [${finding.code}] ${finding.message}`) .join("\n"); return `${summary}\n${details}`; } //# sourceMappingURL=runtime-integrity.js.map