UNPKG

polyv-live-cli

Version:

CLI tool for managing PolyV live streaming services.

162 lines 6.31 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SceneExecutor = void 0; const variable_resolver_1 = require("./variable-resolver"); const resource_handlers_1 = require("./resource-handlers"); class SceneExecutor { constructor(_client) { this.lastExecution = { rolledBack: [] }; this.handlers = (0, resource_handlers_1.createResourceHandlers)(_client); this.resolver = new variable_resolver_1.VariableResolver(); } setProgressCallback(callback) { this.progressCallback = callback; } getLastExecution() { return this.lastExecution; } async execute(config, options = {}) { const startTime = Date.now(); this.lastExecution = { rolledBack: [] }; const order = this.getExecutionOrder(config); const outputs = {}; const created = []; const results = []; const timings = {}; try { for (let i = 0; i < order.length; i++) { const resourceId = order[i]; if (!resourceId) continue; const resource = config.resources.find(r => r.id === resourceId); if (!resource) continue; this.reportProgress({ phase: 'creating', resourceId, resourceType: resource.type, current: i + 1, total: order.length, }); const resourceStartTime = Date.now(); if (options.dryRun) { results.push({ id: resourceId, type: resource.type, output: {}, status: 'would_create', }); } else { const handler = this.handlers[resource.type]; if (!handler) { throw new Error(`Unknown resource type: ${resource.type}`); } const resolvedParams = this.resolver.resolveObject(resource.params, outputs); const output = await handler.create(resolvedParams, resource.output); outputs[resourceId] = output; created.push({ resource, output }); results.push({ id: resourceId, type: resource.type, output, status: 'created', }); this.trackCreatedResource(resourceId, output); } timings[resourceId] = Date.now() - resourceStartTime; this.reportProgress({ phase: 'created', resourceId, resourceType: resource.type, current: i + 1, total: order.length, }); } const result = { success: true, resources: results, duration: Date.now() - startTime, resourceTimings: timings, }; if (options.dryRun) { result.dryRun = true; } return result; } catch (error) { const failedAt = order[created.length] || 'unknown'; this.lastExecution.failedAt = failedAt; for (let i = created.length - 1; i >= 0; i--) { const createdItem = created[i]; if (!createdItem) continue; this.reportProgress({ phase: 'rolling_back', resourceId: createdItem.resource.id, resourceType: createdItem.resource.type, }); try { const handler = this.handlers[createdItem.resource.type]; if (handler?.rollback) { await handler.rollback(createdItem.output); } this.lastExecution.rolledBack.push(createdItem.resource.id); } catch (rollbackError) { console.error(`Rollback failed for ${createdItem.resource.id}:`, rollbackError); } this.reportProgress({ phase: 'rolled_back', resourceId: createdItem.resource.id, resourceType: createdItem.resource.type, }); } const errorMessage = error instanceof Error ? error.message : String(error); throw new Error(`Failed to create resource "${failedAt}": ${errorMessage}`); } } getExecutionOrder(config) { const resources = config.resources; const ordered = []; const visited = new Set(); const visiting = new Set(); const visit = (resource) => { if (visited.has(resource.id)) { return; } if (visiting.has(resource.id)) { throw new Error(`Circular dependency detected at resource "${resource.id}"`); } visiting.add(resource.id); if (resource.dependsOn) { const deps = Array.isArray(resource.dependsOn) ? resource.dependsOn : [resource.dependsOn]; for (const depId of deps) { const depResource = resources.find(r => r.id === depId); if (!depResource) { throw new Error(`Dependency "${depId}" not found for resource "${resource.id}"`); } visit(depResource); } } visiting.delete(resource.id); visited.add(resource.id); ordered.push(resource.id); }; for (const resource of resources) { visit(resource); } return ordered; } reportProgress(event) { if (this.progressCallback) { this.progressCallback(event); } } trackCreatedResource(_id, _output) { } } exports.SceneExecutor = SceneExecutor; //# sourceMappingURL=scene-executor.js.map