@powerlines/engine 0.49.13 → 0.49.15
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/{api-DcHfCjQK.d.cts → api-D1r7WAQA.d.cts} +13 -13
- package/dist/api-D1r7WAQA.d.cts.map +1 -0
- package/dist/{api-BgyEi2hF.d.mts → api-DRcC7Ry-.d.mts} +13 -13
- package/dist/api-DRcC7Ry-.d.mts.map +1 -0
- package/dist/api.cjs +3 -21
- package/dist/api.d.cts +5 -12
- package/dist/api.d.cts.map +1 -1
- package/dist/api.d.mts +5 -11
- package/dist/api.d.mts.map +1 -1
- package/dist/api.mjs +21 -30
- package/dist/api.mjs.map +1 -1
- package/dist/engine-BLp7JcAB.d.mts +199 -0
- package/dist/engine-BLp7JcAB.d.mts.map +1 -0
- package/dist/{engine-BWwXttY1.mjs → engine-CDFOkhKj.mjs} +113 -121
- package/dist/engine-CDFOkhKj.mjs.map +1 -0
- package/dist/engine-DFKgU8-G.d.cts +199 -0
- package/dist/engine-DFKgU8-G.d.cts.map +1 -0
- package/dist/{engine-CYesECu-.cjs → engine-DlOFwFgt.cjs} +112 -120
- package/dist/engine.cjs +1 -1
- package/dist/engine.d.cts +2 -143
- package/dist/engine.d.mts +2 -143
- package/dist/engine.mjs +1 -1
- package/dist/helpers/{create-execution-host.cjs → create-api.cjs} +14 -13
- package/dist/helpers/create-api.d.cts +18 -0
- package/dist/helpers/create-api.d.cts.map +1 -0
- package/dist/helpers/create-api.d.mts +18 -0
- package/dist/helpers/create-api.d.mts.map +1 -0
- package/dist/helpers/{create-execution-host.mjs → create-api.mjs} +15 -14
- package/dist/helpers/create-api.mjs.map +1 -0
- package/dist/helpers/index.cjs +2 -2
- package/dist/helpers/index.d.cts +2 -2
- package/dist/helpers/index.d.mts +2 -2
- package/dist/helpers/index.mjs +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +1 -1
- package/package.json +23 -23
- package/dist/api-BgyEi2hF.d.mts.map +0 -1
- package/dist/api-DcHfCjQK.d.cts.map +0 -1
- package/dist/engine-BWwXttY1.mjs.map +0 -1
- package/dist/engine.d.cts.map +0 -1
- package/dist/engine.d.mts.map +0 -1
- package/dist/helpers/create-execution-host.d.cts +0 -20
- package/dist/helpers/create-execution-host.d.cts.map +0 -1
- package/dist/helpers/create-execution-host.d.mts +0 -20
- package/dist/helpers/create-execution-host.d.mts.map +0 -1
- package/dist/helpers/create-execution-host.mjs.map +0 -1
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { n as EngineOptions, t as EngineExecutionOptions } from "./config-DKEmqMrh.cjs";
|
|
2
|
+
import { t as EngineContext } from "./context-D0_a0kRO.cjs";
|
|
3
|
+
import { r as ExecutionApiWorkerInterface, t as Engine } from "./api-D1r7WAQA.cjs";
|
|
4
|
+
import { t as PowerlinesEngineContext } from "./engine-context-B8K6Jtkk.cjs";
|
|
5
|
+
import { BuildInlineConfig, CleanInlineConfig, CreateInlineConfig, DeployInlineConfig, DocsInlineConfig, InlineConfig, LintInlineConfig, Mode, PrepareInlineConfig, TestInlineConfig, TypesInlineConfig } from "@powerlines/core";
|
|
6
|
+
|
|
7
|
+
//#region src/_internal/execution-api-worker.d.ts
|
|
8
|
+
declare const RESTARTED: unique symbol;
|
|
9
|
+
interface ExecutionApiWorkerOptions {
|
|
10
|
+
/**
|
|
11
|
+
* The maximum time in milliseconds a worker can run before being terminated.
|
|
12
|
+
*
|
|
13
|
+
* @defaultValue 900000 (15 minutes)
|
|
14
|
+
*/
|
|
15
|
+
timeout?: number;
|
|
16
|
+
/**
|
|
17
|
+
* True if `--max-old-space-size` should not be forwarded to the worker.
|
|
18
|
+
*/
|
|
19
|
+
isolatedMemory?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* The mode to run the worker in, which can affect how the worker is initialized and how it behaves. This is determined based on the resolved configuration of the engine, and can be used to optimize the worker for different environments (e.g., development, production, etc.).
|
|
22
|
+
*/
|
|
23
|
+
mode?: Mode;
|
|
24
|
+
/**
|
|
25
|
+
* An optional root to resolve the execution host path from, which can be used to specify a custom root directory for the worker to use when resolving paths and loading configuration files. If this option is not provided, the worker will use the current working directory as the root directory by default.
|
|
26
|
+
*/
|
|
27
|
+
root?: string;
|
|
28
|
+
/**
|
|
29
|
+
* The context of the {@link @powerlines/engine#Engine | Engine instance}, which can be used to access the engine's state and services within the worker.
|
|
30
|
+
*/
|
|
31
|
+
context: EngineContext;
|
|
32
|
+
}
|
|
33
|
+
declare class ExecutionApiWorker implements ExecutionApiWorkerInterface {
|
|
34
|
+
#private;
|
|
35
|
+
protected executionApiPath: string;
|
|
36
|
+
protected options: ExecutionApiWorkerOptions;
|
|
37
|
+
protected get restartPromise(): Promise<typeof RESTARTED>;
|
|
38
|
+
protected resolveRestartPromise(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Creates a new instance of the Execution API Worker class, which manages a worker process for executing tasks related to the Powerlines Engine. The worker is initialized with the specified options and can be used to run tasks in an isolated environment, with support for automatic restarts and activity monitoring.
|
|
41
|
+
*
|
|
42
|
+
* @param apiPath - The path to the Execution API file.
|
|
43
|
+
* @param options - The options for configuring the worker, including the execution context, exposed methods, timeout, and mode.
|
|
44
|
+
* @returns A promise that resolves to an instance of the ExecutionApiWorker class.
|
|
45
|
+
*/
|
|
46
|
+
static from(apiPath: string, options: ExecutionApiWorkerOptions): Promise<ExecutionApiWorker>;
|
|
47
|
+
/**
|
|
48
|
+
* Create a new API worker instance.
|
|
49
|
+
*
|
|
50
|
+
* @param executionApiPath - The path to the worker file.
|
|
51
|
+
* @param options - The options for the worker, including exposed commands, timeout, and hooks for activity and restart.
|
|
52
|
+
*/
|
|
53
|
+
protected constructor(executionApiPath: string, options: ExecutionApiWorkerOptions);
|
|
54
|
+
execute(command: string, options: EngineExecutionOptions, inlineConfig: InlineConfig): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Closes the worker process, terminating it if it's still running. This method should be called when the worker is no longer needed, to free up system resources and ensure a clean shutdown. If the worker has already been terminated, this method will have no effect.
|
|
57
|
+
*/
|
|
58
|
+
finalize(): Promise<void>;
|
|
59
|
+
protected onHanging(): void;
|
|
60
|
+
protected onActivity(): void;
|
|
61
|
+
protected innerExecute(command: string, options: EngineExecutionOptions, inlineConfig: InlineConfig): Promise<void>;
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/engine.d.ts
|
|
65
|
+
/**
|
|
66
|
+
* The Powerlines process' orchestration and coordination API.
|
|
67
|
+
*
|
|
68
|
+
* @public
|
|
69
|
+
*/
|
|
70
|
+
declare class PowerlinesEngine implements Engine, AsyncDisposable {
|
|
71
|
+
#private;
|
|
72
|
+
/**
|
|
73
|
+
* The Powerlines context
|
|
74
|
+
*/
|
|
75
|
+
get context(): EngineContext;
|
|
76
|
+
/**
|
|
77
|
+
* The execution host, which provides methods to call the execution API functions from the engine context. This allows the engine to invoke commands and other API functions during the execution of Powerlines commands, enabling communication between the engine and the execution contexts.
|
|
78
|
+
*/
|
|
79
|
+
get api(): ExecutionApiWorker;
|
|
80
|
+
/**
|
|
81
|
+
* Create a new Powerlines Engine instance
|
|
82
|
+
*
|
|
83
|
+
* @param context - The Powerlines context
|
|
84
|
+
* @param api - The API host for the execution workers
|
|
85
|
+
* @returns A new instance of the Powerlines Engine
|
|
86
|
+
*/
|
|
87
|
+
constructor(context: EngineContext, api: ExecutionApiWorker);
|
|
88
|
+
/**
|
|
89
|
+
* Create a new Powerlines project
|
|
90
|
+
*
|
|
91
|
+
* @remarks
|
|
92
|
+
* This method will create a new Powerlines project in the current directory.
|
|
93
|
+
*
|
|
94
|
+
* @param inlineConfig - The inline configuration for the create command
|
|
95
|
+
* @returns A promise that resolves when the project has been created
|
|
96
|
+
*/
|
|
97
|
+
create(inlineConfig: CreateInlineConfig): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Generate the Powerlines typescript declaration file
|
|
100
|
+
*
|
|
101
|
+
* @remarks
|
|
102
|
+
* This method will only generate the typescript declaration file for the Powerlines project. It is generally recommended to run the full `prepare` command, which will run this method as part of its process.
|
|
103
|
+
*
|
|
104
|
+
* @param inlineConfig - The inline configuration for the types command
|
|
105
|
+
*/
|
|
106
|
+
types(inlineConfig: TypesInlineConfig): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Prepare the Powerlines API
|
|
109
|
+
*
|
|
110
|
+
* @remarks
|
|
111
|
+
* This method will prepare the Powerlines API for use, initializing any necessary resources.
|
|
112
|
+
*
|
|
113
|
+
* @param inlineConfig - The inline configuration for the prepare command
|
|
114
|
+
*/
|
|
115
|
+
prepare(inlineConfig: PrepareInlineConfig): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Clean any previously prepared artifacts
|
|
118
|
+
*
|
|
119
|
+
* @remarks
|
|
120
|
+
* This method will remove the previous Powerlines artifacts from the project.
|
|
121
|
+
*
|
|
122
|
+
* @param inlineConfig - The inline configuration for the clean command
|
|
123
|
+
* @returns A promise that resolves when the clean command has completed
|
|
124
|
+
*/
|
|
125
|
+
clean(inlineConfig: CleanInlineConfig): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Lint the project
|
|
128
|
+
*
|
|
129
|
+
* @param inlineConfig - The inline configuration for the lint command
|
|
130
|
+
* @returns A promise that resolves when the lint command has completed
|
|
131
|
+
*/
|
|
132
|
+
lint(inlineConfig: LintInlineConfig): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* Test the project
|
|
135
|
+
*
|
|
136
|
+
* @remarks
|
|
137
|
+
* This method will run the tests for the Powerlines project.
|
|
138
|
+
*
|
|
139
|
+
* @param inlineConfig - The inline configuration for the test command
|
|
140
|
+
* @returns A promise that resolves when the test command has completed
|
|
141
|
+
*/
|
|
142
|
+
test(inlineConfig: TestInlineConfig): Promise<void>;
|
|
143
|
+
/**
|
|
144
|
+
* Build the project
|
|
145
|
+
*
|
|
146
|
+
* @remarks
|
|
147
|
+
* This method will build the Powerlines project, generating the necessary artifacts.
|
|
148
|
+
*
|
|
149
|
+
* @param inlineConfig - The inline configuration for the build command
|
|
150
|
+
* @returns A promise that resolves when the build command has completed
|
|
151
|
+
*/
|
|
152
|
+
build(inlineConfig: BuildInlineConfig): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Prepare the documentation for the project
|
|
155
|
+
*
|
|
156
|
+
* @param inlineConfig - The inline configuration for the docs command
|
|
157
|
+
* @returns A promise that resolves when the documentation generation has completed
|
|
158
|
+
*/
|
|
159
|
+
docs(inlineConfig: DocsInlineConfig): Promise<void>;
|
|
160
|
+
/**
|
|
161
|
+
* Deploy the project source code
|
|
162
|
+
*
|
|
163
|
+
* @remarks
|
|
164
|
+
* This method will prepare and build the Powerlines project, generating the necessary artifacts for the deployment.
|
|
165
|
+
*
|
|
166
|
+
* @param inlineConfig - The inline configuration for the deploy command
|
|
167
|
+
* @returns A promise that resolves when the deploy command has completed
|
|
168
|
+
*/
|
|
169
|
+
deploy(inlineConfig: DeployInlineConfig): Promise<void>;
|
|
170
|
+
/**
|
|
171
|
+
* Finalization/cleanup processing for the Powerlines API
|
|
172
|
+
*
|
|
173
|
+
* @remarks
|
|
174
|
+
* This step includes any final processes or clean up required by Powerlines. It will be run after each Powerlines command.
|
|
175
|
+
*
|
|
176
|
+
* @returns A promise that resolves when the finalization process has completed
|
|
177
|
+
*/
|
|
178
|
+
finalize(): Promise<void>;
|
|
179
|
+
/**
|
|
180
|
+
* Asynchronous disposal method for the Powerlines Engine, which will call the finalize method to perform any necessary cleanup when the engine is disposed of.
|
|
181
|
+
*/
|
|
182
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
183
|
+
/**
|
|
184
|
+
* Execute a Powerlines command based on the provided execution path and inline configuration, loading the necessary executions from the context and managing their lifecycle.
|
|
185
|
+
*
|
|
186
|
+
* @remarks
|
|
187
|
+
* This method will load the executions for the specified command and inline configuration, then execute each one while managing their lifecycle, including handling their completion and any errors that may occur during execution.
|
|
188
|
+
*
|
|
189
|
+
* @param command - The path to the execution configuration to load and run, which can be used to specify different execution configurations for different commands or scenarios.
|
|
190
|
+
* @param inlineConfig - Additional configuration options provided at runtime, which can override or supplement the options defined in the user configuration file.
|
|
191
|
+
* @returns A promise that resolves when all executions for the specified command have completed
|
|
192
|
+
*/
|
|
193
|
+
protected execute(command: string, inlineConfig: InlineConfig): Promise<void>;
|
|
194
|
+
}
|
|
195
|
+
declare function createContext(options: EngineOptions): Promise<PowerlinesEngineContext<unknown>>;
|
|
196
|
+
declare function createEngine(options: EngineOptions, apiPath?: string): Promise<PowerlinesEngine>;
|
|
197
|
+
//#endregion
|
|
198
|
+
export { createContext as n, createEngine as r, PowerlinesEngine as t };
|
|
199
|
+
//# sourceMappingURL=engine-DFKgU8-G.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-DFKgU8-G.d.cts","names":[],"sources":["../src/_internal/execution-api-worker.ts","../src/engine.ts"],"mappings":";;;;;;;cAuCM,SAAA;AAAA,UA8DW,yBAAA;;AAhEgC;;;;EAgF/C,OAAA;EAhBe;;;EAqBf,cAAA;EALA;;;EAUA,IAAA,GAAO,IAAA;EAKP;;;EAAA,IAAA;EAKsB;AAGxB;;EAHE,OAAA,EAAS,aAAa;AAAA;AAAA,cAGX,kBAAA,YAA8B,2BAAA;EAAA;YAsF7B,gBAAA;EAAA,UACA,OAAA,EAAS,yBAAA;EAAA,cAxEP,cAAA,CAAA,GAAc,OAAA,QAAA,SAAA;EAAA,UASlB,qBAAA,CAAA;EA6WC;;;;;;;EAAA,OA9VS,IAAA,CAClB,OAAA,UACA,OAAA,EAAS,yBAAA,GAAyB,OAAA,CAAA,kBAAA;EAzCgC;;;;;;EAAA,UAqF3D,WAAA,CACG,gBAAA,UACA,OAAA,EAAS,yBAAA;EA4SR,OAAA,CACX,OAAA,UACA,OAAA,EAAS,sBAAA,EACT,YAAA,EAAc,YAAA,GAAY,OAAA;EAvXA;;;EA0Zf,QAAA,CAAA,GAAY,OAAA;EAAA,UAYf,SAAA,CAAA;EAAA,UAoBA,UAAA,CAAA;EAAA,UAUM,YAAA,CACd,OAAA,UACA,OAAA,EAAS,sBAAA,EACT,YAAA,EAAc,YAAA,GAAY,OAAA;AAAA;;;;;AA7jBmB;;;cCSpC,gBAAA,YAA4B,MAAA,EAAQ,eAAA;EAAA;EDuDhC;;;EAAA,ICzCJ,OAAA,CAAA,GAAW,aAAA;EDyDtB;;;EAAA,IClDW,GAAA,CAAA,GAAO,kBAAA;EDiElB;;;;AAKsB;AAGxB;;cC9DqB,OAAA,EAAS,aAAA,EAAe,GAAA,EAAK,kBAAA;EDqJ3B;;;;;;;;;ECvIR,MAAA,CAAO,YAAA,EAAc,kBAAA,GAAkB,OAAA;EDyd3B;;;;;;;;ECvcZ,KAAA,CAAM,YAAA,EAAc,iBAAA,GAAiB,OAAA;EDoHtC;;;;;;;;EClGC,OAAA,CAAQ,YAAA,EAAc,mBAAA,GAAmB,OAAA;EDqD3C;;;;;;;;;EClCE,KAAA,CAAM,YAAA,EAAc,iBAAA,GAAiB,OAAA;ED8XvC;;;;;;EC9WE,IAAA,CAAK,YAAA,EAAc,gBAAA,GAAgB,OAAA;ED8ZtC;;;;;;;;;EC3YG,IAAA,CAAK,YAAA,EAAc,gBAAA,GAAgB,OAAA;ED4apB;;;;ACpjB9B;;;;;EA2Je,KAAA,CAAM,YAAA,EAAc,iBAAA,GAAiB,OAAA;EA3HF;;;;;;EA2InC,IAAA,CAAK,YAAA,EAAc,gBAAA,GAAgB,OAAA;EAtEf;;;;;;;;;EAyFpB,MAAA,CAAO,YAAA,EAAc,kBAAA,GAAkB,OAAA;EAAlB;;;;;;;;EAkBrB,QAAA,CAAA,GAAQ,OAAA;EAhNyC;;;EAAA,CA6NhD,MAAA,CAAO,YAAA,KAAa,OAAA;;;;;;;;;;;YAclB,OAAA,CAAQ,OAAA,UAAiB,YAAA,EAAc,YAAA,GAAY,OAAA;AAAA;AAAA,iBA8B/C,aAAA,CAAc,OAAA,EAAS,aAAA,GAAa,OAAA,CAAA,uBAAA;AAAA,iBAuBpC,YAAA,CACpB,OAAA,EAAS,aAAA,EACT,OAAA,YAAkC,OAAA,CAAA,gBAAA"}
|
|
@@ -2,9 +2,6 @@ const require_chunk = require('./chunk-C_NdSu1c.cjs');
|
|
|
2
2
|
const require_helpers_stream = require('./helpers/stream.cjs');
|
|
3
3
|
const require_context_engine_context = require('./context/engine-context.cjs');
|
|
4
4
|
let _stryke_path_append = require("@stryke/path/append");
|
|
5
|
-
let _stryke_convert_to_array = require("@stryke/convert/to-array");
|
|
6
|
-
let _stryke_type_checks_is_set_object = require("@stryke/type-checks/is-set-object");
|
|
7
|
-
let _stryke_type_checks_is_function = require("@stryke/type-checks/is-function");
|
|
8
5
|
let _stryke_type_checks_is_number = require("@stryke/type-checks/is-number");
|
|
9
6
|
let _stryke_type_checks_is_set = require("@stryke/type-checks/is-set");
|
|
10
7
|
let node_events = require("node:events");
|
|
@@ -19,13 +16,12 @@ let _stryke_fs_resolve = require("@stryke/fs/resolve");
|
|
|
19
16
|
let _stryke_type_checks_is_set_string = require("@stryke/type-checks/is-set-string");
|
|
20
17
|
let _stryke_type_checks_is_string = require("@stryke/type-checks/is-string");
|
|
21
18
|
let date_fns_formatDuration = require("date-fns/formatDuration");
|
|
22
|
-
let jiti = require("jiti");
|
|
23
19
|
let node_util = require("node:util");
|
|
24
20
|
let node_worker_threads = require("node:worker_threads");
|
|
25
21
|
let piscina = require("piscina");
|
|
26
22
|
piscina = require_chunk.__toESM(piscina, 1);
|
|
27
23
|
|
|
28
|
-
//#region src/_internal/execution-
|
|
24
|
+
//#region src/_internal/execution-api-worker.ts
|
|
29
25
|
const RESTARTED = Symbol("powerlines-worker:restarted");
|
|
30
26
|
/**
|
|
31
27
|
* Formats the debug address into a string.
|
|
@@ -65,54 +61,57 @@ function getNodeDebugType(nodeOptions) {
|
|
|
65
61
|
if (nodeOptions.inspect) return "inspect";
|
|
66
62
|
if (nodeOptions["inspect-brk"] || nodeOptions.inspect_brk) return "inspect-brk";
|
|
67
63
|
}
|
|
68
|
-
var
|
|
69
|
-
|
|
70
|
-
exposedMethods;
|
|
64
|
+
var ExecutionApiWorker = class ExecutionApiWorker {
|
|
65
|
+
executionApiPath;
|
|
71
66
|
options;
|
|
72
67
|
#worker;
|
|
68
|
+
#logger;
|
|
69
|
+
#activeTasks = 0;
|
|
70
|
+
#restartPromise = null;
|
|
71
|
+
#resolveRestartPromise = null;
|
|
72
|
+
#hangingTimer = false;
|
|
73
|
+
#createWorker;
|
|
74
|
+
get restartPromise() {
|
|
75
|
+
if (!this.#restartPromise) this.#restartPromise = new Promise((resolve) => {
|
|
76
|
+
this.#resolveRestartPromise = resolve;
|
|
77
|
+
});
|
|
78
|
+
return this.#restartPromise;
|
|
79
|
+
}
|
|
80
|
+
resolveRestartPromise() {
|
|
81
|
+
if (this.#resolveRestartPromise) {
|
|
82
|
+
this.#resolveRestartPromise(RESTARTED);
|
|
83
|
+
this.#restartPromise = null;
|
|
84
|
+
this.#resolveRestartPromise = null;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
73
87
|
/**
|
|
74
|
-
* Creates a new instance of the
|
|
88
|
+
* Creates a new instance of the Execution API Worker class, which manages a worker process for executing tasks related to the Powerlines Engine. The worker is initialized with the specified options and can be used to run tasks in an isolated environment, with support for automatic restarts and activity monitoring.
|
|
75
89
|
*
|
|
76
|
-
* @param apiPath - The path to the Execution
|
|
90
|
+
* @param apiPath - The path to the Execution API file.
|
|
77
91
|
* @param options - The options for configuring the worker, including the execution context, exposed methods, timeout, and mode.
|
|
78
|
-
* @returns A promise that resolves to an instance of the
|
|
92
|
+
* @returns A promise that resolves to an instance of the ExecutionApiWorker class.
|
|
79
93
|
*/
|
|
80
94
|
static async from(apiPath, options) {
|
|
81
95
|
const mode = await (0, _powerlines_core_lib_config.getDefaultMode)(options.context.cwd);
|
|
82
96
|
const resolvedPath = await (0, _stryke_fs_resolve.resolve)(apiPath, { paths: [options.context.cwd, options.root ? (0, _stryke_path_append.appendPath)(options.root, options.context.cwd) : void 0].filter(Boolean) });
|
|
83
|
-
if (!resolvedPath) throw new Error(`Could not resolve the provided Execution
|
|
84
|
-
|
|
85
|
-
if (exposedMethods.length === 0) {
|
|
86
|
-
const jiti$1 = (0, jiti.createJiti)(require("url").pathToFileURL(__filename).href, {
|
|
87
|
-
cache: false,
|
|
88
|
-
interopDefault: true,
|
|
89
|
-
tsconfigPaths: true
|
|
90
|
-
});
|
|
91
|
-
const mod = await jiti$1.import(jiti$1.esmResolve(resolvedPath));
|
|
92
|
-
if ((0, _stryke_type_checks_is_function.isFunction)(mod)) exposedMethods.push(...exposedMethods, "default");
|
|
93
|
-
else if ((0, _stryke_type_checks_is_set_object.isSetObject)(mod)) exposedMethods = Object.keys(mod).filter((name) => (0, _stryke_type_checks_is_function.isFunction)(mod[name]));
|
|
94
|
-
}
|
|
95
|
-
return new ExecutionHostWorker(resolvedPath, exposedMethods, {
|
|
97
|
+
if (!resolvedPath) throw new Error(`Could not resolve the provided Execution API path: \`${apiPath}\`.`);
|
|
98
|
+
return new ExecutionApiWorker(resolvedPath, {
|
|
96
99
|
mode,
|
|
97
100
|
...options
|
|
98
101
|
});
|
|
99
102
|
}
|
|
100
103
|
/**
|
|
101
|
-
* Create a new worker instance.
|
|
104
|
+
* Create a new API worker instance.
|
|
102
105
|
*
|
|
103
|
-
* @param
|
|
104
|
-
* @param
|
|
105
|
-
* @param options - The options for the worker, including exposed methods, timeout, and hooks for activity and restart.
|
|
106
|
+
* @param executionApiPath - The path to the worker file.
|
|
107
|
+
* @param options - The options for the worker, including exposed commands, timeout, and hooks for activity and restart.
|
|
106
108
|
*/
|
|
107
|
-
constructor(
|
|
108
|
-
this.
|
|
109
|
-
this.exposedMethods = exposedMethods;
|
|
109
|
+
constructor(executionApiPath, options) {
|
|
110
|
+
this.executionApiPath = executionApiPath;
|
|
110
111
|
this.options = options;
|
|
111
|
-
const {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
let resolveRestartPromise;
|
|
115
|
-
let activeTasks = 0;
|
|
112
|
+
const { isolatedMemory = false, mode = "production", context } = this.options;
|
|
113
|
+
this.options.timeout ??= 9e5;
|
|
114
|
+
this.#logger = context.extendLogger({ category: "communication" });
|
|
116
115
|
this.#worker = void 0;
|
|
117
116
|
process.on("exit", () => {
|
|
118
117
|
this.finalize();
|
|
@@ -209,103 +208,64 @@ var ExecutionHostWorker = class ExecutionHostWorker {
|
|
|
209
208
|
].includes(key)) execArgv.push(formatted);
|
|
210
209
|
else nodeOptionsParts.push(formatted);
|
|
211
210
|
}
|
|
212
|
-
|
|
213
|
-
if (!this.#worker) return;
|
|
214
|
-
const resolve = resolveRestartPromise;
|
|
215
|
-
createWorker();
|
|
216
|
-
logger.warn(`Sending SIGTERM signal to worker due to timeout${timeout ? ` of ${(0, date_fns_formatDuration.formatDuration)({ seconds: timeout / 1e3 })}` : ""}. Subsequent errors may be a result of the worker exiting.`);
|
|
217
|
-
this.finalize().then(() => {
|
|
218
|
-
resolve(RESTARTED);
|
|
219
|
-
});
|
|
220
|
-
};
|
|
221
|
-
let hangingTimer = false;
|
|
222
|
-
const onActivity = () => {
|
|
223
|
-
if (hangingTimer) clearTimeout(hangingTimer);
|
|
224
|
-
hangingTimer = activeTasks > 0 && setTimeout(onHanging, timeout);
|
|
225
|
-
};
|
|
226
|
-
const createWorker = () => {
|
|
211
|
+
this.#createWorker = () => {
|
|
227
212
|
const env = {
|
|
228
213
|
...process.env,
|
|
229
214
|
NODE_ENV: mode,
|
|
230
215
|
NODE_OPTIONS: nodeOptionsParts.join(" "),
|
|
231
|
-
|
|
216
|
+
POWERLINES_EXECUTION_WORKER: "true"
|
|
232
217
|
};
|
|
233
218
|
if (env.FORCE_COLOR === void 0 && !env.NO_COLOR && !env.CI && env.TERM !== "dumb" && (process.stdout.isTTY || process.stderr?.isTTY)) env.FORCE_COLOR = "1";
|
|
234
|
-
logger.debug(`Creating worker from file ${
|
|
219
|
+
this.#logger.debug(`Creating worker from file ${executionApiPath} with execution arguments: ${JSON.stringify(execArgv, null, 2)}`);
|
|
235
220
|
this.#worker = new piscina.default({
|
|
236
|
-
filename:
|
|
221
|
+
filename: executionApiPath,
|
|
237
222
|
execArgv,
|
|
238
223
|
env
|
|
239
224
|
});
|
|
240
|
-
restartPromise = new Promise((resolve) => {
|
|
241
|
-
resolveRestartPromise = resolve;
|
|
225
|
+
this.#restartPromise = new Promise((resolve) => {
|
|
226
|
+
this.#resolveRestartPromise = resolve;
|
|
242
227
|
});
|
|
243
228
|
this.#worker.on("exit", (code, signal) => {
|
|
244
|
-
logger.debug(`Worker process exited with code ${code} and signal ${signal}`);
|
|
229
|
+
this.#logger.debug(`Worker process exited with code ${code} and signal ${signal}`);
|
|
245
230
|
if ((code || signal && signal !== "SIGINT") && this.#worker) {
|
|
246
231
|
const error = /* @__PURE__ */ new Error(`Execution Host Worker exited unexpectedly with code ${code} and signal ${signal}`);
|
|
247
|
-
logger.error(error);
|
|
232
|
+
this.#logger.error(error);
|
|
248
233
|
this.finalize().then(() => {
|
|
249
234
|
throw error;
|
|
250
235
|
});
|
|
251
236
|
}
|
|
252
237
|
});
|
|
253
238
|
this.#worker.on("error", (error) => {
|
|
254
|
-
logger.error({
|
|
239
|
+
this.#logger.error({
|
|
255
240
|
meta: { category: "communication" },
|
|
256
241
|
message: `Worker process emitted an error: ${error.message}`,
|
|
257
242
|
error
|
|
258
243
|
});
|
|
259
244
|
});
|
|
260
245
|
this.#worker.on("message", (data) => {
|
|
261
|
-
onActivity();
|
|
262
|
-
if (Array.isArray(data) && data.length > 1 && (0, _stryke_type_checks_is_number.isNumber)(data[0])) if (data[0] === 0) logger.trace(`Received message from worker: ${JSON.stringify(data.slice(1), null, 2)}`);
|
|
263
|
-
else logger.debug(`Received error message from worker: ${JSON.stringify(data.slice(1), null, 2)}`);
|
|
264
|
-
logger.trace(`Received message from worker: ${JSON.stringify(data, null, 2)}`);
|
|
246
|
+
this.onActivity();
|
|
247
|
+
if (Array.isArray(data) && data.length > 1 && (0, _stryke_type_checks_is_number.isNumber)(data[0])) if (data[0] === 0) this.#logger.trace(`Received message from worker: ${JSON.stringify(data.slice(1), null, 2)}`);
|
|
248
|
+
else this.#logger.debug(`Received error message from worker: ${JSON.stringify(data.slice(1), null, 2)}`);
|
|
249
|
+
this.#logger.trace(`Received message from worker: ${JSON.stringify(data, null, 2)}`);
|
|
265
250
|
});
|
|
266
251
|
};
|
|
267
|
-
createWorker();
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
name: method,
|
|
279
|
-
transferList: [port2]
|
|
280
|
-
});
|
|
281
|
-
let aborted = false;
|
|
282
|
-
const onActivityAbort = () => {
|
|
283
|
-
if (!aborted) aborted = true;
|
|
284
|
-
};
|
|
285
|
-
(0, node_stream.pipeline)(new require_helpers_stream.MessagePortDuplex(port1, { onActivityAbort }), process.stdout, (err) => {
|
|
286
|
-
if (err) {
|
|
287
|
-
logger.debug(`Received exception message from worker: ${JSON.stringify(err, null, 2)}`);
|
|
288
|
-
throw err;
|
|
289
|
-
}
|
|
290
|
-
});
|
|
291
|
-
await promise;
|
|
292
|
-
};
|
|
293
|
-
this[method] = timeout ? async (options, inlineConfig) => {
|
|
294
|
-
activeTasks++;
|
|
295
|
-
try {
|
|
296
|
-
let attempts = 0;
|
|
297
|
-
for (;;) {
|
|
298
|
-
onActivity();
|
|
299
|
-
const result = await Promise.race([callWorker(options, inlineConfig), restartPromise]);
|
|
300
|
-
if (result !== RESTARTED) return result;
|
|
301
|
-
logger.warn(`Execution Host Worker was restarted while calling method "${method}" (attempt ${attempts++}). Retrying the call...`);
|
|
302
|
-
}
|
|
303
|
-
} finally {
|
|
304
|
-
activeTasks--;
|
|
305
|
-
onActivity();
|
|
252
|
+
this.#createWorker();
|
|
253
|
+
}
|
|
254
|
+
async execute(command, options, inlineConfig) {
|
|
255
|
+
if (this.options.timeout) {
|
|
256
|
+
this.#activeTasks++;
|
|
257
|
+
try {
|
|
258
|
+
let attempts = 0;
|
|
259
|
+
for (;;) {
|
|
260
|
+
this.onActivity();
|
|
261
|
+
if (await Promise.race([this.innerExecute(command, options, inlineConfig), this.#restartPromise]) !== RESTARTED) return;
|
|
262
|
+
this.#logger.warn(`Execution Host Worker was restarted while calling method "${command}" (attempt ${attempts++}). Retrying the call...`);
|
|
306
263
|
}
|
|
307
|
-
}
|
|
308
|
-
|
|
264
|
+
} finally {
|
|
265
|
+
this.#activeTasks--;
|
|
266
|
+
this.onActivity();
|
|
267
|
+
}
|
|
268
|
+
} else await this.innerExecute(command, options, inlineConfig);
|
|
309
269
|
}
|
|
310
270
|
/**
|
|
311
271
|
* Closes the worker process, terminating it if it's still running. This method should be called when the worker is no longer needed, to free up system resources and ensure a clean shutdown. If the worker has already been terminated, this method will have no effect.
|
|
@@ -316,6 +276,39 @@ var ExecutionHostWorker = class ExecutionHostWorker {
|
|
|
316
276
|
await worker.close({ force: true });
|
|
317
277
|
this.#worker = void 0;
|
|
318
278
|
}
|
|
279
|
+
onHanging() {
|
|
280
|
+
if (!this.#worker) return;
|
|
281
|
+
this.#createWorker();
|
|
282
|
+
this.#logger.warn(`Sending SIGTERM signal to worker due to timeout${this.options.timeout ? ` of ${(0, date_fns_formatDuration.formatDuration)({ seconds: this.options.timeout / 1e3 })}` : ""}. Subsequent errors may be a result of the worker exiting.`);
|
|
283
|
+
this.finalize().then(() => {
|
|
284
|
+
this.#resolveRestartPromise?.(RESTARTED);
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
onActivity() {
|
|
288
|
+
if (this.#hangingTimer) clearTimeout(this.#hangingTimer);
|
|
289
|
+
this.#hangingTimer = this.#activeTasks > 0 && setTimeout(() => this.onHanging(), this.options.timeout);
|
|
290
|
+
}
|
|
291
|
+
async innerExecute(command, options, inlineConfig) {
|
|
292
|
+
if (!this.#worker) throw new Error("Execution Host Worker is not initialized");
|
|
293
|
+
const { port1, port2 } = new node_worker_threads.MessageChannel();
|
|
294
|
+
const promise = this.#worker.run({
|
|
295
|
+
command,
|
|
296
|
+
options,
|
|
297
|
+
inlineConfig,
|
|
298
|
+
port: port2
|
|
299
|
+
}, { transferList: [port2] });
|
|
300
|
+
let aborted = false;
|
|
301
|
+
const onActivityAbort = () => {
|
|
302
|
+
if (!aborted) aborted = true;
|
|
303
|
+
};
|
|
304
|
+
(0, node_stream.pipeline)(new require_helpers_stream.MessagePortDuplex(port1, { onActivityAbort }), process.stdout, (err) => {
|
|
305
|
+
if (err) {
|
|
306
|
+
this.#logger.debug(`Received exception message from worker: ${JSON.stringify(err, null, 2)}`);
|
|
307
|
+
throw err;
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
await promise;
|
|
311
|
+
}
|
|
319
312
|
};
|
|
320
313
|
|
|
321
314
|
//#endregion
|
|
@@ -333,7 +326,7 @@ var PowerlinesEngine = class {
|
|
|
333
326
|
/**
|
|
334
327
|
* The execution host, which provides methods to call the execution API functions from the engine context. This allows the engine to invoke commands and other API functions during the execution of Powerlines commands, enabling communication between the engine and the execution contexts.
|
|
335
328
|
*/
|
|
336
|
-
#
|
|
329
|
+
#api;
|
|
337
330
|
/**
|
|
338
331
|
* The Powerlines context
|
|
339
332
|
*/
|
|
@@ -343,19 +336,19 @@ var PowerlinesEngine = class {
|
|
|
343
336
|
/**
|
|
344
337
|
* The execution host, which provides methods to call the execution API functions from the engine context. This allows the engine to invoke commands and other API functions during the execution of Powerlines commands, enabling communication between the engine and the execution contexts.
|
|
345
338
|
*/
|
|
346
|
-
get
|
|
347
|
-
return this.#
|
|
339
|
+
get api() {
|
|
340
|
+
return this.#api;
|
|
348
341
|
}
|
|
349
342
|
/**
|
|
350
343
|
* Create a new Powerlines Engine instance
|
|
351
344
|
*
|
|
352
345
|
* @param context - The Powerlines context
|
|
353
|
-
* @param
|
|
346
|
+
* @param api - The API host for the execution workers
|
|
354
347
|
* @returns A new instance of the Powerlines Engine
|
|
355
348
|
*/
|
|
356
|
-
constructor(context,
|
|
349
|
+
constructor(context, api) {
|
|
357
350
|
this.#context = context;
|
|
358
|
-
this.#
|
|
351
|
+
this.#api = api;
|
|
359
352
|
}
|
|
360
353
|
/**
|
|
361
354
|
* Create a new Powerlines project
|
|
@@ -504,7 +497,7 @@ var PowerlinesEngine = class {
|
|
|
504
497
|
async finalize() {
|
|
505
498
|
const timer = this.context.timer("Finalize");
|
|
506
499
|
this.context.info("🏁 Finalization processes started");
|
|
507
|
-
await this.
|
|
500
|
+
await this.api.finalize();
|
|
508
501
|
this.context.debug("✔ Finalization completed successfully");
|
|
509
502
|
timer();
|
|
510
503
|
}
|
|
@@ -520,16 +513,16 @@ var PowerlinesEngine = class {
|
|
|
520
513
|
* @remarks
|
|
521
514
|
* This method will load the executions for the specified command and inline configuration, then execute each one while managing their lifecycle, including handling their completion and any errors that may occur during execution.
|
|
522
515
|
*
|
|
523
|
-
* @param
|
|
516
|
+
* @param command - The path to the execution configuration to load and run, which can be used to specify different execution configurations for different commands or scenarios.
|
|
524
517
|
* @param inlineConfig - Additional configuration options provided at runtime, which can override or supplement the options defined in the user configuration file.
|
|
525
518
|
* @returns A promise that resolves when all executions for the specified command have completed
|
|
526
519
|
*/
|
|
527
|
-
async execute(
|
|
528
|
-
await Promise.all((await this.context.loadExecutions(
|
|
520
|
+
async execute(command, inlineConfig) {
|
|
521
|
+
await Promise.all((await this.context.loadExecutions(command, inlineConfig)).map(async (execution) => {
|
|
529
522
|
try {
|
|
530
|
-
await this.
|
|
523
|
+
await this.api.execute(command, execution.options, inlineConfig);
|
|
531
524
|
} catch (error) {
|
|
532
|
-
this.context.error(`Execution of method "${
|
|
525
|
+
this.context.error(`Execution of method "${command}" failed for execution with invocation ID "${execution.invocationId}" and execution ID "${execution.options.executionId}": \n\n${error instanceof Error ? error.stack || error.message : String(error)}`);
|
|
533
526
|
throw error;
|
|
534
527
|
} finally {
|
|
535
528
|
this.context.completeExecution(execution.invocationId, execution.options.executionId);
|
|
@@ -558,13 +551,12 @@ async function createContext(options) {
|
|
|
558
551
|
websocket: port
|
|
559
552
|
});
|
|
560
553
|
}
|
|
561
|
-
async function createEngine(options, apiPath = "@powerlines/engine/api"
|
|
554
|
+
async function createEngine(options, apiPath = "@powerlines/engine/api") {
|
|
562
555
|
node_events.EventEmitter.setMaxListeners(Infinity);
|
|
563
556
|
const context = await createContext(options);
|
|
564
|
-
return new PowerlinesEngine(context, await
|
|
557
|
+
return new PowerlinesEngine(context, await ExecutionApiWorker.from(apiPath, {
|
|
565
558
|
root: options.root,
|
|
566
|
-
context
|
|
567
|
-
apiMethods
|
|
559
|
+
context
|
|
568
560
|
}));
|
|
569
561
|
}
|
|
570
562
|
|
package/dist/engine.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_engine = require('./engine-
|
|
2
|
+
const require_engine = require('./engine-DlOFwFgt.cjs');
|
|
3
3
|
|
|
4
4
|
exports.PowerlinesEngine = require_engine.PowerlinesEngine;
|
|
5
5
|
exports.createContext = require_engine.createContext;
|