@zhuixin/engine-client 0.2.2 → 0.2.4
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/dist/index.cjs +39 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +39 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -37,9 +37,11 @@ var import_node_child_process = require("child_process");
|
|
|
37
37
|
var import_node_readline = __toESM(require("readline"), 1);
|
|
38
38
|
var import_protocol = require("@zhuixin/protocol");
|
|
39
39
|
var EngineClient = class {
|
|
40
|
-
constructor(executable, childEnv = {}) {
|
|
40
|
+
constructor(executable, childEnv = {}, onChild, timeoutMs = 20 * 6e4) {
|
|
41
41
|
this.executable = executable;
|
|
42
42
|
this.childEnv = childEnv;
|
|
43
|
+
this.onChild = onChild;
|
|
44
|
+
this.timeoutMs = timeoutMs;
|
|
43
45
|
}
|
|
44
46
|
child = null;
|
|
45
47
|
sequence = 0;
|
|
@@ -55,14 +57,35 @@ var EngineClient = class {
|
|
|
55
57
|
APPTRACE_WORKSPACE_ROOT: workspacePath
|
|
56
58
|
}
|
|
57
59
|
});
|
|
60
|
+
this.onChild?.(this.child);
|
|
61
|
+
this.child.on("error", (error) => this.failAll(error.message));
|
|
62
|
+
this.child.on("exit", (code) => {
|
|
63
|
+
this.failAll(`Engine exited${code === null ? "" : ` with code ${code}`}`);
|
|
64
|
+
});
|
|
58
65
|
const lines = import_node_readline.default.createInterface({ input: this.child.stdout });
|
|
59
66
|
lines.on("line", (line) => {
|
|
60
67
|
const parsed = import_protocol.engineResponseSchema.safeParse(JSON.parse(line));
|
|
61
68
|
if (!parsed.success) return;
|
|
62
|
-
|
|
69
|
+
if (parsed.data.id === "unknown" && !parsed.data.ok) {
|
|
70
|
+
this.failAll(
|
|
71
|
+
parsed.data.error?.message ?? "Engine rejected the request"
|
|
72
|
+
);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const entry = this.pending.get(parsed.data.id);
|
|
76
|
+
if (!entry) return;
|
|
77
|
+
clearTimeout(entry.timer);
|
|
63
78
|
this.pending.delete(parsed.data.id);
|
|
79
|
+
entry.resolve(parsed.data);
|
|
64
80
|
});
|
|
65
81
|
}
|
|
82
|
+
failAll(message) {
|
|
83
|
+
for (const entry of this.pending.values()) {
|
|
84
|
+
clearTimeout(entry.timer);
|
|
85
|
+
entry.reject(new Error(message));
|
|
86
|
+
}
|
|
87
|
+
this.pending.clear();
|
|
88
|
+
}
|
|
66
89
|
async execute(workspacePath, capability, input = {}) {
|
|
67
90
|
await this.start(workspacePath);
|
|
68
91
|
const id = `req-${++this.sequence}`;
|
|
@@ -84,12 +107,20 @@ var EngineClient = class {
|
|
|
84
107
|
};
|
|
85
108
|
return new Promise((resolve, reject) => {
|
|
86
109
|
if (!this.child) return reject(new Error("Engine is not running"));
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
110
|
+
const timer = setTimeout(() => {
|
|
111
|
+
this.pending.delete(id);
|
|
112
|
+
reject(new Error(`Engine request timed out after ${this.timeoutMs}ms`));
|
|
113
|
+
}, this.timeoutMs);
|
|
114
|
+
this.pending.set(id, {
|
|
115
|
+
timer,
|
|
116
|
+
reject,
|
|
117
|
+
resolve: (response) => {
|
|
118
|
+
if (!response.ok || !response.result) {
|
|
119
|
+
reject(new Error(response.error?.message ?? "Engine request failed"));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
resolve(response.result);
|
|
91
123
|
}
|
|
92
|
-
resolve(response.result);
|
|
93
124
|
});
|
|
94
125
|
this.child.stdin.write(`${JSON.stringify(request)}
|
|
95
126
|
`);
|
|
@@ -98,7 +129,7 @@ var EngineClient = class {
|
|
|
98
129
|
close() {
|
|
99
130
|
this.child?.kill("SIGTERM");
|
|
100
131
|
this.child = null;
|
|
101
|
-
this.
|
|
132
|
+
this.failAll("Engine client closed");
|
|
102
133
|
}
|
|
103
134
|
};
|
|
104
135
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport readline from \"node:readline\";\nimport {\n PROTOCOL_VERSION,\n engineResponseSchema,\n type EngineCapability,\n type EngineRequest,\n type EngineResponse\n} from \"@zhuixin/protocol\";\n\nexport class EngineClient {\n private child: ChildProcessWithoutNullStreams | null = null;\n private sequence = 0;\n private readonly pending = new Map
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport readline from \"node:readline\";\nimport {\n PROTOCOL_VERSION,\n engineResponseSchema,\n type EngineCapability,\n type EngineRequest,\n type EngineResponse\n} from \"@zhuixin/protocol\";\n\nexport class EngineClient {\n private child: ChildProcessWithoutNullStreams | null = null;\n private sequence = 0;\n private readonly pending = new Map<\n string,\n {\n resolve: (value: EngineResponse) => void;\n reject: (error: Error) => void;\n timer: NodeJS.Timeout;\n }\n >();\n\n constructor(\n private readonly executable: string,\n private readonly childEnv: NodeJS.ProcessEnv = {},\n private readonly onChild?: (child: ChildProcessWithoutNullStreams) => void,\n private readonly timeoutMs = 20 * 60_000\n ) {}\n\n async start(workspacePath: string): Promise<void> {\n if (this.child) return;\n const spec = this.executable.endsWith(\".js\")\n ? { command: process.execPath, args: [this.executable, \"engine\"] }\n : { command: this.executable, args: [\"engine\"] };\n this.child = spawn(spec.command, spec.args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: {\n ...process.env,\n ...this.childEnv,\n APPTRACE_WORKSPACE_ROOT: workspacePath\n }\n });\n this.onChild?.(this.child);\n this.child.on(\"error\", (error) => this.failAll(error.message));\n this.child.on(\"exit\", (code) => {\n this.failAll(`Engine exited${code === null ? \"\" : ` with code ${code}`}`);\n });\n const lines = readline.createInterface({ input: this.child.stdout });\n lines.on(\"line\", (line) => {\n const parsed = engineResponseSchema.safeParse(JSON.parse(line));\n if (!parsed.success) return;\n if (parsed.data.id === \"unknown\" && !parsed.data.ok) {\n this.failAll(\n parsed.data.error?.message ?? \"Engine rejected the request\"\n );\n return;\n }\n const entry = this.pending.get(parsed.data.id);\n if (!entry) return;\n clearTimeout(entry.timer);\n this.pending.delete(parsed.data.id);\n entry.resolve(parsed.data);\n });\n }\n\n private failAll(message: string): void {\n for (const entry of this.pending.values()) {\n clearTimeout(entry.timer);\n entry.reject(new Error(message));\n }\n this.pending.clear();\n }\n\n async execute(\n workspacePath: string,\n capability: EngineCapability,\n input: {\n targetId?: string;\n artifactId?: string;\n values?: Record<string, unknown>;\n license?: { licenseId?: string; features: string[] };\n licenseToken?: string;\n } = {}\n ): Promise<Record<string, unknown>> {\n await this.start(workspacePath);\n const id = `req-${++this.sequence}`;\n const request: EngineRequest = {\n id,\n protocolVersion: PROTOCOL_VERSION,\n operation: \"execute\",\n capability,\n workspacePath,\n ...(input.targetId ? { targetId: input.targetId } : {}),\n ...(input.artifactId ? { artifactId: input.artifactId } : {}),\n ...(input.values ? { input: input.values } : {}),\n ...(input.license || input.licenseToken\n ? {\n license: {\n ...(input.license ?? { features: [] }),\n ...(input.licenseToken ? { token: input.licenseToken } : {})\n }\n }\n : {})\n };\n return new Promise((resolve, reject) => {\n if (!this.child) return reject(new Error(\"Engine is not running\"));\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error(`Engine request timed out after ${this.timeoutMs}ms`));\n }, this.timeoutMs);\n this.pending.set(id, {\n timer,\n reject,\n resolve: (response) => {\n if (!response.ok || !response.result) {\n reject(new Error(response.error?.message ?? \"Engine request failed\"));\n return;\n }\n resolve(response.result);\n }\n });\n this.child.stdin.write(`${JSON.stringify(request)}\\n`);\n });\n }\n\n close(): void {\n this.child?.kill(\"SIGTERM\");\n this.child = null;\n this.failAll(\"Engine client closed\");\n }\n}\n"],"mappings":"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","names":["readline"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
import { ChildProcessWithoutNullStreams } from 'node:child_process';
|
|
1
2
|
import { EngineCapability } from '@zhuixin/protocol';
|
|
2
3
|
|
|
3
4
|
declare class EngineClient {
|
|
4
5
|
private readonly executable;
|
|
5
6
|
private readonly childEnv;
|
|
7
|
+
private readonly onChild?;
|
|
8
|
+
private readonly timeoutMs;
|
|
6
9
|
private child;
|
|
7
10
|
private sequence;
|
|
8
11
|
private readonly pending;
|
|
9
|
-
constructor(executable: string, childEnv?: NodeJS.ProcessEnv);
|
|
12
|
+
constructor(executable: string, childEnv?: NodeJS.ProcessEnv, onChild?: ((child: ChildProcessWithoutNullStreams) => void) | undefined, timeoutMs?: number);
|
|
10
13
|
start(workspacePath: string): Promise<void>;
|
|
14
|
+
private failAll;
|
|
11
15
|
execute(workspacePath: string, capability: EngineCapability, input?: {
|
|
12
16
|
targetId?: string;
|
|
13
17
|
artifactId?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
import { ChildProcessWithoutNullStreams } from 'node:child_process';
|
|
1
2
|
import { EngineCapability } from '@zhuixin/protocol';
|
|
2
3
|
|
|
3
4
|
declare class EngineClient {
|
|
4
5
|
private readonly executable;
|
|
5
6
|
private readonly childEnv;
|
|
7
|
+
private readonly onChild?;
|
|
8
|
+
private readonly timeoutMs;
|
|
6
9
|
private child;
|
|
7
10
|
private sequence;
|
|
8
11
|
private readonly pending;
|
|
9
|
-
constructor(executable: string, childEnv?: NodeJS.ProcessEnv);
|
|
12
|
+
constructor(executable: string, childEnv?: NodeJS.ProcessEnv, onChild?: ((child: ChildProcessWithoutNullStreams) => void) | undefined, timeoutMs?: number);
|
|
10
13
|
start(workspacePath: string): Promise<void>;
|
|
14
|
+
private failAll;
|
|
11
15
|
execute(workspacePath: string, capability: EngineCapability, input?: {
|
|
12
16
|
targetId?: string;
|
|
13
17
|
artifactId?: string;
|
package/dist/index.js
CHANGED
|
@@ -6,9 +6,11 @@ import {
|
|
|
6
6
|
engineResponseSchema
|
|
7
7
|
} from "@zhuixin/protocol";
|
|
8
8
|
var EngineClient = class {
|
|
9
|
-
constructor(executable, childEnv = {}) {
|
|
9
|
+
constructor(executable, childEnv = {}, onChild, timeoutMs = 20 * 6e4) {
|
|
10
10
|
this.executable = executable;
|
|
11
11
|
this.childEnv = childEnv;
|
|
12
|
+
this.onChild = onChild;
|
|
13
|
+
this.timeoutMs = timeoutMs;
|
|
12
14
|
}
|
|
13
15
|
child = null;
|
|
14
16
|
sequence = 0;
|
|
@@ -24,14 +26,35 @@ var EngineClient = class {
|
|
|
24
26
|
APPTRACE_WORKSPACE_ROOT: workspacePath
|
|
25
27
|
}
|
|
26
28
|
});
|
|
29
|
+
this.onChild?.(this.child);
|
|
30
|
+
this.child.on("error", (error) => this.failAll(error.message));
|
|
31
|
+
this.child.on("exit", (code) => {
|
|
32
|
+
this.failAll(`Engine exited${code === null ? "" : ` with code ${code}`}`);
|
|
33
|
+
});
|
|
27
34
|
const lines = readline.createInterface({ input: this.child.stdout });
|
|
28
35
|
lines.on("line", (line) => {
|
|
29
36
|
const parsed = engineResponseSchema.safeParse(JSON.parse(line));
|
|
30
37
|
if (!parsed.success) return;
|
|
31
|
-
|
|
38
|
+
if (parsed.data.id === "unknown" && !parsed.data.ok) {
|
|
39
|
+
this.failAll(
|
|
40
|
+
parsed.data.error?.message ?? "Engine rejected the request"
|
|
41
|
+
);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const entry = this.pending.get(parsed.data.id);
|
|
45
|
+
if (!entry) return;
|
|
46
|
+
clearTimeout(entry.timer);
|
|
32
47
|
this.pending.delete(parsed.data.id);
|
|
48
|
+
entry.resolve(parsed.data);
|
|
33
49
|
});
|
|
34
50
|
}
|
|
51
|
+
failAll(message) {
|
|
52
|
+
for (const entry of this.pending.values()) {
|
|
53
|
+
clearTimeout(entry.timer);
|
|
54
|
+
entry.reject(new Error(message));
|
|
55
|
+
}
|
|
56
|
+
this.pending.clear();
|
|
57
|
+
}
|
|
35
58
|
async execute(workspacePath, capability, input = {}) {
|
|
36
59
|
await this.start(workspacePath);
|
|
37
60
|
const id = `req-${++this.sequence}`;
|
|
@@ -53,12 +76,20 @@ var EngineClient = class {
|
|
|
53
76
|
};
|
|
54
77
|
return new Promise((resolve, reject) => {
|
|
55
78
|
if (!this.child) return reject(new Error("Engine is not running"));
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
79
|
+
const timer = setTimeout(() => {
|
|
80
|
+
this.pending.delete(id);
|
|
81
|
+
reject(new Error(`Engine request timed out after ${this.timeoutMs}ms`));
|
|
82
|
+
}, this.timeoutMs);
|
|
83
|
+
this.pending.set(id, {
|
|
84
|
+
timer,
|
|
85
|
+
reject,
|
|
86
|
+
resolve: (response) => {
|
|
87
|
+
if (!response.ok || !response.result) {
|
|
88
|
+
reject(new Error(response.error?.message ?? "Engine request failed"));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
resolve(response.result);
|
|
60
92
|
}
|
|
61
|
-
resolve(response.result);
|
|
62
93
|
});
|
|
63
94
|
this.child.stdin.write(`${JSON.stringify(request)}
|
|
64
95
|
`);
|
|
@@ -67,7 +98,7 @@ var EngineClient = class {
|
|
|
67
98
|
close() {
|
|
68
99
|
this.child?.kill("SIGTERM");
|
|
69
100
|
this.child = null;
|
|
70
|
-
this.
|
|
101
|
+
this.failAll("Engine client closed");
|
|
71
102
|
}
|
|
72
103
|
};
|
|
73
104
|
export {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport readline from \"node:readline\";\nimport {\n PROTOCOL_VERSION,\n engineResponseSchema,\n type EngineCapability,\n type EngineRequest,\n type EngineResponse\n} from \"@zhuixin/protocol\";\n\nexport class EngineClient {\n private child: ChildProcessWithoutNullStreams | null = null;\n private sequence = 0;\n private readonly pending = new Map
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport readline from \"node:readline\";\nimport {\n PROTOCOL_VERSION,\n engineResponseSchema,\n type EngineCapability,\n type EngineRequest,\n type EngineResponse\n} from \"@zhuixin/protocol\";\n\nexport class EngineClient {\n private child: ChildProcessWithoutNullStreams | null = null;\n private sequence = 0;\n private readonly pending = new Map<\n string,\n {\n resolve: (value: EngineResponse) => void;\n reject: (error: Error) => void;\n timer: NodeJS.Timeout;\n }\n >();\n\n constructor(\n private readonly executable: string,\n private readonly childEnv: NodeJS.ProcessEnv = {},\n private readonly onChild?: (child: ChildProcessWithoutNullStreams) => void,\n private readonly timeoutMs = 20 * 60_000\n ) {}\n\n async start(workspacePath: string): Promise<void> {\n if (this.child) return;\n const spec = this.executable.endsWith(\".js\")\n ? { command: process.execPath, args: [this.executable, \"engine\"] }\n : { command: this.executable, args: [\"engine\"] };\n this.child = spawn(spec.command, spec.args, {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n env: {\n ...process.env,\n ...this.childEnv,\n APPTRACE_WORKSPACE_ROOT: workspacePath\n }\n });\n this.onChild?.(this.child);\n this.child.on(\"error\", (error) => this.failAll(error.message));\n this.child.on(\"exit\", (code) => {\n this.failAll(`Engine exited${code === null ? \"\" : ` with code ${code}`}`);\n });\n const lines = readline.createInterface({ input: this.child.stdout });\n lines.on(\"line\", (line) => {\n const parsed = engineResponseSchema.safeParse(JSON.parse(line));\n if (!parsed.success) return;\n if (parsed.data.id === \"unknown\" && !parsed.data.ok) {\n this.failAll(\n parsed.data.error?.message ?? \"Engine rejected the request\"\n );\n return;\n }\n const entry = this.pending.get(parsed.data.id);\n if (!entry) return;\n clearTimeout(entry.timer);\n this.pending.delete(parsed.data.id);\n entry.resolve(parsed.data);\n });\n }\n\n private failAll(message: string): void {\n for (const entry of this.pending.values()) {\n clearTimeout(entry.timer);\n entry.reject(new Error(message));\n }\n this.pending.clear();\n }\n\n async execute(\n workspacePath: string,\n capability: EngineCapability,\n input: {\n targetId?: string;\n artifactId?: string;\n values?: Record<string, unknown>;\n license?: { licenseId?: string; features: string[] };\n licenseToken?: string;\n } = {}\n ): Promise<Record<string, unknown>> {\n await this.start(workspacePath);\n const id = `req-${++this.sequence}`;\n const request: EngineRequest = {\n id,\n protocolVersion: PROTOCOL_VERSION,\n operation: \"execute\",\n capability,\n workspacePath,\n ...(input.targetId ? { targetId: input.targetId } : {}),\n ...(input.artifactId ? { artifactId: input.artifactId } : {}),\n ...(input.values ? { input: input.values } : {}),\n ...(input.license || input.licenseToken\n ? {\n license: {\n ...(input.license ?? { features: [] }),\n ...(input.licenseToken ? { token: input.licenseToken } : {})\n }\n }\n : {})\n };\n return new Promise((resolve, reject) => {\n if (!this.child) return reject(new Error(\"Engine is not running\"));\n const timer = setTimeout(() => {\n this.pending.delete(id);\n reject(new Error(`Engine request timed out after ${this.timeoutMs}ms`));\n }, this.timeoutMs);\n this.pending.set(id, {\n timer,\n reject,\n resolve: (response) => {\n if (!response.ok || !response.result) {\n reject(new Error(response.error?.message ?? \"Engine request failed\"));\n return;\n }\n resolve(response.result);\n }\n });\n this.child.stdin.write(`${JSON.stringify(request)}\\n`);\n });\n }\n\n close(): void {\n this.child?.kill(\"SIGTERM\");\n this.child = null;\n this.failAll(\"Engine client closed\");\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhuixin/engine-client",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "AppTrace client for the private analysis engine",
|
|
6
6
|
"repository": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@zhuixin/protocol": "0.2.
|
|
25
|
+
"@zhuixin/protocol": "0.2.4"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"tsup": "^8.5.0",
|