import { LocalPluginPackageActivationPublisher } from '@qinglong/local-admin/package-activation'; import { LocalPluginPackageResourceByteSource } from '@qinglong/local-admin/package-resource-materialization'; import { PluginPackageRecoveryCoordinator, type PluginPackageRecoveryCycleResult, } from '@qinglong/runtime-core/plugin-package-recovery'; import { PluginPackageAutomationPublicationCoordinator, PluginPackageAutomationPublicationRecoveryCoordinator, type PluginPackageAutomationPublicationRecoveryCycleResult, } from '@qinglong/runtime-core/plugin-package-automation-publication'; import { MAX_PLUGIN_PACKAGE_TASK_PUBLICATION_RECOVERY_PAGES, MAX_PLUGIN_PACKAGE_TASK_PUBLICATION_RECOVERY_PAGE_SIZE, PluginPackageTaskPublicationCoordinator, PluginPackageTaskPublicationRecoveryCoordinator, type PluginPackageTaskPublicationRecoveryCycleResult, } from '@qinglong/runtime-core/plugin-package-task-publication'; import { MAX_PROJECT_TOOL_SNAPSHOT_RECOVERY_PAGES, MAX_PROJECT_TOOL_SNAPSHOT_SOURCE_PAGE_SIZE, ProjectToolDefinitionSnapshotPublicationCoordinator, ProjectToolDefinitionSnapshotRecoveryCoordinator, type ProjectToolDefinitionSnapshotRecoveryCycleResult, } from '@qinglong/runtime-core/project-tool-definition-snapshot'; import { createBuiltInTaskSpecSemanticRegistry } from '@qinglong/runtime-core/task-spec-semantic'; import type { LocalApplicationEnabledBootstrapOptions } from './contract'; import type { LocalApplicationReadyStorage } from './storageActivation'; import { LocalApplicationPluginPackageAutomationPublicationRequiredError, LocalApplicationPluginPackageRecoveryRequiredError, LocalApplicationPluginPackageTaskPublicationRequiredError, LocalApplicationPluginPackageToolSnapshotRequiredError, } from './startupErrors'; export interface LocalApplicationPluginPackageStartup { readonly pluginPackageRecovery: Readonly; readonly pluginPackageTaskPublicationRecovery: Readonly; readonly pluginPackageAutomationPublicationRecovery: Readonly; readonly pluginPackageToolSnapshotRecovery: Readonly; } export async function recoverLocalApplicationPluginPackages( options: LocalApplicationEnabledBootstrapOptions, storage: LocalApplicationReadyStorage, ): Promise { const pluginPackageInstalls = await storage.pluginPackageInstalls(); const pluginPackageActivation = new LocalPluginPackageActivationPublisher({ stagingRoot: options.pluginPackages.stagingRoot, activationRoot: options.pluginPackages.activationRoot, now: options.pluginPackages.now, }); const pluginPackageRecovery = await new PluginPackageRecoveryCoordinator({ repository: pluginPackageInstalls, stageProvider: options.pluginPackages.stageProvider, publisher: pluginPackageActivation, now: options.pluginPackages.now, }).recover({ ...(options.pluginPackages.pageSize === undefined ? {} : { pageSize: options.pluginPackages.pageSize }), ...(options.pluginPackages.maxPages === undefined ? {} : { maxPages: options.pluginPackages.maxPages }), }); if (!pluginPackageRecovery.safeToAdmit) { throw new LocalApplicationPluginPackageRecoveryRequiredError( pluginPackageRecovery, ); } await options.applicationAudit({ profile: options.profile, state: 'plugin_packages_recovered', pluginPackageRecovery, }); const taskSpecSemanticRegistry = createBuiltInTaskSpecSemanticRegistry(); const pluginPackageTaskReconciliations = await storage.pluginPackageTaskReconciliations(); const pluginPackageMaterializedRevisions = await storage.pluginPackageMaterializedRevisions(); const pluginPackageSecretBindings = await storage.pluginPackageSecretBindings(); const pluginPackageTaskPublicationRecovery = await new PluginPackageTaskPublicationRecoveryCoordinator({ source: pluginPackageTaskReconciliations, publisher: new PluginPackageTaskPublicationCoordinator({ generationSource: pluginPackageActivation, lockSource: pluginPackageInstalls, byteSource: new LocalPluginPackageResourceByteSource({ stagingRoot: options.pluginPackages.stagingRoot, }), materializedRepository: pluginPackageMaterializedRevisions, secretBindingSource: pluginPackageSecretBindings, reconciliationRepository: pluginPackageTaskReconciliations, taskSpecSemanticRegistry, }), }).recover({ ...(options.pluginPackages.taskPublicationPageSize === undefined ? {} : { pageSize: options.pluginPackages.taskPublicationPageSize }), ...(options.pluginPackages.taskPublicationMaxPages === undefined ? {} : { maxPages: options.pluginPackages.taskPublicationMaxPages }), }); if (!pluginPackageTaskPublicationRecovery.safeToAdmit) { throw new LocalApplicationPluginPackageTaskPublicationRequiredError( pluginPackageTaskPublicationRecovery, ); } await options.applicationAudit({ profile: options.profile, state: 'plugin_package_tasks_published', pluginPackageRecovery, pluginPackageTaskPublicationRecovery, }); const pluginPackageAutomationPublications = await storage.pluginPackageAutomationPublications(); const pluginPackageAutomationPublicationRecovery = await new PluginPackageAutomationPublicationRecoveryCoordinator({ source: pluginPackageAutomationPublications, publisher: new PluginPackageAutomationPublicationCoordinator({ generationSource: pluginPackageActivation, materializedRepository: pluginPackageMaterializedRevisions, repository: pluginPackageAutomationPublications, taskSpecSemanticRegistry, now: options.pluginPackages.now, }), }).recover({ ...(options.pluginPackages.taskPublicationPageSize === undefined ? {} : { pageSize: options.pluginPackages.taskPublicationPageSize }), ...(options.pluginPackages.taskPublicationMaxPages === undefined ? {} : { maxPages: options.pluginPackages.taskPublicationMaxPages }), }); if (!pluginPackageAutomationPublicationRecovery.safeToAdmit) { throw new LocalApplicationPluginPackageAutomationPublicationRequiredError( pluginPackageAutomationPublicationRecovery, ); } await options.applicationAudit({ profile: options.profile, state: 'plugin_package_automations_published', pluginPackageRecovery, pluginPackageTaskPublicationRecovery, pluginPackageAutomationPublicationRecovery, }); const projectToolDefinitionSnapshots = await storage.projectToolDefinitionSnapshots(); const pluginPackageToolSnapshotRecovery = await new ProjectToolDefinitionSnapshotRecoveryCoordinator({ source: projectToolDefinitionSnapshots, publisher: new ProjectToolDefinitionSnapshotPublicationCoordinator({ source: projectToolDefinitionSnapshots, materializedRepository: pluginPackageMaterializedRevisions, repository: projectToolDefinitionSnapshots, taskSpecSemanticRegistry, pageSize: Math.min( options.pluginPackages.taskPublicationPageSize ?? (options.profile === 'edge' ? 4 : 16), MAX_PROJECT_TOOL_SNAPSHOT_SOURCE_PAGE_SIZE, ), }), }).recover({ pageSize: options.pluginPackages.taskPublicationPageSize ?? (options.profile === 'edge' ? 1 : 8), maxPages: options.pluginPackages.taskPublicationMaxPages ?? MAX_PROJECT_TOOL_SNAPSHOT_RECOVERY_PAGES, }); if (!pluginPackageToolSnapshotRecovery.safeToAdmit) { throw new LocalApplicationPluginPackageToolSnapshotRequiredError( pluginPackageToolSnapshotRecovery, ); } await options.applicationAudit({ profile: options.profile, state: 'plugin_package_tools_snapshotted', pluginPackageRecovery, pluginPackageTaskPublicationRecovery, pluginPackageAutomationPublicationRecovery, pluginPackageToolSnapshotRecovery, }); return Object.freeze({ pluginPackageRecovery, pluginPackageTaskPublicationRecovery, pluginPackageAutomationPublicationRecovery, pluginPackageToolSnapshotRecovery, }); }