@aalis/runtime 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,13 @@
1
- import { appendFile, mkdir, writeFile } from 'node:fs/promises';
2
- import { dirname } from 'node:path';
3
- import { LogHub } from '@aalis/core';
1
+ import { appendFile, mkdir, rename, writeFile } from 'node:fs/promises';
2
+ import { dirname, extname } from 'node:path';
3
+ import { DefaultLogger, LogHub } from '@aalis/core';
4
4
  import { formatLogLine } from '@aalis/schema-log';
5
5
  import { getBootstrapBuffer } from './bootstrap-buffer.js';
6
6
  /** 默认日志文件路径。webui-server 等下游目前各自硬编码同一相对路径。 */
7
7
  export const DEFAULT_LOG_FILE = 'data/latest.log';
8
8
  const RUNTIME_SCOPE = 'aalis:runtime';
9
+ /** 启动时保留的上几轮日志份数:latest.1.log(上一轮)到 latest.5.log,更早的被挤掉。 */
10
+ const LOG_HISTORY_COUNT = 5;
9
11
  function formatUnknownError(err) {
10
12
  if (err instanceof Error)
11
13
  return err.stack || err.message;
@@ -21,9 +23,41 @@ export async function appendCrashLog(label, err, logFile = DEFAULT_LOG_FILE) {
21
23
  message: `${label}: ${formatUnknownError(err)}`,
22
24
  }));
23
25
  }
