builderman 1.0.3 → 1.0.5
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/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/index.d.ts +3 -26
- package/dist/index.js +2 -205
- package/dist/pipeline.d.ts +5 -0
- package/dist/pipeline.js +184 -0
- package/dist/task.d.ts +5 -0
- package/dist/task.js +39 -0
- package/dist/types.d.ts +29 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const $TASK_INTERNAL: unique symbol;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const $TASK_INTERNAL = Symbol("task-internal");
|
package/dist/index.d.ts
CHANGED
|
@@ -1,26 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
5
|
-
export interface TaskConfig {
|
|
6
|
-
name: string;
|
|
7
|
-
commands: Commands;
|
|
8
|
-
cwd: string;
|
|
9
|
-
readyOn?: (output: string) => boolean;
|
|
10
|
-
dependsOn?: Dependency[];
|
|
11
|
-
}
|
|
12
|
-
export type Dependency = Promise<void> | (() => Promise<void>);
|
|
13
|
-
export interface Task extends TaskConfig {
|
|
14
|
-
readyOrComplete(): Promise<void>;
|
|
15
|
-
}
|
|
16
|
-
export interface Pipeline {
|
|
17
|
-
run(): Promise<void>;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Creates a task configuration.
|
|
21
|
-
*/
|
|
22
|
-
export declare function task(config: TaskConfig): Task;
|
|
23
|
-
/**
|
|
24
|
-
* Creates a pipeline that manages task execution with dependency-based coordination.
|
|
25
|
-
*/
|
|
26
|
-
export declare function pipeline(tasks: Task[]): Pipeline;
|
|
1
|
+
export * from "./task.js";
|
|
2
|
+
export * from "./pipeline.js";
|
|
3
|
+
export type { Task, Pipeline, TaskConfig } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,205 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import * as path from "node:path";
|
|
4
|
-
/**
|
|
5
|
-
* Creates a task configuration.
|
|
6
|
-
*/
|
|
7
|
-
export function task(config) {
|
|
8
|
-
let resolveReady = null;
|
|
9
|
-
const readyPromise = new Promise((resolve) => {
|
|
10
|
-
resolveReady = resolve;
|
|
11
|
-
});
|
|
12
|
-
let isReady = false;
|
|
13
|
-
let isComplete = false;
|
|
14
|
-
const task = {
|
|
15
|
-
...config,
|
|
16
|
-
dependsOn: config.dependsOn || [],
|
|
17
|
-
readyOrComplete() {
|
|
18
|
-
return readyPromise;
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
task._markReady = () => {
|
|
22
|
-
if (!isReady && resolveReady) {
|
|
23
|
-
isReady = true;
|
|
24
|
-
resolveReady();
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
task._markComplete = () => {
|
|
28
|
-
if (!isComplete) {
|
|
29
|
-
isComplete = true;
|
|
30
|
-
if (!isReady && resolveReady) {
|
|
31
|
-
isReady = true;
|
|
32
|
-
resolveReady();
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
task._isReady = () => isReady;
|
|
37
|
-
task._isComplete = () => isComplete;
|
|
38
|
-
return task;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Creates a pipeline that manages task execution with dependency-based coordination.
|
|
42
|
-
*/
|
|
43
|
-
export function pipeline(tasks) {
|
|
44
|
-
return {
|
|
45
|
-
async run() {
|
|
46
|
-
const eventEmitter = new EventEmitter();
|
|
47
|
-
const runningTasks = new Map();
|
|
48
|
-
const completedTasks = new Set();
|
|
49
|
-
const readyTasks = new Set();
|
|
50
|
-
// Determine which command to use based on NODE_ENV
|
|
51
|
-
const isProduction = process.env.NODE_ENV === "production";
|
|
52
|
-
const getCommand = (task) => {
|
|
53
|
-
return isProduction ? task.commands.build : task.commands.dev;
|
|
54
|
-
};
|
|
55
|
-
// Function to check if a task's dependencies are satisfied
|
|
56
|
-
const canStart = async (task) => {
|
|
57
|
-
if (runningTasks.has(task.name) || completedTasks.has(task.name)) {
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
if (!task.dependsOn || task.dependsOn.length === 0) {
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
// Wait for all dependencies
|
|
64
|
-
for (const dep of task.dependsOn) {
|
|
65
|
-
if (typeof dep === "function") {
|
|
66
|
-
await dep();
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
await dep;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return true;
|
|
73
|
-
};
|
|
74
|
-
// Function to start a task
|
|
75
|
-
const startTask = async (task) => {
|
|
76
|
-
if (runningTasks.has(task.name)) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
const command = getCommand(task);
|
|
80
|
-
// Ensure node_modules/.bin is in PATH for local dependencies
|
|
81
|
-
const taskCwd = path.isAbsolute(task.cwd)
|
|
82
|
-
? task.cwd
|
|
83
|
-
: path.resolve(process.cwd(), task.cwd);
|
|
84
|
-
const localBinPath = path.join(taskCwd, "node_modules", ".bin");
|
|
85
|
-
// Build PATH with local node_modules/.bin first
|
|
86
|
-
const existingPath = process.env.PATH || process.env.Path || "";
|
|
87
|
-
const pathSeparator = process.platform === "win32" ? ";" : ":";
|
|
88
|
-
const binPaths = [localBinPath];
|
|
89
|
-
const rootBinPath = path.join(process.cwd(), "node_modules", ".bin");
|
|
90
|
-
if (rootBinPath !== localBinPath) {
|
|
91
|
-
binPaths.push(rootBinPath);
|
|
92
|
-
}
|
|
93
|
-
if (existingPath) {
|
|
94
|
-
binPaths.push(existingPath);
|
|
95
|
-
}
|
|
96
|
-
const newPath = binPaths.join(pathSeparator);
|
|
97
|
-
const env = {
|
|
98
|
-
...process.env,
|
|
99
|
-
PATH: newPath,
|
|
100
|
-
Path: newPath,
|
|
101
|
-
};
|
|
102
|
-
const child = spawn(command, {
|
|
103
|
-
cwd: task.cwd,
|
|
104
|
-
stdio: ["inherit", "pipe", "pipe"],
|
|
105
|
-
shell: true,
|
|
106
|
-
env,
|
|
107
|
-
});
|
|
108
|
-
// Handle spawn errors
|
|
109
|
-
child.on("error", (error) => {
|
|
110
|
-
console.error(`[${task.name}] Failed to start:`, error.message);
|
|
111
|
-
runningTasks.delete(task.name);
|
|
112
|
-
completedTasks.add(task.name);
|
|
113
|
-
task._markComplete();
|
|
114
|
-
process.exitCode = 1;
|
|
115
|
-
eventEmitter.emit("taskCompleted", task.name);
|
|
116
|
-
});
|
|
117
|
-
runningTasks.set(task.name, child);
|
|
118
|
-
// If task doesn't have readyOn, mark as ready immediately
|
|
119
|
-
if (!task.readyOn) {
|
|
120
|
-
readyTasks.add(task.name);
|
|
121
|
-
task._markReady();
|
|
122
|
-
eventEmitter.emit("taskReady", task.name);
|
|
123
|
-
}
|
|
124
|
-
// Monitor stdout for readiness
|
|
125
|
-
let stdoutBuffer = "";
|
|
126
|
-
let allOutput = "";
|
|
127
|
-
child.stdout?.on("data", (data) => {
|
|
128
|
-
const chunk = data.toString();
|
|
129
|
-
allOutput += chunk;
|
|
130
|
-
stdoutBuffer += chunk;
|
|
131
|
-
const lines = stdoutBuffer.split("\n");
|
|
132
|
-
stdoutBuffer = lines.pop() || "";
|
|
133
|
-
for (const line of lines) {
|
|
134
|
-
// Check if task is ready based on readyOn callback
|
|
135
|
-
if (task.readyOn && !readyTasks.has(task.name)) {
|
|
136
|
-
if (task.readyOn(allOutput)) {
|
|
137
|
-
readyTasks.add(task.name);
|
|
138
|
-
task._markReady();
|
|
139
|
-
eventEmitter.emit("taskReady", task.name);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
// Forward stdout to parent
|
|
143
|
-
process.stdout.write(line + "\n");
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
// Forward any remaining buffer on end
|
|
147
|
-
child.stdout?.on("end", () => {
|
|
148
|
-
if (stdoutBuffer) {
|
|
149
|
-
process.stdout.write(stdoutBuffer);
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
// Forward stderr
|
|
153
|
-
child.stderr?.on("data", (data) => {
|
|
154
|
-
process.stderr.write(data);
|
|
155
|
-
});
|
|
156
|
-
// Handle task completion
|
|
157
|
-
child.on("exit", (code) => {
|
|
158
|
-
runningTasks.delete(task.name);
|
|
159
|
-
completedTasks.add(task.name);
|
|
160
|
-
task._markComplete();
|
|
161
|
-
if (code !== 0) {
|
|
162
|
-
process.exitCode = code || 1;
|
|
163
|
-
}
|
|
164
|
-
eventEmitter.emit("taskCompleted", task.name);
|
|
165
|
-
});
|
|
166
|
-
};
|
|
167
|
-
// Function to try starting tasks when dependencies are ready
|
|
168
|
-
const tryStartTasks = async () => {
|
|
169
|
-
for (const task of tasks) {
|
|
170
|
-
if (await canStart(task)) {
|
|
171
|
-
await startTask(task);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
};
|
|
175
|
-
// Listen for task readiness and completion to start dependent tasks
|
|
176
|
-
eventEmitter.on("taskReady", tryStartTasks);
|
|
177
|
-
eventEmitter.on("taskCompleted", tryStartTasks);
|
|
178
|
-
// Start tasks that don't have dependencies
|
|
179
|
-
await tryStartTasks();
|
|
180
|
-
// Wait for all tasks to complete
|
|
181
|
-
return new Promise((resolve, reject) => {
|
|
182
|
-
const checkCompletion = () => {
|
|
183
|
-
if (runningTasks.size === 0) {
|
|
184
|
-
resolve();
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
eventEmitter.on("taskCompleted", checkCompletion);
|
|
188
|
-
checkCompletion();
|
|
189
|
-
// Handle process termination
|
|
190
|
-
process.on("SIGINT", () => {
|
|
191
|
-
for (const child of runningTasks.values()) {
|
|
192
|
-
child.kill("SIGINT");
|
|
193
|
-
}
|
|
194
|
-
reject(new Error("Process interrupted"));
|
|
195
|
-
});
|
|
196
|
-
process.on("SIGTERM", () => {
|
|
197
|
-
for (const child of runningTasks.values()) {
|
|
198
|
-
child.kill("SIGTERM");
|
|
199
|
-
}
|
|
200
|
-
reject(new Error("Process terminated"));
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
},
|
|
204
|
-
};
|
|
205
|
-
}
|
|
1
|
+
export * from "./task.js";
|
|
2
|
+
export * from "./pipeline.js";
|
package/dist/pipeline.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { EventEmitter } from "node:events";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { $TASK_INTERNAL } from "./constants.js";
|
|
5
|
+
/**
|
|
6
|
+
* Creates a pipeline that manages task execution with dependency-based coordination.
|
|
7
|
+
*/
|
|
8
|
+
export function pipeline(tasks) {
|
|
9
|
+
return {
|
|
10
|
+
async run() {
|
|
11
|
+
const eventEmitter = new EventEmitter();
|
|
12
|
+
const runningTasks = new Map();
|
|
13
|
+
const completedTasks = new Set();
|
|
14
|
+
const readyTasks = new Set();
|
|
15
|
+
// Determine which command to use based on NODE_ENV
|
|
16
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
17
|
+
const getCommand = (task) => {
|
|
18
|
+
return isProduction
|
|
19
|
+
? task[$TASK_INTERNAL].commands.build
|
|
20
|
+
: task[$TASK_INTERNAL].commands.dev;
|
|
21
|
+
};
|
|
22
|
+
// Function to check if a task's dependencies are satisfied
|
|
23
|
+
const canStart = async (task) => {
|
|
24
|
+
if (runningTasks.has(task.name) || completedTasks.has(task.name)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const { dependsOn: dependencies } = task[$TASK_INTERNAL];
|
|
28
|
+
if (!dependencies || dependencies.length === 0) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
// Wait for all dependencies
|
|
32
|
+
for (const dep of dependencies) {
|
|
33
|
+
if (typeof dep === "function") {
|
|
34
|
+
await dep();
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
await dep;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return true;
|
|
41
|
+
};
|
|
42
|
+
// Function to start a task
|
|
43
|
+
const startTask = async (task) => {
|
|
44
|
+
if (runningTasks.has(task.name)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const command = getCommand(task);
|
|
48
|
+
const { cwd, readyOn, markComplete, markReady } = task[$TASK_INTERNAL];
|
|
49
|
+
// Ensure node_modules/.bin is in PATH for local dependencies
|
|
50
|
+
const taskCwd = path.isAbsolute(cwd)
|
|
51
|
+
? cwd
|
|
52
|
+
: path.resolve(process.cwd(), cwd);
|
|
53
|
+
const localBinPath = path.join(taskCwd, "node_modules", ".bin");
|
|
54
|
+
// Build PATH with local node_modules/.bin first
|
|
55
|
+
const existingPath = process.env.PATH || process.env.Path || "";
|
|
56
|
+
const pathSeparator = process.platform === "win32" ? ";" : ":";
|
|
57
|
+
const binPaths = [localBinPath];
|
|
58
|
+
const rootBinPath = path.join(process.cwd(), "node_modules", ".bin");
|
|
59
|
+
if (rootBinPath !== localBinPath) {
|
|
60
|
+
binPaths.push(rootBinPath);
|
|
61
|
+
}
|
|
62
|
+
if (existingPath) {
|
|
63
|
+
binPaths.push(existingPath);
|
|
64
|
+
}
|
|
65
|
+
const newPath = binPaths.join(pathSeparator);
|
|
66
|
+
const env = {
|
|
67
|
+
...process.env,
|
|
68
|
+
PATH: newPath,
|
|
69
|
+
Path: newPath,
|
|
70
|
+
};
|
|
71
|
+
// On Windows, use cmd.exe explicitly to avoid path resolution issues
|
|
72
|
+
// Using shell: true can cause issues with Git Bash paths
|
|
73
|
+
const spawnOptions = {
|
|
74
|
+
cwd,
|
|
75
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
76
|
+
env,
|
|
77
|
+
};
|
|
78
|
+
if (process.platform === "win32") {
|
|
79
|
+
// Use cmd.exe explicitly on Windows
|
|
80
|
+
spawnOptions.shell = process.env.ComSpec || "cmd.exe";
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// On Unix-like systems, use shell: true
|
|
84
|
+
spawnOptions.shell = true;
|
|
85
|
+
}
|
|
86
|
+
const child = spawn(command, spawnOptions);
|
|
87
|
+
// Handle spawn errors
|
|
88
|
+
child.on("error", (error) => {
|
|
89
|
+
console.error(`[${task.name}] Failed to start:`, error.message);
|
|
90
|
+
runningTasks.delete(task.name);
|
|
91
|
+
completedTasks.add(task.name);
|
|
92
|
+
markComplete();
|
|
93
|
+
process.exitCode = 1;
|
|
94
|
+
eventEmitter.emit("taskCompleted", task.name);
|
|
95
|
+
});
|
|
96
|
+
runningTasks.set(task.name, child);
|
|
97
|
+
// If task doesn't have readyOn, mark as ready immediately
|
|
98
|
+
if (!readyOn) {
|
|
99
|
+
readyTasks.add(task.name);
|
|
100
|
+
markReady();
|
|
101
|
+
eventEmitter.emit("taskReady", task.name);
|
|
102
|
+
}
|
|
103
|
+
// Monitor stdout for readiness
|
|
104
|
+
let stdoutBuffer = "";
|
|
105
|
+
let allOutput = "";
|
|
106
|
+
child.stdout?.on("data", (data) => {
|
|
107
|
+
const chunk = data.toString();
|
|
108
|
+
allOutput += chunk;
|
|
109
|
+
stdoutBuffer += chunk;
|
|
110
|
+
const lines = stdoutBuffer.split("\n");
|
|
111
|
+
stdoutBuffer = lines.pop() || "";
|
|
112
|
+
for (const line of lines) {
|
|
113
|
+
// Check if task is ready based on readyOn callback
|
|
114
|
+
if (readyOn && !readyTasks.has(task.name)) {
|
|
115
|
+
if (readyOn(allOutput)) {
|
|
116
|
+
readyTasks.add(task.name);
|
|
117
|
+
markReady();
|
|
118
|
+
eventEmitter.emit("taskReady", task.name);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Forward stdout to parent
|
|
122
|
+
process.stdout.write(line + "\n");
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
// Forward any remaining buffer on end
|
|
126
|
+
child.stdout?.on("end", () => {
|
|
127
|
+
if (stdoutBuffer) {
|
|
128
|
+
process.stdout.write(stdoutBuffer);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
// Forward stderr
|
|
132
|
+
child.stderr?.on("data", (data) => {
|
|
133
|
+
process.stderr.write(data);
|
|
134
|
+
});
|
|
135
|
+
// Handle task completion
|
|
136
|
+
child.on("exit", (code) => {
|
|
137
|
+
runningTasks.delete(task.name);
|
|
138
|
+
completedTasks.add(task.name);
|
|
139
|
+
markComplete();
|
|
140
|
+
if (code !== 0) {
|
|
141
|
+
process.exitCode = code || 1;
|
|
142
|
+
}
|
|
143
|
+
eventEmitter.emit("taskCompleted", task.name);
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
// Function to try starting tasks when dependencies are ready
|
|
147
|
+
const tryStartTasks = async () => {
|
|
148
|
+
for (const task of tasks) {
|
|
149
|
+
if (await canStart(task)) {
|
|
150
|
+
await startTask(task);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
// Listen for task readiness and completion to start dependent tasks
|
|
155
|
+
eventEmitter.on("taskReady", tryStartTasks);
|
|
156
|
+
eventEmitter.on("taskCompleted", tryStartTasks);
|
|
157
|
+
// Start tasks that don't have dependencies
|
|
158
|
+
await tryStartTasks();
|
|
159
|
+
// Wait for all tasks to complete
|
|
160
|
+
return new Promise((resolve, reject) => {
|
|
161
|
+
const checkCompletion = () => {
|
|
162
|
+
if (runningTasks.size === 0) {
|
|
163
|
+
resolve();
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
eventEmitter.on("taskCompleted", checkCompletion);
|
|
167
|
+
checkCompletion();
|
|
168
|
+
// Handle process termination
|
|
169
|
+
process.on("SIGINT", () => {
|
|
170
|
+
for (const child of runningTasks.values()) {
|
|
171
|
+
child.kill("SIGINT");
|
|
172
|
+
}
|
|
173
|
+
reject(new Error("Process interrupted"));
|
|
174
|
+
});
|
|
175
|
+
process.on("SIGTERM", () => {
|
|
176
|
+
for (const child of runningTasks.values()) {
|
|
177
|
+
child.kill("SIGTERM");
|
|
178
|
+
}
|
|
179
|
+
reject(new Error("Process terminated"));
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
}
|
package/dist/task.d.ts
ADDED
package/dist/task.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { $TASK_INTERNAL } from "./constants.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a task configuration.
|
|
4
|
+
*/
|
|
5
|
+
export function task(config) {
|
|
6
|
+
let resolveReady = null;
|
|
7
|
+
const readyPromise = new Promise((resolve) => {
|
|
8
|
+
resolveReady = resolve;
|
|
9
|
+
});
|
|
10
|
+
let isReady = false;
|
|
11
|
+
let isComplete = false;
|
|
12
|
+
return {
|
|
13
|
+
name: config.name,
|
|
14
|
+
readyOrComplete() {
|
|
15
|
+
return readyPromise;
|
|
16
|
+
},
|
|
17
|
+
[$TASK_INTERNAL]: {
|
|
18
|
+
...config,
|
|
19
|
+
dependsOn: config.dependsOn || [],
|
|
20
|
+
isReady: () => isReady,
|
|
21
|
+
isComplete: () => isComplete,
|
|
22
|
+
markReady: () => {
|
|
23
|
+
if (!isReady && resolveReady) {
|
|
24
|
+
isReady = true;
|
|
25
|
+
resolveReady();
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
markComplete: () => {
|
|
29
|
+
if (!isComplete) {
|
|
30
|
+
isComplete = true;
|
|
31
|
+
if (!isReady && resolveReady) {
|
|
32
|
+
isReady = true;
|
|
33
|
+
resolveReady();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { $TASK_INTERNAL } from "./constants.js";
|
|
2
|
+
export interface Commands {
|
|
3
|
+
dev: string;
|
|
4
|
+
build: string;
|
|
5
|
+
}
|
|
6
|
+
export interface TaskConfig {
|
|
7
|
+
name: string;
|
|
8
|
+
commands: Commands;
|
|
9
|
+
cwd: string;
|
|
10
|
+
readyOn?: (output: string) => boolean;
|
|
11
|
+
dependsOn?: Dependency[];
|
|
12
|
+
}
|
|
13
|
+
export type Dependency = Promise<void> | (() => Promise<void>);
|
|
14
|
+
interface TaskInternal extends TaskConfig {
|
|
15
|
+
dependsOn: Dependency[];
|
|
16
|
+
isReady: () => boolean;
|
|
17
|
+
isComplete: () => boolean;
|
|
18
|
+
markReady: () => void;
|
|
19
|
+
markComplete: () => void;
|
|
20
|
+
}
|
|
21
|
+
export interface Task {
|
|
22
|
+
name: string;
|
|
23
|
+
readyOrComplete(): Promise<void>;
|
|
24
|
+
[$TASK_INTERNAL]: TaskInternal;
|
|
25
|
+
}
|
|
26
|
+
export interface Pipeline {
|
|
27
|
+
run(): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
export {};
|