omkit 0.1.2 → 0.1.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/actions/command.d.ts +4 -15
- package/dist/actions/command.js +41 -29
- package/dist/system/proc.d.ts +2 -0
- package/dist/system/proc.js +1 -1
- package/package.json +1 -1
|
@@ -7,21 +7,10 @@ export interface CommandOptions {
|
|
|
7
7
|
/** Let this command inherit the orchestrator's debugger (default false). */
|
|
8
8
|
inheritDebugger?: boolean;
|
|
9
9
|
}
|
|
10
|
-
declare function build(name: string, cmdOrFile: string, argsOrOptions: readonly string[] | CommandOptions, maybeOptions: CommandOptions): import("../index.ts").ActionInstance<import("zx").ProcessOutput, import("../core/types.ts").NoEvents, void>;
|
|
11
10
|
/**
|
|
12
|
-
* Runs a shell
|
|
11
|
+
* Runs an executable directly (without a shell) as an action instance.
|
|
13
12
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* - `command(name, file, args, options?)` — an executable **plus an args array**; each arg
|
|
17
|
-
* is quoted individually, so spaces and `=`/paths in args are safe without hand-quoting.
|
|
18
|
-
*
|
|
19
|
-
* Output streams into the run's log under `name`; a non-zero exit fails the action;
|
|
20
|
-
* teardown kills the child tree. For interpolated events or a daemon loop, drop to
|
|
21
|
-
* `action(...).run(...)`.
|
|
13
|
+
* Output streams into the run's log under `name`; a non-zero exit fails the
|
|
14
|
+
* action; teardown force-kills the process tree.
|
|
22
15
|
*/
|
|
23
|
-
export declare
|
|
24
|
-
(name: string, cmd: string, options?: CommandOptions): ReturnType<typeof build>;
|
|
25
|
-
(name: string, file: string, args: readonly string[], options?: CommandOptions): ReturnType<typeof build>;
|
|
26
|
-
};
|
|
27
|
-
export {};
|
|
16
|
+
export declare function command(name: string, file: string, args?: readonly string[], options?: CommandOptions): import("../index.ts").ActionInstance<void, import("../core/types.ts").NoEvents, void>;
|
package/dist/actions/command.js
CHANGED
|
@@ -1,38 +1,50 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
1
2
|
import path from "node:path";
|
|
2
3
|
import { action } from "../core/action.js";
|
|
4
|
+
import { killTree, streamLines } from "../system/proc.js";
|
|
3
5
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* Runs an executable directly (without a shell) as an action instance.
|
|
7
|
+
*
|
|
8
|
+
* Output streams into the run's log under `name`; a non-zero exit fails the
|
|
9
|
+
* action; teardown force-kills the process tree.
|
|
7
10
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const hasArgs = Array.isArray(argsOrOptions);
|
|
11
|
-
const args = hasArgs ? argsOrOptions : undefined;
|
|
12
|
-
const options = (hasArgs ? maybeOptions : argsOrOptions) ?? {};
|
|
13
|
-
return action(name).run((ctx) => {
|
|
11
|
+
export function command(name, file, args = [], options = {}) {
|
|
12
|
+
return action(name).run(async (ctx) => {
|
|
14
13
|
const cwd = path.resolve(options.cwd ?? ".");
|
|
15
|
-
const
|
|
14
|
+
const child = spawn(file, args, {
|
|
16
15
|
cwd,
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
env: options.env,
|
|
17
|
+
detached: process.platform !== "win32",
|
|
18
|
+
windowsHide: true,
|
|
19
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
19
20
|
});
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
console.log(`start · '${file}' ${args.join(" ")} · in ${cwd}`);
|
|
22
|
+
void streamLines(child.stdout, (line) => console.info(line));
|
|
23
|
+
void streamLines(child.stderr, (line) => console.error(line));
|
|
24
|
+
let finished = false;
|
|
25
|
+
const onAbort = () => {
|
|
26
|
+
if (!finished && child.pid !== undefined) {
|
|
27
|
+
killTree(child.pid);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
ctx.signal.addEventListener("abort", onAbort, { once: true });
|
|
31
|
+
try {
|
|
32
|
+
await new Promise((resolve, reject) => {
|
|
33
|
+
child.once("error", reject);
|
|
34
|
+
child.once("exit", (code, signal) => {
|
|
35
|
+
finished = true;
|
|
36
|
+
if (code === 0) {
|
|
37
|
+
resolve();
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
reject(new Error(signal ? `${name} terminated by ${signal}` : `${name} exited with code ${code}`));
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
finished = true;
|
|
47
|
+
ctx.signal.removeEventListener("abort", onAbort);
|
|
48
|
+
}
|
|
24
49
|
})();
|
|
25
50
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Runs a shell command as an action instance. Two forms:
|
|
28
|
-
*
|
|
29
|
-
* - `command(name, cmd, options?)` — a full command **string**, run verbatim through the
|
|
30
|
-
* shell, so pipes, globs and `&&` work (quote anything yourself).
|
|
31
|
-
* - `command(name, file, args, options?)` — an executable **plus an args array**; each arg
|
|
32
|
-
* is quoted individually, so spaces and `=`/paths in args are safe without hand-quoting.
|
|
33
|
-
*
|
|
34
|
-
* Output streams into the run's log under `name`; a non-zero exit fails the action;
|
|
35
|
-
* teardown kills the child tree. For interpolated events or a daemon loop, drop to
|
|
36
|
-
* `action(...).run(...)`.
|
|
37
|
-
*/
|
|
38
|
-
export const command = (name, cmdOrFile, argsOrOptions = {}, maybeOptions = {}) => build(name, cmdOrFile, argsOrOptions, maybeOptions);
|
package/dist/system/proc.d.ts
CHANGED
|
@@ -49,3 +49,5 @@ export declare const procRegistry: ProcRegistry;
|
|
|
49
49
|
* actions just describe the command — output streams in, the child dies on teardown.
|
|
50
50
|
*/
|
|
51
51
|
export declare const createProc: (sink: ProcSink, signal: AbortSignal) => Proc;
|
|
52
|
+
/** Split a byte/string stream into lines, calling `onLine` for each non-empty one. */
|
|
53
|
+
export declare function streamLines(stream: AsyncIterable<unknown>, onLine: (line: string) => void): Promise<void>;
|
package/dist/system/proc.js
CHANGED
|
@@ -130,7 +130,7 @@ export const createProc = (sink, signal) => (name, opts) => {
|
|
|
130
130
|
};
|
|
131
131
|
};
|
|
132
132
|
/** Split a byte/string stream into lines, calling `onLine` for each non-empty one. */
|
|
133
|
-
async function streamLines(stream, onLine) {
|
|
133
|
+
export async function streamLines(stream, onLine) {
|
|
134
134
|
let buffer = "";
|
|
135
135
|
for await (const chunk of stream) {
|
|
136
136
|
buffer += String(chunk);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omkit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "A tiny runtime for developer workflows: typed actions that pass runtime capabilities and emit typed events, under one run and one shared log. The operational/runtime layer to tskb's knowledge layer.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|