@actiondock/core 2.10.0 → 2.12.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.
- package/README.md +1 -2
- package/dist/catalog/action-catalog.js +3 -33
- package/dist/catalog/discovery.d.ts +0 -3
- package/dist/catalog/discovery.js +4 -4
- package/dist/catalog/graph.d.ts +0 -4
- package/dist/catalog/graph.js +8 -14
- package/dist/{profile/client-actions.d.ts → client/actions.d.ts} +1 -1
- package/dist/{profile/client-actions.js → client/actions.js} +2 -8
- package/dist/{profile/client-config.d.ts → client/config.d.ts} +1 -1
- package/dist/{profile/client-config.js → client/config.js} +1 -1
- package/dist/client/dispatcher.d.ts +4 -0
- package/dist/client/dispatcher.js +21 -0
- package/dist/client/health.d.ts +38 -0
- package/dist/{profile/client-health.js → client/health.js} +9 -6
- package/dist/client/index.d.ts +16 -0
- package/dist/client/index.js +20 -0
- package/dist/{profile/client-playbooks.d.ts → client/playbooks.d.ts} +1 -1
- package/dist/{profile/client-playbooks.js → client/playbooks.js} +1 -1
- package/dist/{profile/client-runs.d.ts → client/runs.d.ts} +4 -2
- package/dist/{profile/client-runs.js → client/runs.js} +7 -1
- package/dist/{profile/client-state.d.ts → client/state.d.ts} +1 -1
- package/dist/{profile/client-state.js → client/state.js} +1 -1
- package/dist/{profile/client-transport.d.ts → client/transport.d.ts} +29 -10
- package/dist/{profile/client-transport.js → client/transport.js} +125 -35
- package/dist/doctor/checks/index.d.ts +1 -1
- package/dist/doctor/checks/index.js +1 -1
- package/dist/doctor/checks/project.js +20 -88
- package/dist/doctor/checks/runtime.d.ts +0 -4
- package/dist/doctor/checks/runtime.js +0 -28
- package/dist/doctor/doctor.js +1 -2
- package/dist/errors.d.ts +53 -3
- package/dist/errors.js +53 -3
- package/dist/execution/service.d.ts +55 -37
- package/dist/execution/service.js +601 -212
- package/dist/execution/types.d.ts +24 -5
- package/dist/host/host.d.ts +42 -22
- package/dist/host/host.js +562 -149
- package/dist/host/routing.js +6 -6
- package/dist/host/types.d.ts +25 -13
- package/dist/index.d.ts +9 -4
- package/dist/index.js +5 -2
- package/dist/input/advice.d.ts +0 -44
- package/dist/input/advice.js +7 -141
- package/dist/input/flat-materializer.js +1 -1
- package/dist/input/flat-parser.js +1 -1
- package/dist/input/index.d.ts +0 -1
- package/dist/input/index.js +0 -1
- package/dist/input/input-resolver.js +1 -1
- package/dist/input/validation-mapper.d.ts +1 -1
- package/dist/ipc/diagnostic.d.ts +8 -21
- package/dist/ipc/diagnostic.js +24 -57
- package/dist/ipc/host.js +21 -7
- package/dist/ipc/service.d.ts +14 -0
- package/dist/ipc/service.js +132 -26
- package/dist/ipc/types.d.ts +0 -4
- package/dist/package/index.d.ts +4 -5
- package/dist/package/index.js +1 -2
- package/dist/package/runtime.d.ts +94 -23
- package/dist/package/runtime.js +628 -274
- package/dist/package/static-index.d.ts +3 -6
- package/dist/package/static-index.js +11 -40
- package/dist/package/types.d.ts +19 -4
- package/dist/platform/index.d.ts +2 -1
- package/dist/platform/index.js +2 -1
- package/dist/platform/loader-hook.d.ts +32 -0
- package/dist/platform/loader-hook.js +90 -0
- package/dist/{node → platform}/module-loader.d.ts +13 -0
- package/dist/{node → platform}/module-loader.js +51 -4
- package/dist/platform/node.d.ts +19 -8
- package/dist/platform/node.js +50 -20
- package/dist/platform/types.d.ts +7 -47
- package/dist/process/context-process.d.ts +3 -18
- package/dist/process/context-process.js +3 -44
- package/dist/process/control.d.ts +21 -0
- package/dist/process/control.js +34 -0
- package/dist/process/converters.d.ts +23 -0
- package/dist/process/converters.js +92 -0
- package/dist/process/cursor.js +2 -22
- package/dist/process/{diagnostics-sink.d.ts → diagnostics.d.ts} +0 -7
- package/dist/process/{diagnostics-sink.js → diagnostics.js} +6 -8
- package/dist/process/index.d.ts +1 -3
- package/dist/process/index.js +1 -3
- package/dist/process/input-dispatcher.d.ts +4 -13
- package/dist/process/input-dispatcher.js +48 -69
- package/dist/process/managed-record.d.ts +3 -31
- package/dist/process/metadata-store.d.ts +0 -41
- package/dist/process/metadata-store.js +2 -341
- package/dist/process/process-driver.js +2 -2
- package/dist/process/process-manager.d.ts +8 -50
- package/dist/process/process-manager.js +28 -417
- package/dist/process/quotas.d.ts +14 -0
- package/dist/process/quotas.js +29 -0
- package/dist/process/run-executor.js +0 -1
- package/dist/process/terminal-output-cache.d.ts +20 -34
- package/dist/process/terminal-output-cache.js +43 -64
- package/dist/profile/index.d.ts +1 -2
- package/dist/profile/index.js +1 -2
- package/dist/profile/manager.d.ts +2 -4
- package/dist/profile/manager.js +10 -40
- package/dist/profile/types.d.ts +1 -17
- package/dist/project/digest.d.ts +5 -1
- package/dist/project/digest.js +81 -219
- package/dist/project/index.d.ts +4 -5
- package/dist/project/index.js +4 -5
- package/dist/project/init.js +2 -2
- package/dist/project/loader.d.ts +3 -3
- package/dist/project/loader.js +72 -50
- package/dist/project/lockfile.js +6 -5
- package/dist/project/manifest.js +5 -4
- package/dist/project/transactions.d.ts +4 -42
- package/dist/project/transactions.js +83 -138
- package/dist/project/types-generator.js +2 -1
- package/dist/project/types.d.ts +2 -0
- package/dist/registry/index.d.ts +0 -1
- package/dist/registry/index.js +0 -1
- package/dist/registry/lock.d.ts +2 -11
- package/dist/registry/lock.js +14 -183
- package/dist/registry/registry.d.ts +1 -6
- package/dist/registry/registry.js +5 -17
- package/dist/runtime/action-registry.d.ts +1 -5
- package/dist/runtime/action-registry.js +0 -12
- package/dist/runtime/context.js +2 -2
- package/dist/runtime/events.d.ts +11 -50
- package/dist/runtime/events.js +88 -368
- package/dist/runtime/index.d.ts +0 -4
- package/dist/runtime/index.js +0 -4
- package/dist/runtime/run-persistence.d.ts +2 -0
- package/dist/runtime/run-persistence.js +2 -1
- package/dist/runtime/standalone-commands.d.ts +18 -0
- package/dist/runtime/standalone-commands.js +466 -0
- package/dist/runtime/standalone-help.d.ts +20 -0
- package/dist/runtime/standalone-help.js +72 -0
- package/dist/runtime/standalone.d.ts +1 -44
- package/dist/runtime/standalone.js +32 -573
- package/dist/schema/validator.d.ts +2 -2
- package/dist/schema/validator.js +2 -9
- package/dist/server/index.d.ts +0 -2
- package/dist/server/index.js +0 -2
- package/dist/server/routes/actions.js +1 -1
- package/dist/server/routes/info.js +1 -1
- package/dist/server/routes/playbooks.js +1 -1
- package/dist/server/routes/runs.js +123 -16
- package/dist/server/routes/state.js +43 -18
- package/dist/server/security.d.ts +1 -1
- package/dist/server/security.js +2 -2
- package/dist/server/server.js +3 -7
- package/dist/service/factory.js +4 -3
- package/dist/service/index.d.ts +1 -1
- package/dist/service/index.js +1 -1
- package/dist/service/remote-errors.d.ts +1 -1
- package/dist/service/remote-errors.js +6 -6
- package/dist/service/remote-polling.d.ts +3 -0
- package/dist/service/remote-polling.js +10 -5
- package/dist/service/remote.d.ts +5 -1
- package/dist/service/remote.js +108 -17
- package/dist/service/sse-stream.js +2 -2
- package/dist/service/types.d.ts +22 -19
- package/dist/service/types.js +1 -24
- package/dist/storage/clock.d.ts +1 -1
- package/dist/storage/clock.js +1 -1
- package/dist/storage/data-dir-lock.d.ts +10 -22
- package/dist/storage/data-dir-lock.js +28 -56
- package/dist/storage/file-lock.d.ts +64 -0
- package/dist/storage/file-lock.js +447 -0
- package/dist/storage/index.d.ts +2 -2
- package/dist/storage/index.js +5 -4
- package/dist/storage/run-liveness.d.ts +48 -0
- package/dist/storage/run-liveness.js +44 -0
- package/dist/storage/sqlite-config.d.ts +16 -0
- package/dist/storage/sqlite-config.js +59 -0
- package/dist/storage/sqlite-driver.d.ts +3 -1
- package/dist/storage/sqlite-driver.js +14 -4
- package/dist/storage/sqlite-events.d.ts +13 -0
- package/dist/storage/sqlite-events.js +48 -0
- package/dist/storage/sqlite-runs.d.ts +107 -0
- package/dist/storage/sqlite-runs.js +622 -0
- package/dist/storage/sqlite-schema.d.ts +5 -0
- package/dist/storage/sqlite-schema.js +143 -0
- package/dist/storage/sqlite-state.d.ts +33 -0
- package/dist/storage/sqlite-state.js +270 -0
- package/dist/storage/sqlite.d.ts +30 -57
- package/dist/storage/sqlite.js +84 -741
- package/dist/storage/types.d.ts +35 -2
- package/dist/utils/index.d.ts +18 -14
- package/dist/utils/index.js +37 -29
- package/dist/utils/semver.d.ts +18 -0
- package/dist/utils/semver.js +19 -0
- package/dist/utils/warning.d.ts +1 -0
- package/dist/utils/warning.js +52 -0
- package/dist/{json/value-validator.d.ts → value-validator.d.ts} +9 -0
- package/dist/value-validator.js +330 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +10 -12
- package/dist/execution/index.d.ts +0 -2
- package/dist/execution/index.js +0 -2
- package/dist/filter/index.d.ts +0 -1
- package/dist/filter/index.js +0 -1
- package/dist/graph/index.d.ts +0 -4
- package/dist/graph/index.js +0 -4
- package/dist/input/metadata.d.ts +0 -99
- package/dist/input/metadata.js +0 -99
- package/dist/invocation/index.d.ts +0 -2
- package/dist/invocation/index.js +0 -2
- package/dist/ipc/index.d.ts +0 -4
- package/dist/ipc/index.js +0 -4
- package/dist/json/index.d.ts +0 -1
- package/dist/json/index.js +0 -1
- package/dist/json/value-validator.js +0 -330
- package/dist/node/index.d.ts +0 -1
- package/dist/node/index.js +0 -1
- package/dist/platform/node-fs.d.ts +0 -37
- package/dist/platform/node-fs.js +0 -81
- package/dist/process/control-arbiter.d.ts +0 -108
- package/dist/process/control-arbiter.js +0 -250
- package/dist/process/process-executor.d.ts +0 -47
- package/dist/process/process-executor.js +0 -296
- package/dist/profile/client-health.d.ts +0 -14
- package/dist/profile/client-query.d.ts +0 -30
- package/dist/profile/client-query.js +0 -69
- package/dist/profile/client.d.ts +0 -26
- package/dist/profile/client.js +0 -31
- package/dist/project/closure.d.ts +0 -25
- package/dist/project/closure.js +0 -74
- package/dist/registry/store.d.ts +0 -42
- package/dist/registry/store.js +0 -43
- package/dist/runtime/clock.d.ts +0 -7
- package/dist/runtime/clock.js +0 -7
- package/dist/runtime/module-loader.d.ts +0 -2
- package/dist/runtime/module-loader.js +0 -1
- package/dist/runtime/process.d.ts +0 -8
- package/dist/runtime/process.js +0 -1
- package/dist/runtime/runner.d.ts +0 -234
- package/dist/runtime/runner.js +0 -609
- package/dist/schema/index.d.ts +0 -1
- package/dist/schema/index.js +0 -1
- package/dist/server/dispatcher.d.ts +0 -25
- package/dist/server/dispatcher.js +0 -54
- package/dist/service/local.d.ts +0 -27
- package/dist/service/local.js +0 -141
- package/dist/storage/driver.d.ts +0 -10
- package/dist/storage/driver.js +0 -10
- package/dist/storage/lazy.d.ts +0 -8
- package/dist/storage/lazy.js +0 -45
- package/dist/storage/lock-core.d.ts +0 -158
- package/dist/storage/lock-core.js +0 -872
- package/dist/utils/net.d.ts +0 -10
- package/dist/utils/net.js +0 -16
- package/dist/utils/process.d.ts +0 -10
- package/dist/utils/process.js +0 -21
- /package/dist/{filter → utils}/intent.d.ts +0 -0
- /package/dist/{filter → utils}/intent.js +0 -0
|
@@ -6,11 +6,11 @@ import type { ActionSpec, PlaybookSpec } from "./types.js";
|
|
|
6
6
|
* 入参不可变(同实例内复用解析结果的前提),字段与 App 实例的运行时只读状态一一对应。
|
|
7
7
|
*/
|
|
8
8
|
export interface StaticIndexInput {
|
|
9
|
-
/**
|
|
9
|
+
/** 包根目录(缺省时仅聚合配置与内存注入来源) */
|
|
10
10
|
packageRoot?: string;
|
|
11
11
|
/** 包唯一标识 */
|
|
12
12
|
packageId: string;
|
|
13
|
-
/**
|
|
13
|
+
/** 项目配置(规范化清单配置快照,单一事实源) */
|
|
14
14
|
projectConfig: ProjectConfig;
|
|
15
15
|
}
|
|
16
16
|
/** Action 索引构建入参:静态事实来源之上叠加内存注入的 Action 定义集合 */
|
|
@@ -23,11 +23,8 @@ export interface StaticActionIndexInput extends StaticIndexInput {
|
|
|
23
23
|
* 不产生全量模块导入与执行副作用。
|
|
24
24
|
*
|
|
25
25
|
* 聚合优先级(后者覆盖前者同名字段,缺省字段回退前者):
|
|
26
|
-
* -
|
|
27
|
-
* - 项目配置中声明的 actions(Manifest v2 格式);
|
|
26
|
+
* - 项目清单配置快照中声明的 actions(Manifest v2 格式,单一事实源);
|
|
28
27
|
* - 内存显式注入的 Action 定义。
|
|
29
|
-
*
|
|
30
|
-
* 清单文件不存在属于合法空态;解析失败(损坏 JSON 等)输出告警并跳过清单部分。
|
|
31
28
|
*/
|
|
32
29
|
export declare function buildStaticActionMap(input: StaticActionIndexInput): Map<string, ActionSpec>;
|
|
33
30
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import { loadPlaybooks } from "../project/loader.js";
|
|
4
|
-
import {
|
|
4
|
+
import { MANIFEST_FILE_NAME } from "../project/manifest.js";
|
|
5
5
|
/**
|
|
6
6
|
* 将增量声明合并到既有 Action 规范之上(纯函数,单一事实源)。
|
|
7
7
|
*
|
|
@@ -45,53 +45,23 @@ function mergeSpec(base, id, packageId, patch, packageRoot, policy = {}) {
|
|
|
45
45
|
* 不产生全量模块导入与执行副作用。
|
|
46
46
|
*
|
|
47
47
|
* 聚合优先级(后者覆盖前者同名字段,缺省字段回退前者):
|
|
48
|
-
* -
|
|
49
|
-
* - 项目配置中声明的 actions(Manifest v2 格式);
|
|
48
|
+
* - 项目清单配置快照中声明的 actions(Manifest v2 格式,单一事实源);
|
|
50
49
|
* - 内存显式注入的 Action 定义。
|
|
51
|
-
*
|
|
52
|
-
* 清单文件不存在属于合法空态;解析失败(损坏 JSON 等)输出告警并跳过清单部分。
|
|
53
50
|
*/
|
|
54
51
|
export function buildStaticActionMap(input) {
|
|
55
52
|
const { packageRoot, packageId, projectConfig, actionsMap } = input;
|
|
56
53
|
const map = new Map();
|
|
57
|
-
//
|
|
58
|
-
if (packageRoot) {
|
|
59
|
-
const manifestPath = join(packageRoot, MANIFEST_FILE_NAME);
|
|
60
|
-
// 文件不存在属于合法空态(无清单包);解析失败(损坏 JSON 等)则输出告警并跳过清单部分
|
|
61
|
-
if (!existsSync(manifestPath)) {
|
|
62
|
-
// 合法空态:无清单文件,仅依赖后续配置与内存注入来源
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
try {
|
|
66
|
-
const manifest = loadManifest(packageRoot);
|
|
67
|
-
if (manifest?.actions) {
|
|
68
|
-
for (const [id, item] of Object.entries(manifest.actions)) {
|
|
69
|
-
// 磁盘清单为最底层来源:无更低层可回退,tags 与 uses 缺省时归一为空数组
|
|
70
|
-
map.set(id, mergeSpec(undefined, id, packageId, {
|
|
71
|
-
...item,
|
|
72
|
-
tags: item.tags ?? [],
|
|
73
|
-
uses: item.uses ?? [],
|
|
74
|
-
}, packageRoot, {
|
|
75
|
-
arrayFields: ["tags", "uses"],
|
|
76
|
-
deriveFilePath: true,
|
|
77
|
-
}));
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch (err) {
|
|
82
|
-
console.warn(`[App] Failed to load manifest for package '${packageId}' from '${manifestPath}': ${err?.message || String(err)}`);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// 读取项目配置文件中声明的 actions (Manifest v2 格式)
|
|
54
|
+
// 读取规范化清单配置快照中声明的 actions (Manifest v2 格式)
|
|
87
55
|
if (projectConfig && projectConfig.actions) {
|
|
88
56
|
const rawActions = projectConfig.actions;
|
|
89
57
|
if (typeof rawActions === "object" && rawActions !== null) {
|
|
90
58
|
for (const [id, item] of Object.entries(rawActions)) {
|
|
91
|
-
|
|
92
|
-
|
|
59
|
+
map.set(id, mergeSpec(undefined, id, packageId, {
|
|
60
|
+
...item,
|
|
61
|
+
tags: item.tags ?? [],
|
|
62
|
+
uses: item.uses ?? [],
|
|
63
|
+
}, packageRoot, {
|
|
93
64
|
arrayFields: ["tags", "uses"],
|
|
94
|
-
arrayCopy: false,
|
|
95
65
|
deriveFilePath: true,
|
|
96
66
|
}));
|
|
97
67
|
}
|
|
@@ -106,7 +76,7 @@ export function buildStaticActionMap(input) {
|
|
|
106
76
|
continue;
|
|
107
77
|
}
|
|
108
78
|
}
|
|
109
|
-
//
|
|
79
|
+
// 内存注入层:保留清单层解析出的 entry 与 filePath,仅覆盖动态定义相关字段
|
|
110
80
|
map.set(id, mergeSpec(map.get(id), id, packageId, act, packageRoot, {
|
|
111
81
|
arrayFields: ["tags", "uses"],
|
|
112
82
|
preserveEntry: true,
|
|
@@ -127,7 +97,8 @@ export function buildStaticPlaybookMap(input) {
|
|
|
127
97
|
if (packageRoot) {
|
|
128
98
|
const playbooksDir = projectConfig?.playbooksDir || "playbooks";
|
|
129
99
|
const dirPath = join(packageRoot, playbooksDir);
|
|
130
|
-
|
|
100
|
+
const manifestPath = join(packageRoot, MANIFEST_FILE_NAME);
|
|
101
|
+
if (existsSync(manifestPath) || existsSync(dirPath)) {
|
|
131
102
|
try {
|
|
132
103
|
const loaded = loadPlaybooks(packageRoot, playbooksDir);
|
|
133
104
|
for (const [id, def] of loaded) {
|
package/dist/package/types.d.ts
CHANGED
|
@@ -209,8 +209,14 @@ export interface PackageRuntimeInternalOptions extends PackageRuntimeOptions {
|
|
|
209
209
|
identity?: PackageIdentity;
|
|
210
210
|
/** 显式注入的项目级运行时存储实例 */
|
|
211
211
|
storage?: RuntimeStorage;
|
|
212
|
-
/**
|
|
212
|
+
/** 显式注入的全局运行时存储实例(优先级最高) */
|
|
213
213
|
globalStorage?: RuntimeStorage;
|
|
214
|
+
/**
|
|
215
|
+
* Host 共享全局存储提供函数(同步求值,首次需要时才调用)。
|
|
216
|
+
* 优先级低于显式 globalStorage 注入,高于包自建全局库;
|
|
217
|
+
* 提供函数必须同步,因 RuntimeConfig 与 ctx.config.get() 的读取契约是同步的。
|
|
218
|
+
*/
|
|
219
|
+
globalStorageProvider?: () => RuntimeStorage;
|
|
214
220
|
/** 显式注入的事件接收器 */
|
|
215
221
|
eventSink?: EventSink;
|
|
216
222
|
/** 子任务动作调用委托器 */
|
|
@@ -237,6 +243,8 @@ export interface PackageRuntime {
|
|
|
237
243
|
readonly packageRoot?: string;
|
|
238
244
|
/** 项目配置对象(actiondock.json 解析结果) */
|
|
239
245
|
readonly projectConfig: ProjectConfig;
|
|
246
|
+
/** 是否采用纯内存运行模式 */
|
|
247
|
+
readonly inMemory?: boolean;
|
|
240
248
|
/**
|
|
241
249
|
* 受信任内部调用方法(Host 或子任务执行主链调用入口)。
|
|
242
250
|
* 委托内部 ExecutionService 执行,确保全生命周期指标与事件不发生分裂。
|
|
@@ -260,6 +268,8 @@ export interface PackageRuntime {
|
|
|
260
268
|
startAction(id: string, input: JsonValue, options?: RunOptions): Promise<ExecutionTicket>;
|
|
261
269
|
/** 查询任务执行记录列表 */
|
|
262
270
|
listRuns(options?: ListRunsOptions): Promise<RunRecord[]>;
|
|
271
|
+
/** 统计符合条件的任务执行记录总数 */
|
|
272
|
+
countRuns?(options?: ListRunsOptions): Promise<number>;
|
|
263
273
|
/** 查询指定运行标识的记录详情 */
|
|
264
274
|
getRun(runId: string): Promise<RunRecord | undefined>;
|
|
265
275
|
/** 取消指定在运行的任务 */
|
|
@@ -292,7 +302,7 @@ export interface PackageRuntime {
|
|
|
292
302
|
getState<T extends JsonValue = JsonValue>(actionId: string, key: string, options?: StateScopeOptions): Promise<T | undefined>;
|
|
293
303
|
/** 写入指定持久化状态值 */
|
|
294
304
|
setState<T extends JsonValue = JsonValue>(key: string, value: T, options?: StateScopeOptions): Promise<void>;
|
|
295
|
-
setState<T extends JsonValue = JsonValue>(actionId: string, key: string, value: T, options
|
|
305
|
+
setState<T extends JsonValue = JsonValue>(actionId: string, key: string, value: T, options?: StateScopeOptions): Promise<void>;
|
|
296
306
|
/** 删除指定持久化状态项 */
|
|
297
307
|
deleteState(key: string, options?: StateScopeOptions): Promise<boolean>;
|
|
298
308
|
deleteState(actionId: string, key: string, options?: StateScopeOptions): Promise<boolean>;
|
|
@@ -304,10 +314,10 @@ export interface PackageRuntime {
|
|
|
304
314
|
deleteActionState(actionId: string, key: string, options?: StateScopeOptions): Promise<boolean>;
|
|
305
315
|
/** 列出所有状态键 */
|
|
306
316
|
listStateKeys(options?: StateScopeOptions): Promise<string[]>;
|
|
307
|
-
listStateKeys(actionId
|
|
317
|
+
listStateKeys(actionId?: string, options?: StateScopeOptions): Promise<string[]>;
|
|
308
318
|
/** 清空指定持久化状态项 */
|
|
309
319
|
clearState(options?: StateScopeOptions): Promise<number>;
|
|
310
|
-
clearState(actionId
|
|
320
|
+
clearState(actionId?: string, options?: StateScopeOptions): Promise<number>;
|
|
311
321
|
/** 列出当前包在存储中的状态条目(含完整元数据) */
|
|
312
322
|
listStateEntries?(options?: any): Promise<StateEntry[]>;
|
|
313
323
|
/** 优雅关闭应用并收尾清理所有底层资源 */
|
|
@@ -320,4 +330,9 @@ export interface PackageRuntime {
|
|
|
320
330
|
*/
|
|
321
331
|
export interface HostManagedPackageRuntime extends PackageRuntime {
|
|
322
332
|
setActionInvoker(invoker?: ActionInvoker): void;
|
|
333
|
+
/**
|
|
334
|
+
* 内部存储准备入口(Host 持有者路径预热专用):打开包存储并完成运行记录恢复,
|
|
335
|
+
* 只扩展内部装配契约,不加入公共服务端口。
|
|
336
|
+
*/
|
|
337
|
+
prepareResources?(): Promise<void>;
|
|
323
338
|
}
|
package/dist/platform/index.d.ts
CHANGED
package/dist/platform/index.js
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 标准 ESM 解析上下文接口。
|
|
3
|
+
*/
|
|
4
|
+
export interface ResolveContext {
|
|
5
|
+
conditions: string[];
|
|
6
|
+
parentURL?: string;
|
|
7
|
+
importAttributes?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 标准 ESM nextResolve 函数契约。
|
|
11
|
+
*/
|
|
12
|
+
export type NextResolve = (specifier: string, context?: ResolveContext) => Promise<{
|
|
13
|
+
format?: string | null;
|
|
14
|
+
shortCircuit?: boolean;
|
|
15
|
+
url: string;
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* 全链路 ESM 路径重映射解析钩子。
|
|
19
|
+
* 遵循 TypeScript NodeNext 模块规范与 Node.js 官方标准钩子协议:
|
|
20
|
+
* - 仅拦截处于 file: 上下文中的相对路径导入(./、../、.、..);
|
|
21
|
+
* - 当目标请求路径在物理磁盘上不存在或为目录时:
|
|
22
|
+
* - 若以 .js 结尾,自动探测是否存在同名 .ts 或 .tsx;若存在,重定向返回;
|
|
23
|
+
* - 若以 .mjs 结尾,自动探测是否存在同名 .mts;若存在,重定向返回;
|
|
24
|
+
* - 若以 .cjs 结尾,自动探测是否存在同名 .cts;若存在,重定向返回;
|
|
25
|
+
* - 若无扩展名或为目录,自动探测补全 .ts、.tsx、.js、.mjs 以及目录 index 文件;
|
|
26
|
+
* - 针对已存在物理实体文件或非相对导入,全面透传 nextResolve。
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolve(specifier: string, context: ResolveContext, nextResolve: NextResolve): Promise<{
|
|
29
|
+
format?: string | null;
|
|
30
|
+
shortCircuit?: boolean;
|
|
31
|
+
url: string;
|
|
32
|
+
}>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { statSync } from "node:fs";
|
|
2
|
+
import { extname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
|
+
/**
|
|
5
|
+
* 判断指定文件路径是否存在且为常规物理文件。
|
|
6
|
+
* 使用 throwIfNoEntry: false 避免 ENOENT 抛错开销,保持微秒级解析性能。
|
|
7
|
+
*/
|
|
8
|
+
function isPhysicalFile(filePath) {
|
|
9
|
+
try {
|
|
10
|
+
const stat = statSync(filePath, { throwIfNoEntry: false });
|
|
11
|
+
return stat !== undefined && stat.isFile();
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 判断指定路径是否为物理目录。
|
|
19
|
+
*/
|
|
20
|
+
function isDirectory(filePath) {
|
|
21
|
+
try {
|
|
22
|
+
const stat = statSync(filePath, { throwIfNoEntry: false });
|
|
23
|
+
return stat !== undefined && stat.isDirectory();
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 全链路 ESM 路径重映射解析钩子。
|
|
31
|
+
* 遵循 TypeScript NodeNext 模块规范与 Node.js 官方标准钩子协议:
|
|
32
|
+
* - 仅拦截处于 file: 上下文中的相对路径导入(./、../、.、..);
|
|
33
|
+
* - 当目标请求路径在物理磁盘上不存在或为目录时:
|
|
34
|
+
* - 若以 .js 结尾,自动探测是否存在同名 .ts 或 .tsx;若存在,重定向返回;
|
|
35
|
+
* - 若以 .mjs 结尾,自动探测是否存在同名 .mts;若存在,重定向返回;
|
|
36
|
+
* - 若以 .cjs 结尾,自动探测是否存在同名 .cts;若存在,重定向返回;
|
|
37
|
+
* - 若无扩展名或为目录,自动探测补全 .ts、.tsx、.js、.mjs 以及目录 index 文件;
|
|
38
|
+
* - 针对已存在物理实体文件或非相对导入,全面透传 nextResolve。
|
|
39
|
+
*/
|
|
40
|
+
export async function resolve(specifier, context, nextResolve) {
|
|
41
|
+
const { parentURL } = context;
|
|
42
|
+
const isRelative = specifier.startsWith("./") ||
|
|
43
|
+
specifier.startsWith("../") ||
|
|
44
|
+
specifier === "." ||
|
|
45
|
+
specifier === "..";
|
|
46
|
+
if (isRelative && typeof parentURL === "string" && parentURL.startsWith("file:")) {
|
|
47
|
+
let targetUrl;
|
|
48
|
+
try {
|
|
49
|
+
targetUrl = new URL(specifier, parentURL);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return nextResolve(specifier, context);
|
|
53
|
+
}
|
|
54
|
+
const targetPath = fileURLToPath(targetUrl);
|
|
55
|
+
// 目标已存在且为常规文件,直接透传原生解析流程
|
|
56
|
+
if (isPhysicalFile(targetPath)) {
|
|
57
|
+
return nextResolve(specifier, context);
|
|
58
|
+
}
|
|
59
|
+
const isDir = isDirectory(targetPath);
|
|
60
|
+
const ext = extname(targetPath);
|
|
61
|
+
const candidates = [];
|
|
62
|
+
if (ext === ".js") {
|
|
63
|
+
const base = targetPath.slice(0, -3);
|
|
64
|
+
candidates.push(base + ".ts", base + ".tsx");
|
|
65
|
+
}
|
|
66
|
+
else if (ext === ".mjs") {
|
|
67
|
+
const base = targetPath.slice(0, -4);
|
|
68
|
+
candidates.push(base + ".mts");
|
|
69
|
+
}
|
|
70
|
+
else if (ext === ".cjs") {
|
|
71
|
+
const base = targetPath.slice(0, -4);
|
|
72
|
+
candidates.push(base + ".cts");
|
|
73
|
+
}
|
|
74
|
+
else if (!ext || isDir) {
|
|
75
|
+
if (!isDir) {
|
|
76
|
+
candidates.push(targetPath + ".ts", targetPath + ".tsx", targetPath + ".js", targetPath + ".mjs");
|
|
77
|
+
}
|
|
78
|
+
candidates.push(join(targetPath, "index.ts"), join(targetPath, "index.tsx"), join(targetPath, "index.js"), join(targetPath, "index.mjs"));
|
|
79
|
+
}
|
|
80
|
+
for (const candidate of candidates) {
|
|
81
|
+
if (isPhysicalFile(candidate)) {
|
|
82
|
+
const candidateUrl = pathToFileURL(candidate);
|
|
83
|
+
candidateUrl.search = targetUrl.search;
|
|
84
|
+
candidateUrl.hash = targetUrl.hash;
|
|
85
|
+
return nextResolve(candidateUrl.href, context);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return nextResolve(specifier, context);
|
|
90
|
+
}
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
export { resolve as esmResolveHook } from "./loader-hook.js";
|
|
2
|
+
/**
|
|
3
|
+
* 获取模块加载器解析钩子模块的绝对 URL。
|
|
4
|
+
* 兼容源码开发态(.ts)、编译分发态(.js)及独立 ES 模块态(.mjs)。
|
|
5
|
+
*/
|
|
6
|
+
export declare function getLoaderHookUrl(): string;
|
|
7
|
+
/**
|
|
8
|
+
* 注册全链路 ESM 路径重映射加载器钩子。
|
|
9
|
+
* 依托 Node.js 官方 module.register 标准机制,
|
|
10
|
+
* 在进程全局生命周期内只注册一次(基于 Symbol.for 保护)。
|
|
11
|
+
*/
|
|
12
|
+
export declare function registerModuleLoaderHook(): void;
|
|
1
13
|
/**
|
|
2
14
|
* 统一源码模块加载器接口。
|
|
3
15
|
* 解耦 Action 与各类扩展模块的具体加载机制(如 ECMAScript 原生 import、tsx 动态转译加载等)。
|
|
@@ -39,6 +51,7 @@ export declare function unwrapDefaultExport<T = any>(moduleExports: any): T;
|
|
|
39
51
|
* - 完全移除第三方转译运行时依赖
|
|
40
52
|
*/
|
|
41
53
|
export declare class NodeModuleLoader implements ModuleLoader {
|
|
54
|
+
constructor();
|
|
42
55
|
/**
|
|
43
56
|
* 解析模块标识符与路径,严格要求显式扩展名且拒绝目录补全。
|
|
44
57
|
*
|
|
@@ -1,7 +1,51 @@
|
|
|
1
|
+
import { register } from "node:module";
|
|
1
2
|
import { existsSync, statSync } from "node:fs";
|
|
2
3
|
import { dirname, extname, isAbsolute, resolve } from "node:path";
|
|
3
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
|
-
import { ActionDockError, ACTION_LOAD_FAILED } from "../errors.js";
|
|
5
|
+
import { ActionDockError, ACTION_LOAD_FAILED, MODULE_RESOLVE_FAILED } from "../errors.js";
|
|
6
|
+
export { resolve as esmResolveHook } from "./loader-hook.js";
|
|
7
|
+
/**
|
|
8
|
+
* 进程全局加载钩子防重注册标记 Symbol。
|
|
9
|
+
*/
|
|
10
|
+
const LOADER_HOOK_REGISTERED = Symbol.for("actiondock.esm.loader.hook.registered");
|
|
11
|
+
/**
|
|
12
|
+
* 获取模块加载器解析钩子模块的绝对 URL。
|
|
13
|
+
* 兼容源码开发态(.ts)、编译分发态(.js)及独立 ES 模块态(.mjs)。
|
|
14
|
+
*/
|
|
15
|
+
export function getLoaderHookUrl() {
|
|
16
|
+
const jsUrl = new URL("./loader-hook.js", import.meta.url);
|
|
17
|
+
if (existsSync(fileURLToPath(jsUrl))) {
|
|
18
|
+
return jsUrl.href;
|
|
19
|
+
}
|
|
20
|
+
const tsUrl = new URL("./loader-hook.ts", import.meta.url);
|
|
21
|
+
if (existsSync(fileURLToPath(tsUrl))) {
|
|
22
|
+
return tsUrl.href;
|
|
23
|
+
}
|
|
24
|
+
const mjsUrl = new URL("./loader-hook.mjs", import.meta.url);
|
|
25
|
+
if (existsSync(fileURLToPath(mjsUrl))) {
|
|
26
|
+
return mjsUrl.href;
|
|
27
|
+
}
|
|
28
|
+
return jsUrl.href;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 注册全链路 ESM 路径重映射加载器钩子。
|
|
32
|
+
* 依托 Node.js 官方 module.register 标准机制,
|
|
33
|
+
* 在进程全局生命周期内只注册一次(基于 Symbol.for 保护)。
|
|
34
|
+
*/
|
|
35
|
+
export function registerModuleLoaderHook() {
|
|
36
|
+
const globalRef = globalThis;
|
|
37
|
+
if (globalRef[LOADER_HOOK_REGISTERED]) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
globalRef[LOADER_HOOK_REGISTERED] = true;
|
|
41
|
+
try {
|
|
42
|
+
const hookUrl = getLoaderHookUrl();
|
|
43
|
+
register(hookUrl);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// 防御保护:环境不支持或受限场景安全降级
|
|
47
|
+
}
|
|
48
|
+
}
|
|
5
49
|
/**
|
|
6
50
|
* Node 原生 TypeScript 与 ESM 模块支持的扩展名集合。
|
|
7
51
|
*/
|
|
@@ -36,6 +80,9 @@ export function unwrapDefaultExport(moduleExports) {
|
|
|
36
80
|
* - 完全移除第三方转译运行时依赖
|
|
37
81
|
*/
|
|
38
82
|
export class NodeModuleLoader {
|
|
83
|
+
constructor() {
|
|
84
|
+
registerModuleLoaderHook();
|
|
85
|
+
}
|
|
39
86
|
/**
|
|
40
87
|
* 解析模块标识符与路径,严格要求显式扩展名且拒绝目录补全。
|
|
41
88
|
*
|
|
@@ -68,13 +115,13 @@ export class NodeModuleLoader {
|
|
|
68
115
|
const candidateBasePath = isAbsolute(target) ? target : resolve(baseDir, target);
|
|
69
116
|
const ext = extname(candidateBasePath);
|
|
70
117
|
if (!ext) {
|
|
71
|
-
throw new
|
|
118
|
+
throw new ActionDockError(MODULE_RESOLVE_FAILED, `Cannot resolve module '${specifier}' from '${parentPath || process.cwd()}': missing file extension. Explicit .ts, .mts, .js, or .mjs extension is required.`);
|
|
72
119
|
}
|
|
73
120
|
if (!ALLOWED_EXTENSIONS.has(ext)) {
|
|
74
|
-
throw new
|
|
121
|
+
throw new ActionDockError(MODULE_RESOLVE_FAILED, `Cannot resolve module '${specifier}' from '${parentPath || process.cwd()}': unsupported extension '${ext}'. Only .ts, .mts, .js, and .mjs are supported.`);
|
|
75
122
|
}
|
|
76
123
|
if (!existsSync(candidateBasePath)) {
|
|
77
|
-
throw new
|
|
124
|
+
throw new ActionDockError(MODULE_RESOLVE_FAILED, `Cannot resolve module '${specifier}' from '${parentPath || process.cwd()}': file not found`);
|
|
78
125
|
}
|
|
79
126
|
let stat;
|
|
80
127
|
try {
|
package/dist/platform/node.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { ProcessAPI } from "@actiondock/sdk";
|
|
2
|
-
import { type Clock } from "../
|
|
3
|
-
import { type ModuleLoader } from "
|
|
1
|
+
import type { Logger, ProcessAPI } from "@actiondock/sdk";
|
|
2
|
+
import { type Clock } from "../storage/clock.js";
|
|
3
|
+
import { type ModuleLoader } from "./module-loader.js";
|
|
4
4
|
import { ProcessManager } from "../process/process-manager.js";
|
|
5
5
|
import type { ProcessDriver } from "../process/driver.js";
|
|
6
6
|
import { type SqliteDriver } from "../storage/index.js";
|
|
7
|
-
import type {
|
|
7
|
+
import type { EventSink } from "../runtime/events.js";
|
|
8
|
+
import type { RuntimePlatform, StorageFactory } from "./types.js";
|
|
8
9
|
/**
|
|
9
10
|
* Node 平台构建配置选项。
|
|
10
11
|
*/
|
|
@@ -15,7 +16,10 @@ export interface NodePlatformOptions {
|
|
|
15
16
|
dataDir?: string;
|
|
16
17
|
/** 自定义家目录路径 */
|
|
17
18
|
customHome?: string;
|
|
18
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* 历史兼容保留属性(已废弃:文件系统抽象已由原生模块接管)。
|
|
21
|
+
* @deprecated 文件系统抽象已清理,该字段已无实际效果。
|
|
22
|
+
*/
|
|
19
23
|
rootDir?: string;
|
|
20
24
|
/** 自定义 SQLite 驱动工厂函数(必须返回满足同步契约的 SqliteDriver,默认实例化 NodeSqliteDriver) */
|
|
21
25
|
driverFactory?: (dbPath: string) => SqliteDriver;
|
|
@@ -27,12 +31,14 @@ export interface NodePlatformOptions {
|
|
|
27
31
|
processManager?: ProcessManager;
|
|
28
32
|
/** 自定义源码加载驱动(默认实例化 NodeModuleLoader) */
|
|
29
33
|
modules?: ModuleLoader;
|
|
30
|
-
/** 自定义文件系统实现(默认实例化 NodeFileSystem) */
|
|
31
|
-
files?: FileSystem;
|
|
32
34
|
/** 自定义时钟驱动(默认实例化 SystemClock) */
|
|
33
35
|
clock?: Clock;
|
|
34
36
|
/** 自定义存储工厂(默认基于 NodeSqliteDriver 构造) */
|
|
35
37
|
storage?: StorageFactory;
|
|
38
|
+
/** 可选注入的执行事件接收器 */
|
|
39
|
+
eventSink?: EventSink;
|
|
40
|
+
/** 可选注入的统一日志记录器 */
|
|
41
|
+
logger?: Logger;
|
|
36
42
|
}
|
|
37
43
|
/**
|
|
38
44
|
* 创建 Node 运行时平台实例。
|
|
@@ -40,9 +46,14 @@ export interface NodePlatformOptions {
|
|
|
40
46
|
* - NodeSqliteDriver 同步持久化存储驱动
|
|
41
47
|
* - NodeProcessDriver 原生进程驱动与 ProcessManager 受管进程引擎
|
|
42
48
|
* - NodeModuleLoader 原生源码加载器
|
|
43
|
-
* - NodeFileSystem 文件系统
|
|
44
49
|
* - SystemClock 系统时钟
|
|
45
50
|
*
|
|
51
|
+
* 资源按需装配原则:
|
|
52
|
+
* - clock 与存储工厂可立即创建(存储工厂本身不打开任何数据库);
|
|
53
|
+
* - process 与 modules 采用缓存访问器,首次真正访问时才装配默认驱动,
|
|
54
|
+
* 静态发现等旁观路径不触发进程管理器与模块加载钩子的创建成本;
|
|
55
|
+
* - 模块加载钩子注册收敛至 NodeModuleLoader 构造内部,不再在平台工厂入口执行。
|
|
56
|
+
*
|
|
46
57
|
* @param options 平台配置选项
|
|
47
58
|
*/
|
|
48
59
|
export declare function createNodePlatform(options?: NodePlatformOptions): RuntimePlatform;
|
package/dist/platform/node.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { existsSync, mkdirSync } from "node:fs";
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { ActionDockError, STORAGE_INIT_FAILED } from "../errors.js";
|
|
4
|
+
import { SystemClock } from "../storage/clock.js";
|
|
5
|
+
import { NodeModuleLoader } from "./module-loader.js";
|
|
5
6
|
import { NodeProcessDriver } from "../process/process-driver.js";
|
|
6
7
|
import { ProcessManager } from "../process/process-manager.js";
|
|
7
8
|
import { NodeSqliteDriver } from "../storage/sqlite-driver.js";
|
|
8
9
|
import { resolveDatabasePath, resolveGlobalDatabasePath, SqliteRuntimeStorage, } from "../storage/index.js";
|
|
9
|
-
import { NodeFileSystem } from "./node-fs.js";
|
|
10
10
|
function ensureDirectoryForDb(dbPath) {
|
|
11
11
|
if (dbPath !== ":memory:") {
|
|
12
12
|
const dir = dirname(dbPath);
|
|
@@ -18,7 +18,7 @@ function ensureDirectoryForDb(dbPath) {
|
|
|
18
18
|
if (err?.code === "EEXIST" || err?.code === "EISDIR") {
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
|
-
throw new
|
|
21
|
+
throw new ActionDockError(STORAGE_INIT_FAILED, `Failed to create data directory '${dir}' for database '${dbPath}': ${err?.message || String(err)}`, { cause: err });
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -29,25 +29,48 @@ function ensureDirectoryForDb(dbPath) {
|
|
|
29
29
|
* - NodeSqliteDriver 同步持久化存储驱动
|
|
30
30
|
* - NodeProcessDriver 原生进程驱动与 ProcessManager 受管进程引擎
|
|
31
31
|
* - NodeModuleLoader 原生源码加载器
|
|
32
|
-
* - NodeFileSystem 文件系统
|
|
33
32
|
* - SystemClock 系统时钟
|
|
34
33
|
*
|
|
34
|
+
* 资源按需装配原则:
|
|
35
|
+
* - clock 与存储工厂可立即创建(存储工厂本身不打开任何数据库);
|
|
36
|
+
* - process 与 modules 采用缓存访问器,首次真正访问时才装配默认驱动,
|
|
37
|
+
* 静态发现等旁观路径不触发进程管理器与模块加载钩子的创建成本;
|
|
38
|
+
* - 模块加载钩子注册收敛至 NodeModuleLoader 构造内部,不再在平台工厂入口执行。
|
|
39
|
+
*
|
|
35
40
|
* @param options 平台配置选项
|
|
36
41
|
*/
|
|
37
42
|
export function createNodePlatform(options = {}) {
|
|
38
43
|
const platformName = options.name ?? "node";
|
|
39
44
|
const clock = options.clock ?? new SystemClock();
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
// - 进程接口缓存访问器:显式注入直接透传;缺省时按需装配一次默认驱动链
|
|
46
|
+
let cachedProcess;
|
|
47
|
+
const resolveProcess = () => {
|
|
48
|
+
if (options.process) {
|
|
49
|
+
return options.process;
|
|
50
|
+
}
|
|
51
|
+
if (!cachedProcess) {
|
|
52
|
+
const processDriver = options.processDriver ?? new NodeProcessDriver();
|
|
53
|
+
const processManager = options.processManager ?? new ProcessManager({ driver: processDriver });
|
|
54
|
+
cachedProcess = processManager.forOwner({
|
|
55
|
+
tenantId: "default",
|
|
56
|
+
principalId: "default",
|
|
57
|
+
packageInstanceId: "default",
|
|
58
|
+
generationId: "default",
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return cachedProcess;
|
|
62
|
+
};
|
|
63
|
+
// - 模块加载器缓存访问器:首次访问时才创建默认加载器(构造内部注册加载钩子)
|
|
64
|
+
let cachedModules;
|
|
65
|
+
const resolveModules = () => {
|
|
66
|
+
if (options.modules) {
|
|
67
|
+
return options.modules;
|
|
68
|
+
}
|
|
69
|
+
if (!cachedModules) {
|
|
70
|
+
cachedModules = new NodeModuleLoader();
|
|
71
|
+
}
|
|
72
|
+
return cachedModules;
|
|
73
|
+
};
|
|
51
74
|
const createDriver = options.driverFactory ?? ((dbPath) => new NodeSqliteDriver(dbPath));
|
|
52
75
|
const storage = options.storage ?? {
|
|
53
76
|
createStorage(packageId, opts) {
|
|
@@ -65,6 +88,7 @@ export function createNodePlatform(options = {}) {
|
|
|
65
88
|
driver: createDriver(dbPath),
|
|
66
89
|
recoverOrphans: opts?.recoverOrphans === true,
|
|
67
90
|
retentionPolicy: opts?.retentionPolicy,
|
|
91
|
+
logger: options.logger,
|
|
68
92
|
});
|
|
69
93
|
},
|
|
70
94
|
createGlobalStorage(opts) {
|
|
@@ -83,15 +107,21 @@ export function createNodePlatform(options = {}) {
|
|
|
83
107
|
clock,
|
|
84
108
|
driver: createDriver(dbPath),
|
|
85
109
|
recoverOrphans: opts?.recoverOrphans === true,
|
|
110
|
+
logger: options.logger,
|
|
86
111
|
});
|
|
87
112
|
},
|
|
88
113
|
};
|
|
89
|
-
|
|
114
|
+
const platform = {
|
|
90
115
|
name: platformName,
|
|
91
116
|
clock,
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
117
|
+
eventSink: options.eventSink,
|
|
118
|
+
get process() {
|
|
119
|
+
return resolveProcess();
|
|
120
|
+
},
|
|
121
|
+
get modules() {
|
|
122
|
+
return resolveModules();
|
|
123
|
+
},
|
|
95
124
|
storage,
|
|
96
125
|
};
|
|
126
|
+
return platform;
|
|
97
127
|
}
|