Files
vendoo/app/kernel/lifecycle.mjs
T
Masterluke77andGitHub 6f48827f4d Vendoo 1.41.2 – Git Ignore Boundary & Module Tracking Hotfix (#18)
* docs: prepare Vendoo 1.41.2 git-ignore boundary hotfix

* fix: track native source modules with root-anchored runtime ignores
2026-07-09 17:09:00 +02:00

50 lines
1.7 KiB
JavaScript

import { PlatformError } from './errors.mjs';
export class LifecycleManager {
#state = 'created';
#hooks = [];
register({ id, order = 100, start = async () => {}, stop = async () => {} }) {
if (!id || this.#hooks.some(hook => hook.id === id)) {
throw new PlatformError(`Ungültiger oder doppelter Lifecycle-Hook: ${id}`, { code: 'LIFECYCLE_HOOK_INVALID' });
}
this.#hooks.push({ id: String(id), order: Number(order) || 100, start, stop, state: 'registered' });
}
async start(context) {
if (!['created', 'stopped'].includes(this.#state)) throw new PlatformError(`Kernel kann aus Zustand ${this.#state} nicht starten.`, { code: 'LIFECYCLE_STATE_INVALID' });
this.#state = 'starting';
const started = [];
try {
for (const hook of [...this.#hooks].sort((a, b) => a.order - b.order)) {
hook.state = 'starting';
await hook.start(context);
hook.state = 'running';
started.push(hook);
}
this.#state = 'running';
} catch (error) {
for (const hook of started.reverse()) {
try { await hook.stop({ ...context, rollback: true }); } catch {}
hook.state = 'stopped';
}
this.#state = 'failed';
throw error;
}
}
async stop(context) {
if (!['running', 'starting'].includes(this.#state)) return;
this.#state = 'stopping';
for (const hook of [...this.#hooks].sort((a, b) => b.order - a.order)) {
if (hook.state !== 'running') continue;
try { await hook.stop(context); } finally { hook.state = 'stopped'; }
}
this.#state = 'stopped';
}
snapshot() {
return { state: this.#state, hooks: this.#hooks.map(({ start: _s, stop: _t, ...hook }) => ({ ...hook })) };
}
}