@actiondock/core 2.9.1 → 2.11.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 +12 -15
- 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 +24 -92
- package/dist/doctor/checks/registry.js +1 -1
- 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 +85 -4
- package/dist/errors.js +114 -4
- 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 +565 -150
- 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/describe.d.ts +6 -0
- package/dist/input/describe.js +26 -1
- 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 +2 -2
- package/dist/input/validation-mapper.d.ts +1 -1
- package/dist/invocation/policy.js +2 -0
- 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 +31 -526
- 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
package/dist/ipc/diagnostic.js
CHANGED
|
@@ -1,29 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* 诊断流极简转发器(DiagnosticForwarder)。
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* 2. 实时监测字节总量与秒级传输速率上限。
|
|
7
|
-
* 3. 达到阈值后立即停止对外转发、向诊断通道记录截断事件。
|
|
8
|
-
* 4. 持续以非阻塞方式静默排空后续数据流,避免子进程因管道背压堆积死锁。
|
|
4
|
+
* 将子进程输出流(stdout/stderr)的数据转发至目标流。
|
|
5
|
+
* 严禁静默丢数据,遇到写入异常即时透传。
|
|
9
6
|
*/
|
|
10
7
|
export class DiagnosticForwarder {
|
|
11
|
-
maxBytes;
|
|
12
|
-
maxRateBytesPerSec;
|
|
13
8
|
target;
|
|
14
9
|
prefix;
|
|
15
|
-
|
|
16
|
-
totalBytesEmitted = 0;
|
|
17
|
-
windowStartMs = Date.now();
|
|
18
|
-
bytesInCurrentWindow = 0;
|
|
19
|
-
truncated = false;
|
|
10
|
+
onError;
|
|
20
11
|
attachedStreams = new Map();
|
|
21
12
|
constructor(options = {}) {
|
|
22
|
-
this.maxBytes = options.maxBytes ?? 512 * 1024;
|
|
23
|
-
this.maxRateBytesPerSec = options.maxRateBytesPerSec ?? 64 * 1024;
|
|
24
13
|
this.target = options.target ?? process.stderr;
|
|
25
14
|
this.prefix = options.prefix ?? "";
|
|
26
|
-
this.
|
|
15
|
+
this.onError = options.onError;
|
|
27
16
|
}
|
|
28
17
|
/**
|
|
29
18
|
* 绑定并监听可读流(如 childProcess.stdout 或 childProcess.stderr)。
|
|
@@ -36,52 +25,30 @@ export class DiagnosticForwarder {
|
|
|
36
25
|
return;
|
|
37
26
|
const handler = (chunk) => {
|
|
38
27
|
const buf = typeof chunk === "string" ? Buffer.from(chunk, "utf-8") : chunk;
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this.windowStartMs = now;
|
|
44
|
-
this.bytesInCurrentWindow = 0;
|
|
45
|
-
}
|
|
46
|
-
if (this.truncated) {
|
|
47
|
-
// 已截断:仅排空丢弃数据,不转发,保持流处于读取排空状态
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
// 检查容量与速率上限
|
|
51
|
-
let exceedReason = null;
|
|
52
|
-
if (this.totalBytesEmitted + len > this.maxBytes) {
|
|
53
|
-
exceedReason = "size_limit";
|
|
54
|
-
}
|
|
55
|
-
else if (this.bytesInCurrentWindow + len > this.maxRateBytesPerSec) {
|
|
56
|
-
exceedReason = "rate_limit";
|
|
57
|
-
}
|
|
58
|
-
if (exceedReason) {
|
|
59
|
-
this.truncated = true;
|
|
60
|
-
const tag = label ? `[${label}] ` : "";
|
|
61
|
-
const notice = `\n[Supervisor] ${tag}Diagnostic output exceeded ${exceedReason === "size_limit" ? `size limit (${this.maxBytes} bytes)` : `rate limit (${this.maxRateBytesPerSec} B/s)`}. Forwarding suspended; draining stream.\n`;
|
|
62
|
-
try {
|
|
63
|
-
this.target.write(notice);
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
// 忽略写入失败
|
|
67
|
-
}
|
|
68
|
-
this.onTruncated?.(exceedReason);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
// 正常转发
|
|
72
|
-
this.totalBytesEmitted += len;
|
|
73
|
-
this.bytesInCurrentWindow += len;
|
|
28
|
+
const effectivePrefix = this.prefix || (label ? `[${label}] ` : "");
|
|
29
|
+
const data = effectivePrefix
|
|
30
|
+
? Buffer.concat([Buffer.from(effectivePrefix, "utf-8"), buf])
|
|
31
|
+
: buf;
|
|
74
32
|
try {
|
|
75
|
-
|
|
76
|
-
|
|
33
|
+
this.target.write(data, (err) => {
|
|
34
|
+
if (err) {
|
|
35
|
+
if (this.onError) {
|
|
36
|
+
this.onError(err);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.target.emit("error", err);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
if (this.onError) {
|
|
46
|
+
this.onError(err);
|
|
77
47
|
}
|
|
78
48
|
else {
|
|
79
|
-
this.target.
|
|
49
|
+
this.target.emit("error", err);
|
|
80
50
|
}
|
|
81
51
|
}
|
|
82
|
-
catch {
|
|
83
|
-
// 忽略目标写入异常
|
|
84
|
-
}
|
|
85
52
|
};
|
|
86
53
|
stream.on("data", handler);
|
|
87
54
|
this.attachedStreams.set(stream, handler);
|
package/dist/ipc/host.js
CHANGED
|
@@ -16,8 +16,9 @@ const IPC_METHOD_HANDLERS = {
|
|
|
16
16
|
describePlaybook: async (service, a) => service.discovery.describePlaybook(a[0]),
|
|
17
17
|
runAction: async (service, a) => service.execution.run(a[0], a[1], a[2]),
|
|
18
18
|
startAction: async (service, a) => service.execution.start(a[0], a[1], a[2]),
|
|
19
|
-
listRuns: async (service, a) => service.runs.list(a[0]),
|
|
20
|
-
|
|
19
|
+
listRuns: async (service, a) => service.runs.list(a[0], a[1]),
|
|
20
|
+
countRuns: async (service, a) => typeof service.runs.count === "function" ? service.runs.count(a[0], a[1]) : undefined,
|
|
21
|
+
getRun: async (service, a) => service.runs.get(a[0], a[1]),
|
|
21
22
|
cancelRun: async (service, a) => service.runs.cancel(a[0], a[1]),
|
|
22
23
|
clearRuns: async (service, a) => service.runs.clear ? await service.runs.clear(a[0]) : 0,
|
|
23
24
|
cleanExpiredRuns: async (service, a) => service.runs.cleanExpired ? await service.runs.cleanExpired(a[0]) : 0,
|
|
@@ -75,8 +76,11 @@ export async function serveParentIpc(service) {
|
|
|
75
76
|
return arg;
|
|
76
77
|
}
|
|
77
78
|
const { [IPC_SIGNAL_MARKER]: _marker, ...rest } = arg;
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
let controller = activeControllers.get(id);
|
|
80
|
+
if (!controller) {
|
|
81
|
+
controller = new AbortController();
|
|
82
|
+
activeControllers.set(id, controller);
|
|
83
|
+
}
|
|
80
84
|
return { ...rest, signal: controller.signal };
|
|
81
85
|
};
|
|
82
86
|
// 监听父进程断连或退出信号
|
|
@@ -119,15 +123,23 @@ export async function serveParentIpc(service) {
|
|
|
119
123
|
}
|
|
120
124
|
}
|
|
121
125
|
catch (err) {
|
|
126
|
+
const isAbort = err?.name === "AbortError" ||
|
|
127
|
+
err?.code === "ABORT_ERR" ||
|
|
128
|
+
err?.code === "EXECUTION_ABORTED" ||
|
|
129
|
+
err?.code === "OPERATION_ABORTED";
|
|
122
130
|
const response = {
|
|
123
131
|
id,
|
|
124
132
|
type: "response",
|
|
125
133
|
ok: false,
|
|
126
134
|
error: {
|
|
127
|
-
code: err?.code || SERVICE_ERROR,
|
|
135
|
+
code: err?.code || (isAbort ? "OPERATION_ABORTED" : SERVICE_ERROR),
|
|
128
136
|
message: err?.message || String(err),
|
|
129
137
|
stack: err?.stack,
|
|
130
|
-
details: err?.details
|
|
138
|
+
details: err?.details !== undefined
|
|
139
|
+
? (typeof err?.details === "object" && err?.details !== null && err?.name === "AbortError"
|
|
140
|
+
? { name: err?.name, ...err.details }
|
|
141
|
+
: err.details)
|
|
142
|
+
: (err?.name === "AbortError" ? { name: err?.name } : undefined),
|
|
131
143
|
},
|
|
132
144
|
};
|
|
133
145
|
if (process.send) {
|
|
@@ -144,7 +156,9 @@ export async function serveParentIpc(service) {
|
|
|
144
156
|
const abortMsg = msg;
|
|
145
157
|
const controller = activeControllers.get(abortMsg.id);
|
|
146
158
|
if (controller) {
|
|
147
|
-
|
|
159
|
+
const abortError = new Error(abortMsg.reason || "Execution was aborted via IPC");
|
|
160
|
+
abortError.name = "AbortError";
|
|
161
|
+
controller.abort(abortError);
|
|
148
162
|
}
|
|
149
163
|
}
|
|
150
164
|
else if (msg.type === "close") {
|
package/dist/ipc/service.d.ts
CHANGED
|
@@ -2,6 +2,10 @@ import { type ChildProcess } from "node:child_process";
|
|
|
2
2
|
import type { PackageInfo } from "../package/types.js";
|
|
3
3
|
import type { ActionDockService, ConfigPort, DiscoveryPort, ExecutionPort, RunsPort, StatePort } from "../service/types.js";
|
|
4
4
|
import type { IpcServiceOptions } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* 创建标准 AbortError 异常对象。
|
|
7
|
+
*/
|
|
8
|
+
export declare function createAbortError(reason?: unknown): Error;
|
|
5
9
|
/**
|
|
6
10
|
* 跨进程取消信号占位标记字段名。
|
|
7
11
|
* AbortSignal 不可序列化,序列化 options 时把 signal 字段替换为该标记,
|
|
@@ -12,6 +16,16 @@ export declare const IPC_SIGNAL_MARKER = "__ipcSignal";
|
|
|
12
16
|
* 判断执行选项中是否携带跨进程取消信号占位标记。
|
|
13
17
|
*/
|
|
14
18
|
export declare function hasIpcSignalMarker(value: unknown): value is Record<string, unknown>;
|
|
19
|
+
/**
|
|
20
|
+
* 序列化执行选项与查询选项的边界收敛函数。
|
|
21
|
+
*
|
|
22
|
+
* 序列化边界决策:
|
|
23
|
+
* - 剥离不可序列化对象:AbortSignal 无法通过 Node IPC 通道传递,在此转换为 IPC_SIGNAL_MARKER 占位标记,由远端宿主根据标记重建 AbortController 接入取消链路。
|
|
24
|
+
* - 过滤非安全值:全面剔除函数、undefined、Symbol 与 BigInt 等无法安全跨进程传递的值,防止 IPC 序列化异常或意外的远端反射。
|
|
25
|
+
* - 循环引用防御:递归遍历嵌套对象(如 config 配置项或 filter 筛选条件)时基于调用栈祖先集合进行环检测,阻断循环引用进入 IPC 通道,且不误伤跨字段复用的合法对象。
|
|
26
|
+
* - 支持跨进程选项透传:安全保留 RunOptions 与 RunReadOptions、ListRunsOptions 中的合法字段(包含 timeoutMs、config、requestId、limit、offset、packageId、action、status、since、until、requestIds、filter 等)。
|
|
27
|
+
*/
|
|
28
|
+
export declare function markIpcSignal<T extends Record<string, any>>(options?: T): Record<string, unknown> | undefined;
|
|
15
29
|
/**
|
|
16
30
|
* 基于 Node IPC 监督进程通信通道的 ActionDockService 实现。
|
|
17
31
|
* 遵循标准 Service Ports 体系,隔离子进程生命周期并暴露结构化服务端口。
|
package/dist/ipc/service.js
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { fork } from "node:child_process";
|
|
3
3
|
import { DiagnosticForwarder } from "./diagnostic.js";
|
|
4
|
-
import { ActionDockError, CAPABILITY_UNAVAILABLE, EXECUTION_ABORTED, HOST_PROCESS_EXITED, IPC_ERROR, SERVICE_CLOSED, } from "../errors.js";
|
|
4
|
+
import { ActionDockError, CAPABILITY_UNAVAILABLE, EXECUTION_ABORTED, HOST_PROCESS_EXITED, INVALID_ARGUMENT, IPC_ERROR, SERVICE_CLOSED, } from "../errors.js";
|
|
5
|
+
/**
|
|
6
|
+
* 创建标准 AbortError 异常对象。
|
|
7
|
+
*/
|
|
8
|
+
export function createAbortError(reason) {
|
|
9
|
+
const message = reason instanceof Error
|
|
10
|
+
? (reason.message || "The operation was aborted")
|
|
11
|
+
: reason !== undefined
|
|
12
|
+
? String(reason)
|
|
13
|
+
: "The operation was aborted";
|
|
14
|
+
const err = new Error(message, reason !== undefined ? { cause: reason } : undefined);
|
|
15
|
+
err.name = "AbortError";
|
|
16
|
+
return err;
|
|
17
|
+
}
|
|
5
18
|
/**
|
|
6
19
|
* 跨进程取消信号占位标记字段名。
|
|
7
20
|
* AbortSignal 不可序列化,序列化 options 时把 signal 字段替换为该标记,
|
|
@@ -17,22 +30,79 @@ export function hasIpcSignalMarker(value) {
|
|
|
17
30
|
value[IPC_SIGNAL_MARKER] === true);
|
|
18
31
|
}
|
|
19
32
|
/**
|
|
20
|
-
*
|
|
33
|
+
* 安全收敛可跨进程传递的数据值,过滤函数、undefined、Symbol、BigInt 并防御循环引用。
|
|
34
|
+
*/
|
|
35
|
+
function sanitizeIpcValue(value, ancestors) {
|
|
36
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
if (typeof value === "undefined" || typeof value === "function" || typeof value === "symbol" || typeof value === "bigint") {
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
if (typeof value === "object") {
|
|
43
|
+
if (ancestors.has(value)) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
ancestors.add(value);
|
|
47
|
+
try {
|
|
48
|
+
if (Array.isArray(value)) {
|
|
49
|
+
const result = [];
|
|
50
|
+
for (const item of value) {
|
|
51
|
+
const sanitized = sanitizeIpcValue(item, ancestors);
|
|
52
|
+
if (sanitized !== undefined) {
|
|
53
|
+
result.push(sanitized);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
const result = {};
|
|
59
|
+
for (const [key, val] of Object.entries(value)) {
|
|
60
|
+
const sanitized = sanitizeIpcValue(val, ancestors);
|
|
61
|
+
if (sanitized !== undefined) {
|
|
62
|
+
result[key] = sanitized;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
finally {
|
|
68
|
+
ancestors.delete(value);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 序列化执行选项与查询选项的边界收敛函数。
|
|
75
|
+
*
|
|
76
|
+
* 序列化边界决策:
|
|
77
|
+
* - 剥离不可序列化对象:AbortSignal 无法通过 Node IPC 通道传递,在此转换为 IPC_SIGNAL_MARKER 占位标记,由远端宿主根据标记重建 AbortController 接入取消链路。
|
|
78
|
+
* - 过滤非安全值:全面剔除函数、undefined、Symbol 与 BigInt 等无法安全跨进程传递的值,防止 IPC 序列化异常或意外的远端反射。
|
|
79
|
+
* - 循环引用防御:递归遍历嵌套对象(如 config 配置项或 filter 筛选条件)时基于调用栈祖先集合进行环检测,阻断循环引用进入 IPC 通道,且不误伤跨字段复用的合法对象。
|
|
80
|
+
* - 支持跨进程选项透传:安全保留 RunOptions 与 RunReadOptions、ListRunsOptions 中的合法字段(包含 timeoutMs、config、requestId、limit、offset、packageId、action、status、since、until、requestIds、filter 等)。
|
|
21
81
|
*/
|
|
22
|
-
function markIpcSignal(options) {
|
|
23
|
-
if (!options)
|
|
82
|
+
export function markIpcSignal(options) {
|
|
83
|
+
if (!options || typeof options !== "object")
|
|
24
84
|
return undefined;
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
85
|
+
const ancestors = new Set();
|
|
86
|
+
ancestors.add(options);
|
|
87
|
+
try {
|
|
88
|
+
const clean = {};
|
|
89
|
+
for (const [key, value] of Object.entries(options)) {
|
|
90
|
+
if (key === "signal") {
|
|
91
|
+
if (value) {
|
|
92
|
+
clean[IPC_SIGNAL_MARKER] = true;
|
|
93
|
+
}
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const sanitized = sanitizeIpcValue(value, ancestors);
|
|
97
|
+
if (sanitized !== undefined) {
|
|
98
|
+
clean[key] = sanitized;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return clean;
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
ancestors.delete(options);
|
|
34
105
|
}
|
|
35
|
-
return clean;
|
|
36
106
|
}
|
|
37
107
|
/**
|
|
38
108
|
* 基于 Node IPC 监督进程通信通道的 ActionDockService 实现。
|
|
@@ -51,8 +121,6 @@ export class IpcActionDockService {
|
|
|
51
121
|
management;
|
|
52
122
|
constructor(options) {
|
|
53
123
|
this.forwarder = new DiagnosticForwarder({
|
|
54
|
-
maxBytes: options.maxDiagnosticBytes,
|
|
55
|
-
maxRateBytesPerSec: options.maxDiagnosticRate,
|
|
56
124
|
target: options.diagnosticTarget,
|
|
57
125
|
});
|
|
58
126
|
if (options.childProcess) {
|
|
@@ -66,7 +134,7 @@ export class IpcActionDockService {
|
|
|
66
134
|
});
|
|
67
135
|
}
|
|
68
136
|
else {
|
|
69
|
-
throw new
|
|
137
|
+
throw new ActionDockError(INVALID_ARGUMENT, "IpcActionDockService requires either 'childProcess' or 'scriptPath'");
|
|
70
138
|
}
|
|
71
139
|
if (this.child.stdout) {
|
|
72
140
|
this.forwarder.attach(this.child.stdout, "stdout");
|
|
@@ -93,7 +161,13 @@ export class IpcActionDockService {
|
|
|
93
161
|
pending.resolve(resp.data);
|
|
94
162
|
}
|
|
95
163
|
else {
|
|
96
|
-
const
|
|
164
|
+
const isAbort = resp.error?.code === "EXECUTION_ABORTED" ||
|
|
165
|
+
resp.error?.code === "OPERATION_ABORTED" ||
|
|
166
|
+
resp.error?.code === "ABORT_ERR" ||
|
|
167
|
+
resp.error?.details?.name === "AbortError";
|
|
168
|
+
const err = isAbort
|
|
169
|
+
? createAbortError(resp.error?.message)
|
|
170
|
+
: new ActionDockError(resp.error?.code || IPC_ERROR, resp.error?.message || "IPC Service call failed", resp.error?.details);
|
|
97
171
|
pending.reject(err);
|
|
98
172
|
}
|
|
99
173
|
}
|
|
@@ -129,7 +203,7 @@ export class IpcActionDockService {
|
|
|
129
203
|
* 生成方法级端口转发器:把端口方法调用映射为 callRemote 远端调用。
|
|
130
204
|
* 方法名与参数列表的对应关系即唯一事实源,杜绝手写转发样板膨胀。
|
|
131
205
|
*/
|
|
132
|
-
const forward = (method, args) => self.callRemote(method, args);
|
|
206
|
+
const forward = (method, args, signal) => self.callRemote(method, args, signal);
|
|
133
207
|
this.discovery = {
|
|
134
208
|
async listPackages() {
|
|
135
209
|
return forward("listPackages", []);
|
|
@@ -171,11 +245,38 @@ export class IpcActionDockService {
|
|
|
171
245
|
},
|
|
172
246
|
};
|
|
173
247
|
this.runs = {
|
|
174
|
-
async list(query) {
|
|
175
|
-
|
|
248
|
+
async list(query, options) {
|
|
249
|
+
const signal = options?.signal ?? query?.signal;
|
|
250
|
+
if (signal?.aborted) {
|
|
251
|
+
throw createAbortError(signal.reason);
|
|
252
|
+
}
|
|
253
|
+
const serializableQuery = markIpcSignal(query);
|
|
254
|
+
const serializableOptions = markIpcSignal(options);
|
|
255
|
+
const args = serializableOptions !== undefined
|
|
256
|
+
? [serializableQuery ?? {}, serializableOptions]
|
|
257
|
+
: [serializableQuery];
|
|
258
|
+
return forward("listRuns", args, signal);
|
|
259
|
+
},
|
|
260
|
+
async count(query, options) {
|
|
261
|
+
const signal = options?.signal ?? query?.signal;
|
|
262
|
+
if (signal?.aborted) {
|
|
263
|
+
throw createAbortError(signal.reason);
|
|
264
|
+
}
|
|
265
|
+
const serializableQuery = markIpcSignal(query);
|
|
266
|
+
const serializableOptions = markIpcSignal(options);
|
|
267
|
+
const args = serializableOptions !== undefined
|
|
268
|
+
? [serializableQuery ?? {}, serializableOptions]
|
|
269
|
+
: [serializableQuery];
|
|
270
|
+
return forward("countRuns", args, signal);
|
|
176
271
|
},
|
|
177
|
-
async get(runId) {
|
|
178
|
-
const
|
|
272
|
+
async get(runId, options) {
|
|
273
|
+
const signal = options?.signal ?? options?.query?.signal;
|
|
274
|
+
if (signal?.aborted) {
|
|
275
|
+
throw createAbortError(signal.reason);
|
|
276
|
+
}
|
|
277
|
+
const serializableOptions = markIpcSignal(options);
|
|
278
|
+
const args = serializableOptions !== undefined ? [runId, serializableOptions] : [runId];
|
|
279
|
+
const res = await forward("getRun", args, signal);
|
|
179
280
|
return res ?? undefined;
|
|
180
281
|
},
|
|
181
282
|
async cancel(runId, reason) {
|
|
@@ -243,9 +344,7 @@ export class IpcActionDockService {
|
|
|
243
344
|
}
|
|
244
345
|
await this.readyPromise;
|
|
245
346
|
if (signal?.aborted) {
|
|
246
|
-
|
|
247
|
-
err.name = "AbortError";
|
|
248
|
-
throw err;
|
|
347
|
+
throw createAbortError(signal.reason);
|
|
249
348
|
}
|
|
250
349
|
const id = randomUUID();
|
|
251
350
|
const message = {
|
|
@@ -258,6 +357,13 @@ export class IpcActionDockService {
|
|
|
258
357
|
if (signal && !signal.aborted) {
|
|
259
358
|
onAbort = () => {
|
|
260
359
|
this.sendAbort(id);
|
|
360
|
+
if (method !== "runAction") {
|
|
361
|
+
const pending = this.pendingCalls.get(id);
|
|
362
|
+
if (pending) {
|
|
363
|
+
this.pendingCalls.delete(id);
|
|
364
|
+
pending.reject(createAbortError(signal.reason));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
261
367
|
};
|
|
262
368
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
263
369
|
}
|
package/dist/ipc/types.d.ts
CHANGED
|
@@ -46,10 +46,6 @@ export interface IpcServiceOptions {
|
|
|
46
46
|
cwd?: string;
|
|
47
47
|
/** 环境变量 */
|
|
48
48
|
env?: NodeJS.ProcessEnv;
|
|
49
|
-
/** 诊断流最大缓冲字节数 */
|
|
50
|
-
maxDiagnosticBytes?: number;
|
|
51
|
-
/** 诊断流每秒最大字节速率 */
|
|
52
|
-
maxDiagnosticRate?: number;
|
|
53
49
|
/** 诊断流目标输出 */
|
|
54
50
|
diagnosticTarget?: any;
|
|
55
51
|
/** 是否启用管理端口(默认 true) */
|
package/dist/package/index.d.ts
CHANGED
|
@@ -10,13 +10,12 @@ export { createPackageRuntime, DefaultPackageRuntime, } from "./runtime.js";
|
|
|
10
10
|
export { createNonClosingStorageView } from "./storage-view.js";
|
|
11
11
|
export { findExecutable } from "../utils/index.js";
|
|
12
12
|
export type { PackageRuntime, PackageRuntimeOptions, PackageInfo, ActionSpec, ActionSummary, PlaybookSpec, PlaybookSummary, } from "./types.js";
|
|
13
|
-
export type { RuntimePlatform,
|
|
14
|
-
export { type Clock, SystemClock, } from "../
|
|
15
|
-
export type { ModuleLoader } from "../
|
|
13
|
+
export type { RuntimePlatform, StorageFactory, StorageFactoryOptions, GlobalStorageFactoryOptions, } from "../platform/types.js";
|
|
14
|
+
export { type Clock, SystemClock, } from "../storage/clock.js";
|
|
15
|
+
export type { ModuleLoader } from "../platform/module-loader.js";
|
|
16
16
|
export { InMemoryEventSink, type EventSink, } from "../runtime/events.js";
|
|
17
17
|
export { ProcessManager, type ProcessOwner, } from "../process/process-manager.js";
|
|
18
|
-
export type { ProcessExecutor } from "
|
|
19
|
-
export { NodeProcessExecutor } from "../process/process-executor.js";
|
|
18
|
+
export type { ProcessAPI as ProcessExecutor } from "@actiondock/sdk";
|
|
20
19
|
export type { ProcessDriver, ProcessDriverCallbacks, ProcessDriverHandle, ProcessHandle, ProcessObserver, } from "../process/driver.js";
|
|
21
20
|
export { createStorage, resolveDatabasePath, } from "../storage/index.js";
|
|
22
21
|
export { SqliteRuntimeStorage } from "../storage/sqlite.js";
|
package/dist/package/index.js
CHANGED
|
@@ -9,10 +9,9 @@
|
|
|
9
9
|
export { createPackageRuntime, DefaultPackageRuntime, } from "./runtime.js";
|
|
10
10
|
export { createNonClosingStorageView } from "./storage-view.js";
|
|
11
11
|
export { findExecutable } from "../utils/index.js";
|
|
12
|
-
export { SystemClock, } from "../
|
|
12
|
+
export { SystemClock, } from "../storage/clock.js";
|
|
13
13
|
export { InMemoryEventSink, } from "../runtime/events.js";
|
|
14
14
|
export { ProcessManager, } from "../process/process-manager.js";
|
|
15
|
-
export { NodeProcessExecutor } from "../process/process-executor.js";
|
|
16
15
|
// 存储契约与驱动
|
|
17
16
|
export { createStorage, resolveDatabasePath, } from "../storage/index.js";
|
|
18
17
|
export { SqliteRuntimeStorage } from "../storage/sqlite.js";
|
|
@@ -7,6 +7,13 @@ import type { ActionSpec, ActionSummary, ConfigValueView, HostManagedPackageRunt
|
|
|
7
7
|
/**
|
|
8
8
|
* ActionDock 统一包运行时默认实现。
|
|
9
9
|
* 封装并管理单个 Action Package 的执行引擎、静态元数据索引、配置与状态存储生命周期。
|
|
10
|
+
*
|
|
11
|
+
* 资源按需装配契约:
|
|
12
|
+
* - 构造函数只完成身份、清单与内存注入动作的归一化,不打开数据库、
|
|
13
|
+
* 不创建进程接口、不注册模块加载钩子、不实例化执行服务;
|
|
14
|
+
* - 包存储、执行服务、全局存储与配置解析器拆分为内部资源槽位,
|
|
15
|
+
* 首次实际调用时准备并缓存复用;
|
|
16
|
+
* - info / list / describe / 规程发现等静态查询全程零资源创建。
|
|
10
17
|
*/
|
|
11
18
|
export declare class DefaultPackageRuntime implements HostManagedPackageRuntime {
|
|
12
19
|
readonly identity: PackageIdentity;
|
|
@@ -15,15 +22,20 @@ export declare class DefaultPackageRuntime implements HostManagedPackageRuntime
|
|
|
15
22
|
readonly generationId: string;
|
|
16
23
|
readonly packageRoot?: string;
|
|
17
24
|
readonly projectConfig: ProjectConfig;
|
|
25
|
+
readonly inMemory: boolean;
|
|
18
26
|
private readonly platform;
|
|
19
|
-
private readonly storage;
|
|
20
|
-
private readonly globalStorage?;
|
|
21
|
-
private readonly executionService;
|
|
22
27
|
private readonly actionsMap;
|
|
23
28
|
private readonly options;
|
|
24
|
-
private runtimeConfig;
|
|
25
29
|
private isClosed;
|
|
26
|
-
private
|
|
30
|
+
private storageSlot;
|
|
31
|
+
private executionSlot;
|
|
32
|
+
/** 全局存储:显式注入或首次准备后固定,配合 ownership 判定关闭归属 */
|
|
33
|
+
private globalStorageRes?;
|
|
34
|
+
private runtimeConfig?;
|
|
35
|
+
/** 执行委托暂存:执行服务尚未创建时只保存,不触发资源初始化 */
|
|
36
|
+
private pendingInvoker?;
|
|
37
|
+
/** Host 会话级恢复标记:存储准备阶段收敛执行一次,避免重复执行恢复链 */
|
|
38
|
+
private recoveredForHostSession;
|
|
27
39
|
/** 静态清单索引缓存:包静态事实(根目录、配置、内存注入集合)在实例生命周期内不变,解析结果同实例内复用 */
|
|
28
40
|
private staticActionIndex?;
|
|
29
41
|
private staticPlaybookIndex?;
|
|
@@ -39,6 +51,58 @@ export declare class DefaultPackageRuntime implements HostManagedPackageRuntime
|
|
|
39
51
|
* 聚合逻辑委托 static-index 单一事实源;同实例内复用首次解析结果。
|
|
40
52
|
*/
|
|
41
53
|
private getStaticPlaybookMap;
|
|
54
|
+
private assertOpen;
|
|
55
|
+
/**
|
|
56
|
+
* 准备包存储:打开(或复用注入的)包数据库,等待可选的 ensureInitialized,
|
|
57
|
+
* 并在持有者模式下完成运行记录恢复(允许返回 Promise 的恢复接口必须被等待)。
|
|
58
|
+
* 并发首次调用共享同一在途 Promise;失败时释放新建资源、清空失败 Promise、透传原始错误。
|
|
59
|
+
*/
|
|
60
|
+
private ensureStorage;
|
|
61
|
+
private openStorageAsync;
|
|
62
|
+
/** 构造包存储工厂选项(单一事实源,异步与同步打开路径共用) */
|
|
63
|
+
private buildStorageOptions;
|
|
64
|
+
/**
|
|
65
|
+
* Host 会话级运行记录恢复:同实例生命周期内最多执行一次。
|
|
66
|
+
* 允许返回 Promise 的恢复接口被等待:恢复完成(或失败透传)前存储不发布;
|
|
67
|
+
* 恢复失败沿用既有可观测处理(告警透传),不因异步化静默丢失。
|
|
68
|
+
*/
|
|
69
|
+
private recoverForHostSessionOnce;
|
|
70
|
+
/**
|
|
71
|
+
* 准备全局存储:显式注入优先,其次 Host 共享提供函数,最后独立使用平台存储工厂。
|
|
72
|
+
* 同步契约:RuntimeConfig 与 ctx.config.get() 的读取是同步的,故全局库必须同步可得。
|
|
73
|
+
*/
|
|
74
|
+
private ensureGlobalStorageSync;
|
|
75
|
+
/**
|
|
76
|
+
* 异步准备全局存储:供执行服务装配前调用,保证可选的异步初始化完成。
|
|
77
|
+
* 同步路径(RuntimeConfig 读取)仍走 ensureGlobalStorageSync 复用同一实例。
|
|
78
|
+
*/
|
|
79
|
+
private ensureGlobalStorage;
|
|
80
|
+
/**
|
|
81
|
+
* 准备配置解析器:依赖包存储与全局存储(五层优先级链既有实现不变)。
|
|
82
|
+
* 同步契约:RuntimeConfig 与 ctx.config.get() 的读取是同步的,故同步打开包库;
|
|
83
|
+
* 若异步准备已在途,同步路径仅在实例已发布后复用,避免双打开竞态。
|
|
84
|
+
*/
|
|
85
|
+
private ensureRuntimeConfig;
|
|
86
|
+
/**
|
|
87
|
+
* 获取已就绪的包存储(同步契约专用):
|
|
88
|
+
* - 已发布实例直接复用;
|
|
89
|
+
* - 异步准备在途时等待其结算后复用同一实例;
|
|
90
|
+
* - 未准备时同步打开并登记在途 Promise 已完成状态。
|
|
91
|
+
* 单一事实源:同步打开也走 buildStorageOptions,并补齐会话恢复等待语义的同步近似。
|
|
92
|
+
*/
|
|
93
|
+
private getStorageAlreadyPrepared;
|
|
94
|
+
/** 同步打开包存储(仅当异步准备从未发起时使用) */
|
|
95
|
+
private openStorageSync;
|
|
96
|
+
/**
|
|
97
|
+
* 准备执行服务:等待存储与全局存储就绪后创建唯一 DefaultExecutionService。
|
|
98
|
+
* 失败时只回收执行初始化独自新建的资源,不关闭仍被状态查询使用的包存储。
|
|
99
|
+
*/
|
|
100
|
+
private ensureExecutionService;
|
|
101
|
+
private buildExecutionService;
|
|
102
|
+
/** 异步等待存储准备完成(供执行准备与异步入口复用;单一赋值入口) */
|
|
103
|
+
private prepareStorageAsync;
|
|
104
|
+
/** 获取已创建的执行服务(若存在),不触发创建 */
|
|
105
|
+
private peekExecutionService;
|
|
42
106
|
info(options?: {
|
|
43
107
|
exposeDebugInfo?: boolean;
|
|
44
108
|
}): Promise<PackageInfo>;
|
|
@@ -50,6 +114,8 @@ export declare class DefaultPackageRuntime implements HostManagedPackageRuntime
|
|
|
50
114
|
runAction(id: string, input: JsonValue, options?: RunOptions): Promise<ExecutionResult>;
|
|
51
115
|
startAction(id: string, input: JsonValue, options?: RunOptions): Promise<ExecutionTicket>;
|
|
52
116
|
startInvocation(actionId: string, input: JsonValue, context: InvocationContext): Promise<ExecutionTicket>;
|
|
117
|
+
/** 执行前统一准备:关闭检查与执行服务就绪 */
|
|
118
|
+
private prepareExecution;
|
|
53
119
|
getRun(runId: string): Promise<RunRecord | undefined>;
|
|
54
120
|
cancelRun(runId: string, reason?: string): Promise<CancelResult>;
|
|
55
121
|
events(runId: string, options?: {
|
|
@@ -58,42 +124,47 @@ export declare class DefaultPackageRuntime implements HostManagedPackageRuntime
|
|
|
58
124
|
maxQueueSize?: number;
|
|
59
125
|
}): AsyncIterable<ExecutionEvent>;
|
|
60
126
|
setActionInvoker(invoker?: ActionInvoker): void;
|
|
127
|
+
/**
|
|
128
|
+
* Host 持有者路径预热入口:完成包存储准备(含运行记录恢复),不创建执行服务。
|
|
129
|
+
* 延迟装配下旁观路径零资源创建,持有者工厂在返回前调用本方法保持既有初始化时机。
|
|
130
|
+
*/
|
|
131
|
+
prepareResources(): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* 显式触发运行记录恢复(Host 持有者路径兼容入口)。
|
|
134
|
+
* 延迟装配下恢复已收敛到存储准备路径,本方法确保存储已就绪后按需补一次会话恢复。
|
|
135
|
+
*/
|
|
61
136
|
recoverDeadSessionRuns(sessionId?: string): void;
|
|
62
137
|
listConfig(): Promise<ConfigValueView[]>;
|
|
63
138
|
getConfig(key: string): Promise<ConfigValueView>;
|
|
64
139
|
setConfig(key: string, value: JsonValue): Promise<void>;
|
|
65
140
|
deleteConfig(key: string): Promise<boolean>;
|
|
66
141
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* 完成重载消歧后委托 mergeStateScope 计算最终生效的命名空间:
|
|
70
|
-
* - (actionId, key, options) 形态:位置 actionId 参与冲突校验;
|
|
71
|
-
* - (key, options) 扁平形态:首参是状态键,options.actionId 属合法显式指定。
|
|
72
|
-
*/
|
|
73
|
-
private resolveStateScope;
|
|
74
|
-
/**
|
|
75
|
-
* 合并位置 actionId 与 options.actionId 并计算最终命名空间(单一事实源)。
|
|
76
|
-
*
|
|
77
|
-
* - positionalActionId 非 undefined:调用形态携带位置 actionId,
|
|
78
|
-
* options.actionId 与其冲突时抛出异常(空串同样参与冲突校验);
|
|
79
|
-
* - positionalActionId 为 undefined:无位置 actionId 的扁平调用形态,
|
|
80
|
-
* options.actionId 属合法显式指定,直接采纳。
|
|
142
|
+
* 将可能携带命名空间前缀的状态键解码为 (namespace, key)。
|
|
143
|
+
* 解码失败时按无命名空间处理。
|
|
81
144
|
*/
|
|
82
|
-
private
|
|
145
|
+
private decodeStateKeyParts;
|
|
146
|
+
private hasExplicitStateScope;
|
|
147
|
+
private computeStateNamespace;
|
|
148
|
+
private getStateInternal;
|
|
149
|
+
private setStateInternal;
|
|
150
|
+
private deleteStateInternal;
|
|
151
|
+
private listStateKeysInternal;
|
|
152
|
+
private clearStateInternal;
|
|
83
153
|
getState<T extends JsonValue = JsonValue>(key: string, options?: StateScopeOptions): Promise<T | undefined>;
|
|
84
154
|
getState<T extends JsonValue = JsonValue>(actionId: string, key: string, options?: StateScopeOptions): Promise<T | undefined>;
|
|
85
155
|
setState<T extends JsonValue = JsonValue>(key: string, value: T, options?: StateScopeOptions): Promise<void>;
|
|
86
|
-
setState<T extends JsonValue = JsonValue>(actionId: string, key: string, value: T, options
|
|
156
|
+
setState<T extends JsonValue = JsonValue>(actionId: string, key: string, value: T, options?: StateScopeOptions): Promise<void>;
|
|
87
157
|
deleteState(key: string, options?: StateScopeOptions): Promise<boolean>;
|
|
88
158
|
deleteState(actionId: string, key: string, options?: StateScopeOptions): Promise<boolean>;
|
|
89
159
|
getActionState<T extends JsonValue = JsonValue>(actionId: string, key: string, options?: StateScopeOptions): Promise<T | undefined>;
|
|
90
160
|
setActionState<T extends JsonValue = JsonValue>(actionId: string, key: string, value: T, options?: StateScopeOptions): Promise<void>;
|
|
91
161
|
deleteActionState(actionId: string, key: string, options?: StateScopeOptions): Promise<boolean>;
|
|
92
162
|
listStateKeys(options?: StateScopeOptions): Promise<string[]>;
|
|
93
|
-
listStateKeys(actionId
|
|
163
|
+
listStateKeys(actionId?: string, options?: StateScopeOptions): Promise<string[]>;
|
|
94
164
|
clearState(options?: StateScopeOptions): Promise<number>;
|
|
95
|
-
clearState(actionId
|
|
165
|
+
clearState(actionId?: string, options?: StateScopeOptions): Promise<number>;
|
|
96
166
|
listRuns(options?: ListRunsOptions): Promise<RunRecord[]>;
|
|
167
|
+
countRuns(options?: ListRunsOptions): Promise<number>;
|
|
97
168
|
clearRuns(options?: {
|
|
98
169
|
actionId?: string;
|
|
99
170
|
status?: string;
|