/** * This file is part of the NocoBase (R) project. * Copyright (c) 2020-2024 NocoBase Co., Ltd. * Authors: NocoBase Team. * * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. * For more information, please refer to: https://www.nocobase.com/agreement. */ /// /// import { IDatabaseOptions, Transaction, Transactionable } from '@nocobase/database'; import type Application from '../application'; import type { AppSupervisor } from './index'; import type { IncomingMessage, ServerResponse } from 'http'; /** * Options accepted by discovery adapter when loading an application. */ export type GetAppOptions = { withOutBootStrap?: boolean; [key: string]: any; }; /** * Parameters supplied to a bootstrapper when a sub-application is being started. */ export type BootOptions = { appName: string; options: Record; appSupervisor: AppSupervisor; }; /** * Callback used by process adapters to lazily initialize applications. */ export type AppBootstrapper = (bootOptions: BootOptions) => Promise; /** * All supported lifecycle states of a managed application. */ export type AppStatus = 'preparing' | 'initializing' | 'initialized' | 'running' | 'commanding' | 'stopped' | 'error' | 'not_found'; /** * Metadata representing a deployable environment (container, pod, VM, etc.). */ export type EnvironmentInfo = { name: string; url?: string; proxyUrl?: string; available?: boolean; appVersion?: string; lastHeartbeatAt?: number; }; export type BootstrapLock = { acquire: () => Promise; release: () => Promise; }; export type AppModelOptions = { dbConnType?: 'new_database' | 'new_connection' | 'new_schema' | string; database?: IDatabaseOptions; [key: string]: any; }; export type AppModel = { name: string; cname?: string; environment?: string; environments?: string[]; options: AppModelOptions; }; export type ProcessCommand = { requestId: string; appName: string; action: 'create' | 'start' | 'stop' | 'remove' | string; environments: string[]; payload?: Record; }; export type AppDbCreatorOptions = Transactionable & { app: Application; appOptions: AppModelOptions; }; export type AppDbCreator = (options: AppDbCreatorOptions) => Promise; export type AppOptionsFactory = (appName: string, mainApp: Application, options?: AppModelOptions) => any; /** * Abstraction for discovering applications across deployment environments. */ export type AppStatusesResult = Record | null>; export interface AppDiscoveryAdapter { readonly name: string; readonly environmentName?: string; readonly environmentUrl?: string; readonly environmentProxyUrl?: string; readonly appStatus?: Record; readonly lastSeenAt?: Map; /** * Update the "last seen at" timestamp for an application. */ setAppLastSeenAt(appName: string): void | Promise; getAppLastSeenAt(appName: string): number | null | Promise; /** * Read the cached lifecycle status for a given application. */ getAppStatus(appName: string, defaultStatus?: AppStatus): Promise | AppStatus | null; /** * Persist an application's lifecycle status back to the discovery backend. */ setAppStatus(appName: string, status: AppStatus, options?: Record): void | Promise; clearAppStatus?(appName: string): void | Promise; loadAppModels?(mainApp: Application): Promise; getAppsStatuses?(appNames?: string[]): Promise | AppStatusesResult; addAutoStartApps?(environmentName: string, appName: string[]): Promise; getAutoStartApps?(environmentName: string): Promise; removeAutoStartApps?(environmentName: string, appNames: string[]): Promise; addAppModel?(appModel: AppModel): Promise; getAppModel?(appName: string): Promise; removeAppModel?(appName: string): Promise; getAppNameByCName?(cname: string): Promise; registerEnvironment?(environment: EnvironmentInfo): Promise; unregisterEnvironment?(): Promise; listEnvironments?(): Promise; getEnvironment?(environmentName: string): Promise; heartbeatEnvironment?(): Promise; getBootstrapLock?(appName: string): Promise | BootstrapLock | null; proxyWeb?(appName: string, req: IncomingMessage, res: ServerResponse): Promise; proxyWs?(req: IncomingMessage, socket: any, head: Buffer): Promise; dispose?(): Promise; } export interface AppProcessAdapter { readonly name: string; readonly apps?: Record; readonly appErrors?: Record; readonly lastMaintainingMessage?: Record; readonly statusBeforeCommanding?: Record; addApp(app: Application): void; getApp(appName: string, options?: GetAppOptions): Promise; hasApp(appName: string): boolean; bootstrapApp(appName: string): Promise; getApps?(): Application[]; createApp?(options: { appModel: AppModel; mainApp?: Application; transaction?: Transaction; }, context?: { requestId: string; }): Promise; startApp?(appName: string, context?: { requestId: string; }): Promise; stopApp?(appName: string, context?: { requestId: string; }): Promise; removeApp?(appName: string, context?: { requestId: string; }): Promise; upgradeApp?(appName: string, context?: { requestId: string; }): Promise; removeAllApps?(): Promise; setAppError?(appName: string, error: Error): void; hasAppError?(appName: string): boolean; clearAppError?(appName: string): void; } export interface AppCommandAdapter { dispatchCommand(command: ProcessCommand): Promise; registerCommandHandler(mainApp: Application): void; dispose?(): Promise; }