26
+ /** 第 n 份历史日志的路径,编号插在扩展名前:data/latest.log → data/latest.1.log。 */
27
+ function historyPath(logFile, n) {
28
+ const ext = extname(logFile);
29
+ return `${logFile.slice(0, logFile.length - ext.length)}.${n}${ext}`;
30
+ }
31
+ /**
32
+ * 各份日志后移一位:latest.4.log → latest.5.log(原 latest.5.log 被覆盖)……latest.log → latest.1.log。
33
+ * 从旧往新挪,缺号跳过;某一步失败即停并抛出,此时除了本就该挤掉的最旧一份,没有文件被覆盖。
34
+ */
35
+ async function rotateLogs(logFile) {
36
+ for (let n = LOG_HISTORY_COUNT; n >= 1; n--) {
37
+ try {
38
+ await rename(n === 1 ? logFile : historyPath(logFile, n - 1), historyPath(logFile, n));
39
+ }
40
+ catch (err) {
41
+ if (err.code !== 'ENOENT')
42
+ throw err;
43
+ }
44
+ }
45
+ }
46
+ /**
47
+ * 装文件日志:先把上一轮的日志改名保留(见 rotateLogs),再把启动期日志写入新的 logFile,之后实时追加。
48
+ * 轮转失败不拦启动:照旧覆盖写 logFile,并记一条告警写明原因。不接在原内容后面写:一个文件只装一轮,
49
+ * seq 从 0 起随文件位置单调递增,webui 的历史分页与 CLI 的启动恢复都以此为前提。
50
+ */
24
51
  export async function setupFileLogger(logFile = DEFAULT_LOG_FILE) {
25
52
  let queue = Promise.resolve();
26
53
  await mkdir(dirname(logFile), { recursive: true });
54
+ let rotateError;
55
+ try {
56
+ await rotateLogs(logFile);
57
+ }
58
+ catch (err) {
59
+ rotateError = err instanceof Error ? err.message : String(err);
60
+ }
27
61
  const hub = LogHub.default;
28
62
  // 启动期 entries 由 bootstrap-buffer 持有;作为文件初始内容写入。
29
63
  const initial = getBootstrapBuffer().snapshot().map(formatLogLine).join('');
@@ -31,6 +65,10 @@ export async function setupFileLogger(logFile = DEFAULT_LOG_FILE) {
31
65
  const off = hub.onEntry(entry => {
32
66
  queue = queue.then(() => appendFile(logFile, formatLogLine(entry))).catch(() => { });
33
67
  });
68
+ // 订阅之后再记:告警经 LogHub 同时进控制台与本文件。
69
+ if (rotateError !== undefined) {
70
+ new DefaultLogger(RUNTIME_SCOPE).warn(`上一轮的日志没能改名保留(${rotateError}),本轮已覆盖写入 ${logFile}`);
71
+ }
34
72
  const flush = async () => {
35
73
  await queue.catch(() => { });
36
74
  };
@@ -1 +1 @@
1
- {"version":3,"file":"file-logger.js","sourceRoot":"","sources":["../src/file-logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,8CAA8C;AAC9C,MAAM,CAAC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AAElD,MAAM,aAAa,GAAG,eAAe,CAAC;AAWtC,SAAS,kBAAkB,CAAC,GAAY;IACtC,IAAI,GAAG,YAAY,KAAK;QAAE,OAAO,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC;IAC1D,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,GAAY,EAAE,OAAO,GAAG,gBAAgB;IAC1F,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,MAAM,UAAU,CACd,OAAO,EACP,aAAa,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE;QAC9B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,OAAO;QACd,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,GAAG,KAAK,KAAK,kBAAkB,CAAC,GAAG,CAAC,EAAE;KAChD,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAO,GAAG,gBAAgB;IAC9D,IAAI,KAAK,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAE7C,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;IAC3B,gDAAgD;IAChD,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAElC,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QAC9B,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,KAAK,IAAmB,EAAE;QACtC,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC;IAEF,OAAO;QACL,KAAK;QACL,KAAK,CAAC,OAAO;YACX,MAAM,KAAK,EAAE,CAAC;YACd,GAAG,EAAE,CAAC;QACR,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"file-logger.js","sourceRoot":"","sources":["../src/file-logger.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
1
  export { getBootstrapBuffer, installBootstrapBuffer } from './bootstrap-buffer.js';
2
- export { type ConfigSyncOptions, handleConfigChanged, installConfigHotReload, syncPluginDefaults, } from './config-sync.js';
2
+ export { type ConfigProvider, type ConfigStore, createConfigStore, installHostConfig } from './config-store.js';
3
+ export { type ConfigSyncOptions, handleConfigChanged, installConfigHotReload, syncPluginDefaults, withPluginConfigSync, } from './config-sync.js';
3
4
  export { type ConsoleSinkHandle, installConsoleSink } from './console-sink.js';
4
5
  export { appendCrashLog, DEFAULT_LOG_FILE, type FileLoggerHandle, setupFileLogger } from './file-logger.js';
5
6
  export { createNodeModulesPluginLoader } from './node-modules-loader.js';
7
+ export { createPluginDiscovery, type PluginDescriptor, type PluginDiscovery, type PluginLoader, } from './plugin-discovery.js';
6
8
  export { buildRespawnCommand, createFsPluginLoader, createFsYamlConfigProvider, createProcessRespawnStrategy, isRestartRollback, READY_MESSAGE, type RespawnOptions, type RestartRollback, } from './providers.js';
7
9
  export { type StartAalisOptions, startAalis } from './start.js';
8
10
  export { tryDispatchSubcommand } from './subcommand.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EACL,KAAK,iBAAiB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,4BAA4B,EAC5B,iBAAiB,EACjB,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAChH,OAAO,EACL,KAAK,iBAAiB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EACL,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,4BAA4B,EAC5B,iBAAiB,EACjB,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,eAAe,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -4,14 +4,19 @@
4
4
  // (日志 sink / 终端复原 / 子命令分发)。core 只产生 LogEntry,染色/TTY/文件落盘全在本层。
5
5
  // - createNodeModulesPluginLoader:纯 npm 独立部署(从 node_modules 解析插件)
6
6
  // - createFsPluginLoader:monorepo 自托管(扫描 packages/ 目录)
7
+ // - createPluginDiscovery:把加载器发现的插件整批交给 core,并提供热扫描(plugin-source 服务的实现)
8
+ // - createConfigStore / installHostConfig:配置文档与 host-config 服务(core 只持运行态)
9
+ // - withPluginConfigSync:导入定义后、登记前把 schema 派生默认值深合并进文档
7
10
  // - createFsYamlConfigProvider / createProcessRespawnStrategy:YAML 配置 + 进程级重启
8
11
  // - startAalis:组装以上 + 宿主件为实例并启动(带 options 开关,默认独立部署)
9
12
  // - install*/setup*/tryDispatchSubcommand:宿主件,供高级 opt-in 组装
10
13
  export { getBootstrapBuffer, installBootstrapBuffer } from './bootstrap-buffer.js';
11
- export { handleConfigChanged, installConfigHotReload, syncPluginDefaults, } from './config-sync.js';
14
+ export { createConfigStore, installHostConfig } from './config-store.js';
15
+ export { handleConfigChanged, installConfigHotReload, syncPluginDefaults, withPluginConfigSync, } from './config-sync.js';
12
16
  export { installConsoleSink } from './console-sink.js';
13
17
  export { appendCrashLog, DEFAULT_LOG_FILE, setupFileLogger } from './file-logger.js';
14
18
  export { createNodeModulesPluginLoader } from './node-modules-loader.js';
19
+ export { createPluginDiscovery, } from './plugin-discovery.js';
15
20
  export { buildRespawnCommand, createFsPluginLoader, createFsYamlConfigProvider, createProcessRespawnStrategy, isRestartRollback, READY_MESSAGE, } from './providers.js';
16
21
  export { startAalis } from './start.js';
17
22
  export { tryDispatchSubcommand } from './subcommand.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,uDAAuD;AACvD,8DAA8D;AAC9D,oEAAoE;AACpE,yDAAyD;AACzD,gFAAgF;AAChF,uDAAuD;AACvD,8DAA8D;AAE9D,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAEL,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAA0B,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAyB,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,4BAA4B,EAC5B,iBAAiB,EACjB,aAAa,GAGd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAA0B,UAAU,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,uDAAuD;AACvD,8DAA8D;AAC9D,oEAAoE;AACpE,yDAAyD;AACzD,2EAA2E;AAC3E,6EAA6E;AAC7E,yDAAyD;AACzD,gFAAgF;AAChF,uDAAuD;AACvD,8DAA8D;AAE9D,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAyC,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAChH,OAAO,EAEL,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAA0B,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAyB,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EACL,qBAAqB,GAItB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,4BAA4B,EAC5B,iBAAiB,EACjB,aAAa,GAGd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAA0B,UAAU,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
@@ -1,4 +1,5 @@
1
- import type { Logger, PluginDefinition, PluginLoader } from '@aalis/core';
1
+ import type { Logger, PluginDefinition } from '@aalis/core';
2
+ import type { PluginDescriptor, PluginLoader } from './plugin-discovery.js';
2
3
  /**
3
4
  * 判定一个已装依赖是否为可加载的 Aalis 插件。纯函数,便于单测。
4
5
  * 唯一标准:keywords 含 'aalis-plugin'(真插件均带;契约/前端/核心/工具库带各自类型词,自然排除)。
@@ -6,7 +7,7 @@ import type { Logger, PluginDefinition, PluginLoader } from '@aalis/core';
6
7
  export declare function isLoadablePlugin(meta: Record<string, unknown>): boolean;
7
8
  /**
8
9
  * 从已导入模块取出定义,并按加载器政策出声:形状不对必须 warn;定义 name 与包名不一致也必须点名。
9
- * 判定本身在 `@aalis/core` 的 `pluginDefinitionOf`;两加载器共用本包装,告警文案只有这一份。
10
+ * 判定本身在 `@aalis/api-plugin-source` 的 `pluginDefinitionOf`;两加载器共用本包装,告警文案只有这一份。
10
11
  */
11
12
  export declare function loadPluginDefinition(ns: unknown, pkgName: string, logger: Logger): PluginDefinition | null;
12
13
  /**
@@ -15,17 +16,10 @@ export declare function loadPluginDefinition(ns: unknown, pkgName: string, logge
15
16
  */
16
17
  export declare const HOST_CORE_DIR: string | undefined;
17
18
  /**
18
- * 插件解析到的 @aalis/core 不是宿主那份时拒绝加载该插件(抛错),须在 import 插件之前调用。
19
- *
20
- * 依赖树允许同名包存在多份,两份 core 同处一个进程会让进程级身份分裂(默认日志中枢、
21
- * instanceof 等)且不报任何错。最常见的来路是本地插件目录被装成符号链接:插件目录自带的
22
- * devDependencies 里那份 core 成了它运行时解析到的那份。错误由 App 逐插件接住记 error,
23
- * 其余插件照常加载。两加载器共用。
24
- *
25
- * @param hostCoreDir 宿主那份 core 的包目录(realpath);undefined 时跳过
26
- * @param pluginDir 插件包目录,即两加载器 discover 写进描述符的 `metadata.dir`;缺失时跳过
19
+ * 两加载器共用的 load / reload:先经 {@link assertSameCore} 核对 core 是宿主那份,再动态 import 入口并取出定义。
20
+ * `fresh`(reload)时以入口文件 mtime 作 import URL 的 query,强制 ESM 缓存失效。
27
21
  */
28
- export declare function assertSameCore(hostCoreDir: string | undefined, pluginDir: unknown, pluginName: string): void;
22
+ export declare function importPluginDefinition(desc: PluginDescriptor, hostCoreDir: string | undefined, logger: Logger, fresh: boolean): Promise<PluginDefinition | null>;
29
23
  /**
30
24
  * 疑似插件缺关键词是「装了没反应」死门族之首:peer 依赖 core 却不带任何
31
25
  * aalis-* 类型词(契约/前端/工具库各有其词,带了即非误漏)。两加载器共用。
@@ -38,8 +32,8 @@ export declare function warnLikelyPluginMissingKeyword(logger: Logger, name: str
38
32
  * @param opts.hostCoreDir 宿主那份 @aalis/core 的包目录,默认 {@link HOST_CORE_DIR};插件解析到的 core 与它不同即拒绝加载
39
33
  *
40
34
  * - `discover()`:读 projectDir/package.json 的 dependencies + optionalDependencies,
41
- * 用 require.resolve 定位每个依赖的 package.json,按标记过滤出可加载插件。
42
- * - `load()`:先经 {@link assertSameCore} 核对 core 是宿主那份,再用 `pathToFileURL(entry).href` 动态 import(entry = require.resolve(包名))。
35
+ * 按 node_modules 上溯定位每个依赖的包目录并读其 package.json,按标记过滤出可加载插件;入口见 {@link packageEntry}。
36
+ * - `load()`:先经 {@link assertSameCore} 核对 core 是宿主那份,再用 `pathToFileURL(entry).href` 动态 import。
43
37
  * - `reload()`:用入口文件 mtime 作 import URL query 强制 ESM 缓存失效。
44
38
  */
45
39
  export declare function createNodeModulesPluginLoader(projectDir?: string, opts?: {
@@ -1 +1 @@
1
- {"version":3,"file":"node-modules-loader.d.ts","sourceRoot":"","sources":["../src/node-modules-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAoB,YAAY,EAAE,MAAM,aAAa,CAAC;AA0B5F;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAGvE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAY1G;AAcD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,GAAG,SAMjC,CAAC;AAEL;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAW5G;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAMhH;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,6BAA6B,CAC3C,UAAU,GAAE,MAAsB,EAClC,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,YAAY,CAmEd"}
1
+ {"version":3,"file":"node-modules-loader.d.ts","sourceRoot":"","sources":["../src/node-modules-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAyB5E;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAGvE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAY1G;AAuDD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,GAAG,SAMjC,CAAC;AA0BL;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,gBAAgB,EACtB,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAWlC;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAMhH;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,6BAA6B,CAC3C,UAAU,GAAE,MAAsB,EAClC,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAClC,YAAY,CAwCd"}
@@ -1,17 +1,17 @@
1
- import { existsSync, readFileSync, realpathSync } from 'node:fs';
1
+ import { existsSync, readFileSync, realpathSync, statSync } from 'node:fs';
2
2
  import { stat } from 'node:fs/promises';
3
- import { createRequire } from 'node:module';
4
3
  import { dirname, join, resolve } from 'node:path';
5
4
  import { fileURLToPath, pathToFileURL } from 'node:url';
6
- import { DefaultLogger, pluginDefinitionOf } from '@aalis/core';
5
+ import { pluginDefinitionOf } from '@aalis/api-plugin-source';
6
+ import { DefaultLogger } from '@aalis/core';
7
7
  // ============================================================
8
8
  // NodeModulesPluginLoader —— 从 node_modules 解析并加载插件
9
9
  // ============================================================
10
10
  //
11
11
  // 独立部署(纯 npm 装 Aalis)用的加载器:不扫描 packages/ 目录,而是读项目
12
- // package.json 的 dependencies,逐个用 node 模块解析(require.resolve)定位已装的
13
- // @aalis 插件并 dynamic import。与 monorepo 的 createFsPluginLoader 是「两种部署
14
- // 模型的两个加载器」,非重复:前者扫目录,后者走 node 解析。
12
+ // package.json 的 dependencies,逐个按 Node 的 ESM 解析规则(node_modules 上溯定位包目录、
13
+ // 入口取 import 条件)找到已装的插件并 dynamic import。与 monorepo 的 createFsPluginLoader 是
14
+ // 「两种部署模型的两个加载器」,非重复:前者扫目录,后者走 node 解析。
15
15
  //
16
16
  // 插件识别(纯正向关键词门):
17
17
  // - 唯一标准:package.json 的 keywords 含 'aalis-plugin'。
@@ -36,7 +36,7 @@ export function isLoadablePlugin(meta) {
36
36
  }
37
37
  /**
38
38
  * 从已导入模块取出定义,并按加载器政策出声:形状不对必须 warn;定义 name 与包名不一致也必须点名。
39
- * 判定本身在 `@aalis/core` 的 `pluginDefinitionOf`;两加载器共用本包装,告警文案只有这一份。
39
+ * 判定本身在 `@aalis/api-plugin-source` 的 `pluginDefinitionOf`;两加载器共用本包装,告警文案只有这一份。
40
40
  */
41
41
  export function loadPluginDefinition(ns, pkgName, logger) {
42
42
  const def = pluginDefinitionOf(ns);
@@ -50,25 +50,64 @@ export function loadPluginDefinition(ns, pkgName, logger) {
50
50
  return def;
51
51
  }
52
52
  /**
53
- * 按 Node 的 node_modules 逐级上溯规则,找出从 `start` 目录解析到的 `@aalis/core` 包目录(realpath)。
54
- * 只看目录布局、不走 exports,结果不受入口条件影响;找不到返回 undefined。
53
+ * 按 Node 的 node_modules 逐级上溯规则,找出从 `start` 目录解析到的包 `name` 的目录(realpath)。
54
+ * 只看目录布局、不走 exports,结果不受入口条件与 exports 是否开放 `./package.json` 影响;找不到返回 undefined。
55
55
  */
56
- function coreDirFrom(start) {
56
+ function packageDirFrom(start, name) {
57
57
  for (let dir = realpathSync(start);; dir = dirname(dir)) {
58
- const candidate = join(dir, 'node_modules', '@aalis', 'core');
58
+ const candidate = join(dir, 'node_modules', name);
59
59
  if (existsSync(join(candidate, 'package.json')))
60
60
  return realpathSync(candidate);
61
61
  if (dirname(dir) === dir)
62
62
  return undefined;
63
63
  }
64
64
  }
65
+ /** import() 解析包入口时匹配的条件:Node 的默认条件,module-sync 随 require(esm) 启用 */
66
+ const IMPORT_CONDITIONS = new Set([
67
+ 'node',
68
+ 'import',
69
+ 'default',
70
+ ...(process.features.require_module ? ['module-sync'] : []),
71
+ ]);
72
+ /** exports 目标按 import 条件取值:条件对象依键序、数组依次回退,目标须以 `./` 开头 */
73
+ function exportTarget(target) {
74
+ if (typeof target === 'string')
75
+ return target.startsWith('./') ? target : undefined;
76
+ if (!target || typeof target !== 'object')
77
+ return undefined;
78
+ const branches = Array.isArray(target)
79
+ ? target
80
+ : Object.entries(target).flatMap(([condition, value]) => (IMPORT_CONDITIONS.has(condition) ? [value] : []));
81
+ for (const branch of branches) {
82
+ const hit = exportTarget(branch);
83
+ if (hit)
84
+ return hit;
85
+ }
86
+ return undefined;
87
+ }
88
+ const isFile = (path) => statSync(path, { throwIfNoEntry: false })?.isFile() ?? false;
89
+ /**
90
+ * 包入口的绝对路径,与 import() 对包名解析到的是同一个文件:有 exports 时取 `"."` 的 import 条件目标;
91
+ * 没有时按 legacy main 规则依次试 main、main.js、main/index.js,最后 index.js。文件不存在返回 undefined。
92
+ */
93
+ function packageEntry(dir, meta) {
94
+ const { exports, main } = meta;
95
+ if (exports !== undefined && exports !== null) {
96
+ // 键以 . 开头的是子路径表,取其中的 ".";否则 exports 本身就是 "." 的目标(字符串、数组或条件对象)
97
+ const subpaths = typeof exports === 'object' && !Array.isArray(exports) && Object.keys(exports).some(k => k.startsWith('.'));
98
+ const target = exportTarget(subpaths ? exports['.'] : exports);
99
+ return target && isFile(join(dir, target)) ? join(dir, target) : undefined;
100
+ }
101
+ const guesses = typeof main === 'string' && main ? [main, `${main}.js`, join(main, 'index.js')] : [];
102
+ return [...guesses, 'index.js'].map(file => join(dir, file)).find(isFile);
103
+ }
65
104
  /**
66
105
  * 宿主那份 @aalis/core:runtime 用它创建 App,从本文件所在目录按同一规则算一次。
67
106
  * 算不到(如被打包内联、import.meta.url 不是文件 URL)为 undefined,检测随之跳过,不误报。
68
107
  */
69
108
  export const HOST_CORE_DIR = (() => {
70
109
  try {
71
- return coreDirFrom(dirname(fileURLToPath(import.meta.url)));
110
+ return packageDirFrom(dirname(fileURLToPath(import.meta.url)), '@aalis/core');
72
111
  }
73
112
  catch {
74
113
  return undefined;
@@ -79,16 +118,16 @@ export const HOST_CORE_DIR = (() => {
79
118
  *
80
119
  * 依赖树允许同名包存在多份,两份 core 同处一个进程会让进程级身份分裂(默认日志中枢、
81
120
  * instanceof 等)且不报任何错。最常见的来路是本地插件目录被装成符号链接:插件目录自带的
82
- * devDependencies 里那份 core 成了它运行时解析到的那份。错误由 App 逐插件接住记 error,
83
- * 其余插件照常加载。两加载器共用。
121
+ * devDependencies 里那份 core 成了它运行时解析到的那份。错误由宿主的插件发现(createPluginDiscovery
122
+ * 的 importAll)逐插件接住并记 error,其余插件照常加载。两加载器共用。
84
123
  *
85
124
  * @param hostCoreDir 宿主那份 core 的包目录(realpath);undefined 时跳过
86
125
  * @param pluginDir 插件包目录,即两加载器 discover 写进描述符的 `metadata.dir`;缺失时跳过
87
126
  */
88
- export function assertSameCore(hostCoreDir, pluginDir, pluginName) {
127
+ function assertSameCore(hostCoreDir, pluginDir, pluginName) {
89
128
  if (!hostCoreDir || typeof pluginDir !== 'string')
90
129
  return;
91
- const theirs = coreDirFrom(pluginDir);
130
+ const theirs = packageDirFrom(pluginDir, '@aalis/core');
92
131
  if (!theirs || theirs === hostCoreDir)
93
132
  return;
94
133
  const version = (dir) => String(readJson(join(dir, 'package.json'))?.version ?? '版本未知');
@@ -97,6 +136,23 @@ export function assertSameCore(hostCoreDir, pluginDir, pluginName) {
97
136
  '插件应把 @aalis/core 写进 peerDependencies 而非 dependencies;本地目录安装改用 npm install --install-links 或 pnpm add file:;' +
98
137
  '排查用 npm query "#@aalis/core" / pnpm why @aalis/core');
99
138
  }
139
+ /**
140
+ * 两加载器共用的 load / reload:先经 {@link assertSameCore} 核对 core 是宿主那份,再动态 import 入口并取出定义。
141
+ * `fresh`(reload)时以入口文件 mtime 作 import URL 的 query,强制 ESM 缓存失效。
142
+ */
143
+ export async function importPluginDefinition(desc, hostCoreDir, logger, fresh) {
144
+ assertSameCore(hostCoreDir, desc.metadata?.dir, desc.name);
145
+ let cacheKey = '';
146
+ if (fresh) {
147
+ try {
148
+ cacheKey = `?t=${(await stat(desc.source)).mtimeMs}`;
149
+ }
150
+ catch {
151
+ /* stat 失败时用空 key,让 import 自己报错 */
152
+ }
153
+ }
154
+ return loadPluginDefinition(await import(pathToFileURL(desc.source).href + cacheKey), desc.name, logger);
155
+ }
100
156
  /**
101
157
  * 疑似插件缺关键词是「装了没反应」死门族之首:peer 依赖 core 却不带任何
102
158
  * aalis-* 类型词(契约/前端/工具库各有其词,带了即非误漏)。两加载器共用。
@@ -115,15 +171,13 @@ export function warnLikelyPluginMissingKeyword(logger, name, meta) {
115
171
  * @param opts.hostCoreDir 宿主那份 @aalis/core 的包目录,默认 {@link HOST_CORE_DIR};插件解析到的 core 与它不同即拒绝加载
116
172
  *
117
173
  * - `discover()`:读 projectDir/package.json 的 dependencies + optionalDependencies,
118
- * 用 require.resolve 定位每个依赖的 package.json,按标记过滤出可加载插件。
119
- * - `load()`:先经 {@link assertSameCore} 核对 core 是宿主那份,再用 `pathToFileURL(entry).href` 动态 import(entry = require.resolve(包名))。
174
+ * 按 node_modules 上溯定位每个依赖的包目录并读其 package.json,按标记过滤出可加载插件;入口见 {@link packageEntry}。
175
+ * - `load()`:先经 {@link assertSameCore} 核对 core 是宿主那份,再用 `pathToFileURL(entry).href` 动态 import。
120
176
  * - `reload()`:用入口文件 mtime 作 import URL query 强制 ESM 缓存失效。
121
177
  */
122
178
  export function createNodeModulesPluginLoader(projectDir = process.cwd(), opts = {}) {
123
179
  const root = resolve(projectDir);
124
180
  const hostCoreDir = opts.hostCoreDir === undefined ? HOST_CORE_DIR : realpathSync(opts.hostCoreDir);
125
- // 以项目 package.json 为基准创建 require,确保从项目 node_modules 解析
126
- const req = createRequire(pathToFileURL(resolve(root, 'package.json')));
127
181
  const logger = new DefaultLogger('aalis:loader');
128
182
  return {
129
183
  async discover() {
@@ -136,56 +190,28 @@ export function createNodeModulesPluginLoader(projectDir = process.cwd(), opts =
136
190
  };
137
191
  const discovered = [];
138
192
  for (const dep of Object.keys(deps)) {
139
- let metaPath;
140
- try {
141
- metaPath = req.resolve(`${dep}/package.json`);
142
- }
143
- catch (err) {
144
- // 未安装保持安静;但 exports 映射屏蔽 package.json 的包(装了却读不到
145
- // 元数据)是链上最早的静默死点——无法判定是否插件,必须出声。
146
- if (err.code === 'ERR_PACKAGE_PATH_NOT_EXPORTED') {
147
- logger.warn(`依赖 "${dep}" 的 exports 映射未导出 "./package.json",无法读取元数据判定是否插件,跳过`);
148
- }
193
+ // 未安装保持安静
194
+ const dir = packageDirFrom(root, dep);
195
+ if (!dir)
149
196
  continue;
150
- }
151
- const meta = readJson(metaPath);
197
+ const meta = readJson(join(dir, 'package.json'));
152
198
  if (!meta)
153
199
  continue;
154
200
  if (!isLoadablePlugin(meta)) {
155
201
  warnLikelyPluginMissingKeyword(logger, dep, meta);
156
202
  continue;
157
203
  }
158
- let entry;
159
- try {
160
- entry = req.resolve(dep);
161
- }
162
- catch {
163
- logger.warn(`插件 "${dep}" 入口无法解析(缺 main/exports 或产物未打进 files),跳过`);
204
+ const entry = packageEntry(dir, meta);
205
+ if (!entry) {
206
+ logger.warn(`插件 "${dep}" 入口无法解析(exports 的 "." 没有 import 条件可用的目标,或入口文件不存在:main 写错、产物未打进 files),跳过`);
164
207
  continue;
165
208
  }
166
- discovered.push({
167
- name: meta.name ?? dep,
168
- source: entry,
169
- metadata: { dir: dirname(metaPath) },
170
- });
209
+ discovered.push({ name: meta.name ?? dep, source: entry, metadata: { dir } });
171
210
  }
172
211
  return discovered;
173
212
  },
174
- async load(desc) {
175
- assertSameCore(hostCoreDir, desc.metadata?.dir, desc.name);
176
- return loadPluginDefinition(await import(pathToFileURL(desc.source).href), desc.name, logger);
177
- },
178
- async reload(desc) {
179
- assertSameCore(hostCoreDir, desc.metadata?.dir, desc.name);
180
- let cacheKey = '';
181
- try {
182
- cacheKey = `?t=${(await stat(desc.source)).mtimeMs}`;
183
- }
184
- catch {
185
- /* stat 失败时用空 key,让 import 自己报错 */
186
- }
187
- return loadPluginDefinition(await import(pathToFileURL(desc.source).href + cacheKey), desc.name, logger);
188
- },
213
+ load: desc => importPluginDefinition(desc, hostCoreDir, logger, false),
214
+ reload: desc => importPluginDefinition(desc, hostCoreDir, logger, true),
189
215
  };
190
216
  }
191
217
  //# sourceMappingURL=node-modules-loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-modules-loader.js","sourceRoot":"","sources":["../src/node-modules-loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node-modules-loader.js","sourceRoot":"","sources":["../src/node-modules-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { HostConfig } from '@aalis/api-host-config';
2
+ import type { PluginSourceService } from '@aalis/api-plugin-source';
3
+ import { type App, type PluginDefinition } from '@aalis/core';
4
+ /**
5
+ * 已发现但尚未导入的插件条目。`source` 是 loader 自己理解的字符串
6
+ * (fs loader 用绝对路径,URL loader 用 URL,内存 loader 用 module 别名)。
7
+ */
8
+ export interface PluginDescriptor {
9
+ /** 插件名,与定义的 `name` 一致;按它跳过已注册者 */
10
+ name: string;
11
+ /** 给 loader 自己用的不透明定位串 */
12
+ source: string;
13
+ /** loader 可挂任意辅助元数据(cache key、版本号、manifest 等) */
14
+ metadata?: Record<string, unknown>;
15
+ }
16
+ /**
17
+ * 插件加载器:负责"插件从哪里来"。
18
+ *
19
+ * - `discover()` 列出当前可用的插件条目
20
+ * - `load(descriptor)` 把条目导入成插件定义(模块默认导出的 definePlugin 产物);不是插件返回 null
21
+ * - `reload(descriptor)` 可选——热扫描时用(fs loader 用 mtime 做 cache buster),不提供时退化为 `load()`
22
+ */
23
+ export interface PluginLoader {
24
+ discover(): Promise<PluginDescriptor[]>;
25
+ load(descriptor: PluginDescriptor): Promise<PluginDefinition | null>;
26
+ reload?(descriptor: PluginDescriptor): Promise<PluginDefinition | null>;
27
+ }
28
+ export interface PluginDiscovery extends PluginSourceService {
29
+ /** 冷启动:发现并导入全部插件,整批注册,返回时已静置 */
30
+ loadAll(): Promise<void>;
31
+ /**
32
+ * 登记配置文档里尚未注册的 `name:suffix` 实例,模块取注册表里该模块在册实例的定义(主实例优先);判据与冷启动、热扫描相同。
33
+ * 配置热重载在同步文档之后调用。不等静置。
34
+ */
35
+ registerConfiguredInstances(): Promise<void>;
36
+ }
37
+ /**
38
+ * @param doc 配置文档:登记时按实例 id 取配置与禁用标记,并从中枚举 `name:suffix` 实例。
39
+ * 配置原样交给 core,默认值回填由加载器一侧的政策(withPluginConfigSync)先写进文档。
40
+ */
41
+ export declare function createPluginDiscovery(app: App, loader: PluginLoader, doc: Omit<HostConfig, 'save'>): PluginDiscovery;
42
+ //# sourceMappingURL=plugin-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-discovery.d.ts","sourceRoot":"","sources":["../src/plugin-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,gBAAgB,EAA4C,MAAM,aAAa,CAAC;AAYxG;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACxC,IAAI,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,CAAC,UAAU,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACzE;AAED,MAAM,WAAW,eAAgB,SAAQ,mBAAmB;IAC1D,gCAAgC;IAChC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB;;;OAGG;IACH,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,eAAe,CAiGpH"}
@@ -0,0 +1,107 @@
1
+ import { parseInstanceId } from '@aalis/core';
2
+ /**
3
+ * @param doc 配置文档:登记时按实例 id 取配置与禁用标记,并从中枚举 `name:suffix` 实例。
4
+ * 配置原样交给 core,默认值回填由加载器一侧的政策(withPluginConfigSync)先写进文档。
5
+ */
6
+ export function createPluginDiscovery(app, loader, doc) {
7
+ const log = app.logger;
8
+ const registration = (definition, instanceId = definition.name) => ({
9
+ definition,
10
+ instanceId,
11
+ config: doc.getPluginConfig(instanceId),
12
+ disabled: doc.isPluginDisabled(instanceId),
13
+ });
14
+ /** 导入一批描述符并备好各自的登记项;单个失败(含 id 撞上危险键、文档拒取)只记该条,不拖累其余 */
15
+ async function importAll(descriptors, fresh) {
16
+ const loaded = [];
17
+ for (const desc of descriptors) {
18
+ try {
19
+ // 加载器已按入口约定判定(pluginDefinitionOf),不是插件返回 null;定义本身的校验在注册时做
20
+ const definition = fresh && loader.reload ? await loader.reload(desc) : await loader.load(desc);
21
+ if (!definition)
22
+ continue;
23
+ loaded.push(registration(definition));
24
+ }
25
+ catch (err) {
26
+ log.error(`加载插件 "${desc.name}" 失败:`, err);
27
+ }
28
+ }
29
+ return loaded;
30
+ }
31
+ /**
32
+ * 配置键里的 `name:suffix` 实例:模块查得到定义才登记,已在注册表的跳过。
33
+ * 冷启动、热扫描与热重载共用,任何一处都不得少收
34
+ */
35
+ function configuredInstances(definitionOf) {
36
+ const items = [];
37
+ for (const configKey of Object.keys(doc.get('plugins') ?? {})) {
38
+ const { moduleName, suffix } = parseInstanceId(configKey);
39
+ if (!suffix || app.plugins.getPlugin(configKey))
40
+ continue;
41
+ const definition = definitionOf(moduleName);
42
+ if (definition)
43
+ items.push(registration(definition, configKey));
44
+ else
45
+ log.warn(`多实例配置 "${configKey}" 对应的模块 "${moduleName}" 未找到,跳过`);
46
+ }
47
+ return items;
48
+ }
49
+ /**
50
+ * 单实例配置段找不到对应插件(多为直接 `npm uninstall` 后残留):冷启动时逐段告警一次。
51
+ * 发现到却导入失败的已有加载错误,不重复报;多实例键由 {@link configuredInstances} 报。
52
+ */
53
+ function warnOrphanedConfig(known, discovered) {
54
+ const attempted = new Set(discovered.map(d => d.name));
55
+ for (const configKey of Object.keys(doc.get('plugins') ?? {})) {
56
+ if (parseInstanceId(configKey).suffix)
57
+ continue;
58
+ if (known.has(configKey) || attempted.has(configKey) || app.plugins.getPlugin(configKey))
59
+ continue;
60
+ log.warn(`配置段 "${configKey}" 对应的插件未找到,已忽略;若已卸载可删除该段(其中可能含密钥)`);
61
+ }
62
+ }
63
+ return {
64
+ async loadAll() {
65
+ const discovered = await loader.discover();
66
+ log.info(`发现 ${discovered.length} 个插件`);
67
+ const loaded = await importAll(discovered, false);
68
+ const known = new Map(loaded.map(item => [item.definition.name, item.definition]));
69
+ warnOrphanedConfig(known, discovered);
70
+ await app.pluginAll([...loaded, ...configuredInstances(name => known.get(name))]);
71
+ // app:ready / app:started 的发出时机依赖「返回即全部收敛」;引导路径不在任何 apply 内,无自等死锁面。
72
+ await app.plugins.idle();
73
+ },
74
+ async rescan() {
75
+ const known = new Map();
76
+ const fresh = [];
77
+ for (const desc of await loader.discover()) {
78
+ const registered = app.plugins.getPlugin(desc.name);
79
+ if (registered)
80
+ known.set(registered.definition.name, registered.definition);
81
+ else
82
+ fresh.push(desc);
83
+ }
84
+ const loaded = await importAll(fresh, true);
85
+ for (const item of loaded)
86
+ known.set(item.definition.name, item.definition);
87
+ const results = await app.pluginAll([...loaded, ...configuredInstances(name => known.get(name))]);
88
+ // 模块自报的 name 与描述符不同且已注册时 register 会拒绝——那不算热加载,不报进名单。
89
+ // 报的是登记进注册表的主实例名(定义名),不是加载器给的描述符名(通常是包名,二者可以不同)。
90
+ const names = loaded.filter((_, i) => results[i]).map(item => item.definition.name);
91
+ for (const name of names)
92
+ log.info(`热加载插件: ${name}`);
93
+ return names;
94
+ },
95
+ async registerConfiguredInstances() {
96
+ const known = new Map();
97
+ for (const { name, instanceId } of app.plugins.getStatus()) {
98
+ const definition = app.plugins.getPlugin(instanceId)?.definition;
99
+ // 主实例的定义优先;主实例已卸载时用同模块任一在册实例的,与冷启动时这一段照常登记一致
100
+ if (definition && (instanceId === name || !known.has(name)))
101
+ known.set(name, definition);
102
+ }
103
+ await app.pluginAll(configuredInstances(name => known.get(name)));
104
+ },
105
+ };
106
+ }
107
+ //# sourceMappingURL=plugin-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-discovery.js","sourceRoot":"","sources":["../src/plugin-discovery.ts"],"names":[],"mappings":"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"}