/
mentoster
/
vk-stilus
Обзор
Документация
Войти
/
mentoster
/
vk-stilus
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
3
CI/CD
Аналитика
Безопасность
master
src/background/background-runtime-controller.ts
82 строки
4 KB
mentoster
feat(diagnostics): complete local support runtime
26 июл 2026, 17:45
26 июл 2026, 17:45
cf7bdcd
Код
Авторство
О чём код?
import { verifyInvariant } from '../core/invariant.js'; import { err } from '../core/result.js'; import type { BackgroundResult } from './background-types.js'; import type { DiagnosticController } from './diagnostic-controller.js'; import type { ExtensionController } from './extension-controller.js'; const RUNTIME_CONTEXT = Object.freeze({ owner: 'BackgroundRuntimeController' }); /** @assertion-exception Diagnostics hydration completion is non-authoritative to product startup. */ function consumeHydration(): void {} /** * @classdesc Owns extension behavior and diagnostics as one background lifecycle boundary. * @responsibility Keep diagnostics registered without startup I/O and dispose both background owners. * @nonresponsibility Implement extension behavior, diagnostic protocol, storage, or browser API adapters. * @trustBoundary Delegates all untrusted input validation to the owned checked controllers. * @lifecycle Construct with registered diagnostics -> initialize extension -> dispose extension and diagnostics. * @invariant Both owned controllers remain stable for the lifetime of this wrapper. * @resourceBudget Inherits four product listeners plus one diagnostics runtime-message listener. * @sideEffects Delegates initialization/disposal to the two owned controllers. */ export class BackgroundRuntimeController { readonly extension: ExtensionController; readonly diagnostics: DiagnosticController; constructor(options: Readonly<{ extension: ExtensionController; diagnostics: DiagnosticController; }>) { this.extension = options.extension; this.diagnostics = options.diagnostics; const extensionStable = verifyInvariant( this.extension === options.extension, 'background-runtime.construct.extension', RUNTIME_CONTEXT, ); const diagnosticsStable = verifyInvariant( this.diagnostics === options.diagnostics, 'background-runtime.construct.diagnostics', RUNTIME_CONTEXT, ); if (!extensionStable.ok || !diagnosticsStable.ok) { throw new TypeError('BackgroundRuntimeController unavailable'); } } /** @assertion-exception Product result remains authoritative while diagnostics ownership follows its action listener state. */ async initialize() { const initialized = await this.extension.initialize(); if (initialized.ok) { this.diagnostics.disableFailureActionFallback(); void this.diagnostics.ensureHydrated().then(consumeHydration, consumeHydration); return initialized; } const actionReleased = verifyInvariant( this.extension.actionDisposer === null, 'background-runtime.failure.action-released', RUNTIME_CONTEXT, ); if (actionReleased.ok) await this.diagnostics.enableFailureActionFallback(); return initialized; } async dispose(): Promise<BackgroundResult<Readonly<{ state: 'disposed' }>>> { const extension = await this.extension.dispose(); const diagnostics = this.diagnostics.dispose(); if (!extension.ok) return extension; const diagnosticsRegistered = this.diagnostics.snapshot().registered; const extensionDisposed = verifyInvariant( extension.value.state === 'disposed', 'background-runtime.dispose.extension', RUNTIME_CONTEXT, ); const diagnosticsReleased = verifyInvariant( diagnostics.ok && !diagnosticsRegistered, 'background-runtime.dispose.diagnostics', RUNTIME_CONTEXT, ); if (!extensionDisposed.ok) return err(extensionDisposed.error); return diagnosticsReleased.ok ? extension : err(diagnosticsReleased.error); } }