/**
* 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;
}