@runium/core 0.0.4 → 0.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.
Files changed (3) hide show
  1. package/index.d.ts +6 -1
  2. package/index.js +137 -128
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -23,6 +23,8 @@ export declare enum FileErrorCode {
23
23
 
24
24
  export declare function getProjectSchema(): object;
25
25
 
26
+ export declare const ID_REGEX: RegExp;
27
+
26
28
  export declare class IntervalTrigger extends RuniumTrigger<IntervalTriggerOptions> {
27
29
  constructor(options: IntervalTriggerOptions, project: RuniumTriggerProjectAccessible);
28
30
  enable(): void;
@@ -234,7 +236,8 @@ export declare enum ProjectTaskRestartPolicyType {
234
236
 
235
237
  export declare enum ProjectTaskStartMode {
236
238
  IMMEDIATE = "immediate",
237
- DEFERRED = "deferred"
239
+ DEFERRED = "deferred",
240
+ IGNORE = "ignore"
238
241
  }
239
242
 
240
243
  export declare type ProjectTaskStateCondition = string | boolean | Partial<RuniumTaskState> | ((state: RuniumTaskState) => boolean);
@@ -342,7 +345,9 @@ export declare class Task extends RuniumTask<TaskOptions, TaskState> {
342
345
  constructor(options: TaskOptions);
343
346
  getState(): TaskState;
344
347
  getOptions(): TaskOptions;
348
+ protected canStart(): boolean;
345
349
  start(): Promise<void>;
350
+ protected canStop(): boolean;
346
351
  stop(reason?: string): Promise<void>;
347
352
  restart(): Promise<void>;
348
353
  protected updateState(state: Partial<TaskState>): void;
package/index.js CHANGED
@@ -1,11 +1,11 @@
1
- import { readFile as G, writeFile as x, mkdir as $ } from "node:fs/promises";
2
- import { EventEmitter as O } from "node:events";
3
- import M from "bcx-expression-evaluator";
4
- import q from "ajv/dist/2020.js";
5
- import K from "ajv-keywords";
6
- import { spawn as U } from "node:child_process";
7
- import { createWriteStream as j } from "node:fs";
8
- import { resolve as I, dirname as w } from "node:path";
1
+ import { readFile as x, writeFile as M, mkdir as j } from "node:fs/promises";
2
+ import { EventEmitter as v } from "node:events";
3
+ import q from "bcx-expression-evaluator";
4
+ import K from "ajv/dist/2020.js";
5
+ import U from "ajv-keywords";
6
+ import { spawn as F } from "node:child_process";
7
+ import { createWriteStream as w } from "node:fs";
8
+ import { resolve as I, dirname as P } from "node:path";
9
9
  class p extends Error {
10
10
  code;
11
11
  payload;
@@ -13,67 +13,67 @@ class p extends Error {
13
13
  super(t), this.code = s, this.payload = r;
14
14
  }
15
15
  }
16
- function Et(e) {
16
+ function At(e) {
17
17
  return !!e && e instanceof p;
18
18
  }
19
- var F = ((e) => (e.READ_JSON = "file-read-json", e.WRITE_JSON = "file-write-json", e))(F || {});
20
- async function At(e) {
19
+ var Y = ((e) => (e.READ_JSON = "file-read-json", e.WRITE_JSON = "file-write-json", e))(Y || {});
20
+ async function _t(e) {
21
21
  try {
22
- const t = await G(e, { encoding: "utf-8" });
22
+ const t = await x(e, { encoding: "utf-8" });
23
23
  return JSON.parse(t);
24
24
  } catch (t) {
25
25
  throw new p(`Can not read JSON file ${e}`, "file-read-json", { path: e, original: t });
26
26
  }
27
27
  }
28
- async function _t(e, t) {
28
+ async function It(e, t) {
29
29
  try {
30
- await x(e, JSON.stringify(t, null, 2), { encoding: "utf-8" });
30
+ await M(e, JSON.stringify(t, null, 2), { encoding: "utf-8" });
31
31
  } catch (s) {
32
32
  throw new p(`Can not write JSON file ${e}`, "file-write-json", { path: e, data: t, original: s });
33
33
  }
34
34
  }
35
- const Y = String.raw`"\$unwrap\((.*)\)"`;
36
- var V = ((e) => (e.MACRO_APPLY_ERROR = "macro-apply-error", e))(V || {});
37
- function It(e, t) {
35
+ const V = String.raw`"\$unwrap\((.*)\)"`;
36
+ var J = ((e) => (e.MACRO_APPLY_ERROR = "macro-apply-error", e))(J || {});
37
+ function $t(e, t) {
38
38
  const s = Object.keys(t), r = String.raw`\$(${s.join("|")})\(([^()]*(?:\([^()]*\)[^()]*)*)\)`, i = (o) => {
39
39
  const a = new RegExp(r, "g");
40
40
  let c = o, n = !0;
41
- for (; n; ) n = !1, c = c.replace(a, (u, A, L) => {
41
+ for (; n; ) n = !1, c = c.replace(a, (u, A, N) => {
42
42
  n = !0;
43
- const m = [];
44
- let _ = 0, y = "";
45
- for (const g of L) g === "," && _ === 0 ? (m.push(y.trim()), y = "") : (g === "(" && _++, g === ")" && _--, y += g);
46
- m.push(y.trim());
47
- const N = m.map((g) => g ? i(g) : "");
43
+ const y = [];
44
+ let _ = 0, S = "";
45
+ for (const g of N) g === "," && _ === 0 ? (y.push(S.trim()), S = "") : (g === "(" && _++, g === ")" && _--, S += g);
46
+ y.push(S.trim());
47
+ const G = y.map((g) => g ? i(g) : "");
48
48
  try {
49
- return t[A](...N);
49
+ return t[A](...G);
50
50
  } catch (g) {
51
- throw new p(`Can not apply macro "${A}"`, "macro-apply-error", { type: A, args: m, original: g });
51
+ throw new p(`Can not apply macro "${A}"`, "macro-apply-error", { type: A, args: y, original: g });
52
52
  }
53
53
  });
54
54
  return c;
55
55
  };
56
56
  return (function(o) {
57
- const a = new RegExp(Y, "g");
57
+ const a = new RegExp(V, "g");
58
58
  return o.replace(a, (c, n) => n.trim());
59
59
  })(s.length ? i(e) : e);
60
60
  }
61
- var R = ((e) => (e.IMMEDIATE = "immediate", e.DEFERRED = "deferred", e))(R || {}), d = ((e) => (e.EMIT_EVENT = "emit-event", e.START_TASK = "start-task", e.RESTART_TASK = "restart-task", e.STOP_TASK = "stop-task", e.STOP_PROJECT = "stop-project", e.ENABLE_TRIGGER = "enable-trigger", e.DISABLE_TRIGGER = "disable-trigger", e))(d || {}), f = ((e) => (e.DEFAULT = "default", e))(f || {}), l = ((e) => (e.EVENT = "event", e.TIMEOUT = "timeout", e.INTERVAL = "interval", e))(l || {}), T = ((e) => (e.ALWAYS = "always", e.ON_FAILURE = "on-failure", e))(T || {}), J = ((e) => (e.INCORRECT_DATA = "project-config-incorrect-data", e.TASKS_CIRCULAR_DEPENDENCY = "project-config-tasks-circular-dependency", e.TASK_NOT_EXISTS = "project-config-task-not-exists", e.TRIGGER_NOT_EXISTS = "project-config-trigger-not-exists", e))(J || {});
62
- const B = /* @__PURE__ */ new Set(["start-task", "restart-task", "stop-task"]), H = /* @__PURE__ */ new Set(["enable-trigger", "disable-trigger"]), W = new Set(Object.values(d)), X = new Set(Object.values(l));
63
- function P(e) {
64
- return B.has(e.type);
65
- }
61
+ var f = ((e) => (e.IMMEDIATE = "immediate", e.DEFERRED = "deferred", e.IGNORE = "ignore", e))(f || {}), d = ((e) => (e.EMIT_EVENT = "emit-event", e.START_TASK = "start-task", e.RESTART_TASK = "restart-task", e.STOP_TASK = "stop-task", e.STOP_PROJECT = "stop-project", e.ENABLE_TRIGGER = "enable-trigger", e.DISABLE_TRIGGER = "disable-trigger", e))(d || {}), T = ((e) => (e.DEFAULT = "default", e))(T || {}), l = ((e) => (e.EVENT = "event", e.TIMEOUT = "timeout", e.INTERVAL = "interval", e))(l || {}), m = ((e) => (e.ALWAYS = "always", e.ON_FAILURE = "on-failure", e))(m || {}), B = ((e) => (e.INCORRECT_DATA = "project-config-incorrect-data", e.TASKS_CIRCULAR_DEPENDENCY = "project-config-tasks-circular-dependency", e.TASK_NOT_EXISTS = "project-config-task-not-exists", e.TRIGGER_NOT_EXISTS = "project-config-trigger-not-exists", e))(B || {});
62
+ const H = /* @__PURE__ */ new Set(["start-task", "restart-task", "stop-task"]), W = /* @__PURE__ */ new Set(["enable-trigger", "disable-trigger"]), X = new Set(Object.values(d)), z = new Set(Object.values(l));
66
63
  function b(e) {
67
64
  return H.has(e.type);
68
65
  }
69
- function z(e) {
70
- return !W.has(e.type);
66
+ function O(e) {
67
+ return W.has(e.type);
71
68
  }
72
- function Q(e) {
69
+ function Z(e) {
73
70
  return !X.has(e.type);
74
71
  }
75
- const v = new q({ allowUnionTypes: !0 });
76
- function Z(e) {
72
+ function Q(e) {
73
+ return !z.has(e.type);
74
+ }
75
+ const C = new K({ allowUnionTypes: !0, allErrors: !0, verbose: !0 });
76
+ function tt(e) {
77
77
  const t = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Set();
78
78
  for (const i of e.tasks) s.add(i.id), t.set(i.id, []);
79
79
  const r = new Set(e.triggers?.map((i) => i.id) || []);
@@ -83,13 +83,13 @@ function Z(e) {
83
83
  t.get(o.taskId).push(i.id);
84
84
  }
85
85
  for (const o of i.handlers || []) {
86
- if (P(o.action) && !s.has(o.action.taskId)) throw new p(`Task "${i.id}" handler action uses not existing task "${o.action.taskId}"`, "project-config-task-not-exists", { taskId: i.id, handler: { ...o }, scope: "handlers" });
87
- if (b(o.action) && !r.has(o.action.triggerId)) throw new p(`Task "${i.id}" handler action uses not existing trigger "${o.action.triggerId}"`, "project-config-trigger-not-exists", { taskId: i.id, handler: { ...o }, scope: "handlers" });
86
+ if (b(o.action) && !s.has(o.action.taskId)) throw new p(`Task "${i.id}" handler action uses not existing task "${o.action.taskId}"`, "project-config-task-not-exists", { taskId: i.id, handler: { ...o }, scope: "handlers" });
87
+ if (O(o.action) && !r.has(o.action.triggerId)) throw new p(`Task "${i.id}" handler action uses not existing trigger "${o.action.triggerId}"`, "project-config-trigger-not-exists", { taskId: i.id, handler: { ...o }, scope: "handlers" });
88
88
  }
89
89
  }
90
90
  for (const i of e.triggers || []) {
91
- if (P(i.action) && !s.has(i.action.taskId)) throw new p(`Trigger "${i.id}" action uses not existing task "${i.action.taskId}"`, "project-config-task-not-exists", { trigger: { ...i }, scope: "triggers" });
92
- if (b(i.action) && !r.has(i.action.triggerId)) throw new p(`Trigger "${i.id}" action uses not existing trigger "${i.action.triggerId}"`, "project-config-trigger-not-exists", { trigger: { ...i }, scope: "triggers" });
91
+ if (b(i.action) && !s.has(i.action.taskId)) throw new p(`Trigger "${i.id}" action uses not existing task "${i.action.taskId}"`, "project-config-task-not-exists", { trigger: { ...i }, scope: "triggers" });
92
+ if (O(i.action) && !r.has(i.action.triggerId)) throw new p(`Trigger "${i.id}" action uses not existing trigger "${i.action.triggerId}"`, "project-config-trigger-not-exists", { trigger: { ...i }, scope: "triggers" });
93
93
  }
94
94
  (function(i) {
95
95
  const o = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), c = (n) => {
@@ -106,21 +106,21 @@ function Z(e) {
106
106
  for (const n of i.keys()) o.has(n) || c(n);
107
107
  })(t);
108
108
  }
109
- function tt(e, t) {
109
+ function et(e, t) {
110
110
  (function(s, r) {
111
- const i = v.compile(r || {});
111
+ const i = C.compile(r || {});
112
112
  if (!i(s)) throw new p("Incorrect project config data", "project-config-incorrect-data", { errors: i.errors });
113
- })(e, t), Z(e);
113
+ })(e, t), tt(e);
114
114
  }
115
- K(v, ["uniqueItemProperties"]);
116
- var h = ((e) => (e.IDLE = "idle", e.STARTING = "starting", e.STARTED = "started", e.COMPLETED = "completed", e.FAILED = "failed", e.STOPPING = "stopping", e.STOPPED = "stopped", e))(h || {}), S = ((e) => (e.STATE_CHANGE = "state-change", e.STDOUT = "stdout", e.STDERR = "stderr", e))(S || {});
117
- const $t = -1;
118
- class C extends O {
115
+ U(C, ["uniqueItemProperties"]);
116
+ var h = ((e) => (e.IDLE = "idle", e.STARTING = "starting", e.STARTED = "started", e.COMPLETED = "completed", e.FAILED = "failed", e.STOPPING = "stopping", e.STOPPED = "stopped", e))(h || {}), E = ((e) => (e.STATE_CHANGE = "state-change", e.STDOUT = "stdout", e.STDERR = "stderr", e))(E || {});
117
+ const jt = -1;
118
+ class D extends v {
119
119
  constructor(t) {
120
120
  super(), this.options = t;
121
121
  }
122
122
  }
123
- class et extends C {
123
+ class st extends D {
124
124
  constructor(t) {
125
125
  super(t), this.options = t, this.setMaxListeners(50), this.options.env = { ...process.env, ...t.env || {} }, this.options.cwd = I(process.cwd(), t.cwd || "");
126
126
  }
@@ -135,21 +135,28 @@ class et extends C {
135
135
  getOptions() {
136
136
  return { ...this.options };
137
137
  }
138
- async start() {
138
+ canStart() {
139
139
  const { status: t } = this.state;
140
- if (t !== "started" && t !== "starting" && t !== "stopping") {
140
+ return t !== "started" && t !== "starting" && t !== "stopping";
141
+ }
142
+ async start() {
143
+ if (this.canStart()) {
141
144
  this.updateState({ status: "starting", iteration: this.state.iteration + 1, pid: -1, exitCode: void 0, error: void 0 });
142
145
  try {
143
146
  await this.initLogStreams();
144
- const { cwd: s, command: r, arguments: i = [], env: o, shell: a = !0 } = this.options;
145
- this.process = U(r, i, { cwd: s, env: o, shell: a, stdio: ["ignore", "pipe", "pipe"] }), this.addProcessListeners(), this.setTTLTimer(), this.updateState({ status: "started", pid: this.process.pid });
146
- } catch (s) {
147
- this.onError(s);
147
+ const { cwd: t, command: s, arguments: r = [], env: i, shell: o = !0 } = this.options;
148
+ this.process = F(s, r, { cwd: t, env: i, shell: o, stdio: ["ignore", "pipe", "pipe"] }), this.addProcessListeners(), this.setTTLTimer(), this.updateState({ status: "started", pid: this.process.pid });
149
+ } catch (t) {
150
+ this.onError(t);
148
151
  }
149
152
  }
150
153
  }
154
+ canStop() {
155
+ const { status: t } = this.state;
156
+ return !!this.process && t === "started";
157
+ }
151
158
  async stop(t = "") {
152
- if (this.process && this.state.status !== "stopping" && this.state.status === "started") return this.updateState({ status: "stopping", reason: t }), new Promise((s) => {
159
+ if (this.canStop()) return this.updateState({ status: "stopping", reason: t }), new Promise((s) => {
153
160
  const r = this.options.stopSignal || "SIGTERM";
154
161
  this.process.kill(r), this.process.on("exit", () => {
155
162
  s();
@@ -167,11 +174,11 @@ class et extends C {
167
174
  const { stdout: t = null, stderr: s = null } = this.options.log || {};
168
175
  if (t) {
169
176
  const r = I(t);
170
- await $(w(r), { recursive: !0 }), this.stdoutStream = j(t, { flags: "w" });
177
+ await j(P(r), { recursive: !0 }), this.stdoutStream = w(t, { flags: "w" });
171
178
  }
172
179
  if (s) {
173
180
  const r = I(s);
174
- await $(w(r), { recursive: !0 }), this.stderrStream = j(s, { flags: "w" });
181
+ await j(P(r), { recursive: !0 }), this.stderrStream = w(s, { flags: "w" });
175
182
  }
176
183
  }
177
184
  setTTLTimer() {
@@ -202,23 +209,23 @@ class et extends C {
202
209
  this.ttlTimer && (clearTimeout(this.ttlTimer), this.ttlTimer = null), this.process && (this.process.removeAllListeners(), this.process.stdout?.removeAllListeners(), this.process.stderr?.removeAllListeners(), this.process = null), this.stdoutStream && (this.stdoutStream.end(), this.stdoutStream = null), this.stderrStream && (this.stderrStream.end(), this.stderrStream = null);
203
210
  }
204
211
  }
205
- var st = ((e) => (e.ACTION_TYPE_ALREADY_USED = "project-schema-action-type-already-used", e.TASK_TYPE_ALREADY_USED = "project-schema-task-type-already-used", e.TRIGGER_TYPE_ALREADY_USED = "project-schema-trigger-type-already-used", e))(st || {});
206
- const rt = { id: { type: "string" }, name: { type: "string" }, type: { type: "string" }, mode: { $ref: "#/$defs/Runium_TaskStartMode" }, dependencies: { type: "array", items: { $ref: "#/$defs/Runium_TaskDependency" } }, handlers: { type: "array", items: { $ref: "#/$defs/Runium_TaskHandler" } }, restart: { $ref: "#/$defs/Runium_TaskRestartPolicy" } }, k = { id: { type: "string" }, action: { $ref: "#/$defs/Runium_Action" }, disabled: { type: "boolean" } };
207
- function D(e, t) {
208
- return { type: "object", properties: { ...structuredClone(rt), type: { const: e }, options: { ...structuredClone(t) } }, required: ["id", "options"], additionalProperties: !1 };
212
+ var rt = ((e) => (e.ACTION_TYPE_ALREADY_USED = "project-schema-action-type-already-used", e.TASK_TYPE_ALREADY_USED = "project-schema-task-type-already-used", e.TRIGGER_TYPE_ALREADY_USED = "project-schema-trigger-type-already-used", e))(rt || {});
213
+ const $ = /^[a-zA-Z0-9_-]+$/, it = { id: { type: "string", pattern: $.source }, name: { type: "string" }, type: { type: "string" }, mode: { $ref: "#/$defs/Runium_TaskStartMode" }, dependencies: { type: "array", items: { $ref: "#/$defs/Runium_TaskDependency" } }, handlers: { type: "array", items: { $ref: "#/$defs/Runium_TaskHandler" } }, restart: { $ref: "#/$defs/Runium_TaskRestartPolicy" } }, R = { id: { type: "string", pattern: $.source }, action: { $ref: "#/$defs/Runium_Action" }, disabled: { type: "boolean" } };
214
+ function L(e, t) {
215
+ return { type: "object", properties: { ...structuredClone(it), type: { const: e }, options: { ...structuredClone(t) } }, required: ["id", "options"], additionalProperties: !1 };
209
216
  }
210
- function it(e, t) {
217
+ function ot(e, t) {
211
218
  return { type: "object", properties: { type: { type: "string", const: e }, ...t ? { payload: t } : {} }, required: ["type", ...t ? ["payload"] : []], additionalProperties: !1 };
212
219
  }
213
- function ot(e, t) {
220
+ function nt(e, t) {
214
221
  const s = t ? { payload: t } : {}, r = t ? ["payload"] : [];
215
- return { type: "object", properties: { ...structuredClone(k), type: { type: "string", const: e }, ...s }, required: ["id", "type", "action", ...r], additionalProperties: !1 };
222
+ return { type: "object", properties: { ...structuredClone(R), type: { type: "string", const: e }, ...s }, required: ["id", "type", "action", ...r], additionalProperties: !1 };
216
223
  }
217
- function nt() {
218
- const e = { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://example.com/schemas/project.json", title: "Project", type: "object", properties: { id: { type: "string" }, name: { type: "string" }, tasks: { type: "array", items: { oneOf: [{ $ref: "#/$defs/Runium_TaskConfig" }] }, minItems: 1, uniqueItemProperties: ["id"] }, triggers: { type: "array", items: { $ref: "#/$defs/Runium_Trigger" }, uniqueItemProperties: ["id"] } }, required: ["id", "tasks"], additionalProperties: !1, $defs: { Runium_EnvValue: { type: ["string", "number", "boolean"] }, Runium_Env: { type: "object", additionalProperties: { $ref: "#/$defs/Runium_EnvValue" } }, Runium_TaskStartMode: { type: "string", enum: Object.values(R) }, Runium_TaskHandler: { type: "object", properties: { action: { $ref: "#/$defs/Runium_Action" }, condition: { $ref: "#/$defs/Runium_TaskStateCondition" } }, required: ["action", "condition"], additionalProperties: !1 }, Runium_TaskStateCondition: { oneOf: [{ type: "string" }, { type: "boolean" }, { $ref: "#/$defs/Runium_TaskState" }] }, Runium_TaskState: { type: "object", properties: { status: { $ref: "#/$defs/Runium_TaskStatus" }, iteration: { type: "number", minimum: 0 }, exitCode: { type: "number", minimum: 0 }, reason: { type: "string" } }, additionalProperties: !1 }, Runium_TaskStatus: { type: "string", enum: Object.values(h) }, Runium_TaskDependency: { type: "object", properties: { taskId: { type: "string" }, condition: { $ref: "#/$defs/Runium_TaskStateCondition" } }, required: ["taskId", "condition"], additionalProperties: !1 }, Runium_Trigger: { oneOf: [{ $ref: "#/$defs/Runium_TriggerEvent" }, { $ref: "#/$defs/Runium_TriggerInterval" }, { $ref: "#/$defs/Runium_TriggerTimeout" }] }, Runium_TriggerEvent: { type: "object", properties: { ...structuredClone(k), type: { const: l.EVENT }, event: { type: "string" } }, required: ["id", "type", "event", "action"], additionalProperties: !1 }, Runium_TriggerInterval: { type: "object", properties: { ...structuredClone(k), type: { const: l.INTERVAL }, interval: { type: "number", minimum: 0 } }, required: ["id", "type", "interval", "action"], additionalProperties: !1 }, Runium_TriggerTimeout: { type: "object", properties: { ...structuredClone(k), type: { const: l.TIMEOUT }, timeout: { type: "number", minimum: 0 } }, required: ["id", "type", "timeout", "action"], additionalProperties: !1 }, Runium_Action: { oneOf: [{ $ref: "#/$defs/Runium_ActionEmitEvent" }, { $ref: "#/$defs/Runium_ActionProcessTask" }, { $ref: "#/$defs/Runium_ActionStopProject" }, { $ref: "#/$defs/Runium_ActionToggleTrigger" }] }, Runium_ActionEmitEvent: { type: "object", properties: { type: { type: "string", const: d.EMIT_EVENT }, event: { type: "string" } }, required: ["type", "event"], additionalProperties: !1 }, Runium_ActionProcessTask: { type: "object", properties: { type: { type: "string", enum: [d.START_TASK, d.RESTART_TASK, d.STOP_TASK] }, taskId: { type: "string" } }, required: ["type", "taskId"], additionalProperties: !1 }, Runium_ActionStopProject: { type: "object", properties: { type: { type: "string", const: d.STOP_PROJECT } }, required: ["type"], additionalProperties: !1 }, Runium_ActionToggleTrigger: { type: "object", properties: { type: { type: "string", enum: [d.ENABLE_TRIGGER, d.DISABLE_TRIGGER] }, triggerId: { type: "string" } }, required: ["type", "triggerId"], additionalProperties: !1 }, Runium_TaskConfig: { ...D(f.DEFAULT, { $ref: "#/$defs/Runium_TaskOptions" }) }, Runium_TaskOptions: { type: "object", properties: { command: { type: "string" }, arguments: { type: "array", items: { type: "string" } }, shell: { type: "boolean" }, cwd: { type: "string" }, env: { $ref: "#/$defs/Runium_Env" }, ttl: { type: "number" }, log: { $ref: "#/$defs/Runium_TaskLog" }, stopSignal: { type: "string" } }, required: ["command"], additionalProperties: !1 }, Runium_TaskRestartPolicy: { oneOf: [{ $ref: "#/$defs/Runium_TaskRestartPolicyAlways" }, { $ref: "#/$defs/Runium_TaskRestartPolicyOnFailure" }] }, Runium_TaskRestartPolicyAlways: { type: "object", required: ["policy"], properties: { policy: { const: T.ALWAYS }, delay: { type: "number" } }, additionalProperties: !1 }, Runium_TaskRestartPolicyOnFailure: { type: "object", required: ["policy"], properties: { policy: { const: T.ON_FAILURE }, delay: { type: "number" }, maxRetries: { type: "number" } }, additionalProperties: !1 }, Runium_TaskLog: { type: "object", properties: { stdout: { type: ["string", "null"] }, stderr: { type: ["string", "null"] } }, additionalProperties: !1 } } };
224
+ function at() {
225
+ const e = { $schema: "https://json-schema.org/draft/2020-12/schema", $id: "https://example.com/schemas/project.json", title: "Project", type: "object", properties: { id: { type: "string", pattern: $.source }, name: { type: "string" }, tasks: { type: "array", items: { oneOf: [{ $ref: "#/$defs/Runium_TaskConfig" }] }, minItems: 1, uniqueItemProperties: ["id"] }, triggers: { type: "array", items: { $ref: "#/$defs/Runium_Trigger" }, uniqueItemProperties: ["id"] } }, required: ["id", "tasks"], additionalProperties: !1, $defs: { Runium_EnvValue: { type: ["string", "number", "boolean"] }, Runium_Env: { type: "object", additionalProperties: { $ref: "#/$defs/Runium_EnvValue" } }, Runium_TaskStartMode: { type: "string", enum: Object.values(f) }, Runium_TaskHandler: { type: "object", properties: { action: { $ref: "#/$defs/Runium_Action" }, condition: { $ref: "#/$defs/Runium_TaskStateCondition" } }, required: ["action", "condition"], additionalProperties: !1 }, Runium_TaskStateCondition: { oneOf: [{ type: "string" }, { type: "boolean" }, { $ref: "#/$defs/Runium_TaskState" }] }, Runium_TaskState: { type: "object", properties: { status: { $ref: "#/$defs/Runium_TaskStatus" }, iteration: { type: "number", minimum: 0 }, exitCode: { type: "number", minimum: 0 }, reason: { type: "string" } }, additionalProperties: !1 }, Runium_TaskStatus: { type: "string", enum: Object.values(h) }, Runium_TaskDependency: { type: "object", properties: { taskId: { type: "string" }, condition: { $ref: "#/$defs/Runium_TaskStateCondition" } }, required: ["taskId", "condition"], additionalProperties: !1 }, Runium_Trigger: { oneOf: [{ $ref: "#/$defs/Runium_TriggerEvent" }, { $ref: "#/$defs/Runium_TriggerInterval" }, { $ref: "#/$defs/Runium_TriggerTimeout" }] }, Runium_TriggerEvent: { type: "object", properties: { ...structuredClone(R), type: { const: l.EVENT }, event: { type: "string" } }, required: ["id", "type", "event", "action"], additionalProperties: !1 }, Runium_TriggerInterval: { type: "object", properties: { ...structuredClone(R), type: { const: l.INTERVAL }, interval: { type: "number", minimum: 0 } }, required: ["id", "type", "interval", "action"], additionalProperties: !1 }, Runium_TriggerTimeout: { type: "object", properties: { ...structuredClone(R), type: { const: l.TIMEOUT }, timeout: { type: "number", minimum: 0 } }, required: ["id", "type", "timeout", "action"], additionalProperties: !1 }, Runium_Action: { oneOf: [{ $ref: "#/$defs/Runium_ActionEmitEvent" }, { $ref: "#/$defs/Runium_ActionProcessTask" }, { $ref: "#/$defs/Runium_ActionStopProject" }, { $ref: "#/$defs/Runium_ActionToggleTrigger" }] }, Runium_ActionEmitEvent: { type: "object", properties: { type: { type: "string", const: d.EMIT_EVENT }, event: { type: "string" } }, required: ["type", "event"], additionalProperties: !1 }, Runium_ActionProcessTask: { type: "object", properties: { type: { type: "string", enum: [d.START_TASK, d.RESTART_TASK, d.STOP_TASK] }, taskId: { type: "string" } }, required: ["type", "taskId"], additionalProperties: !1 }, Runium_ActionStopProject: { type: "object", properties: { type: { type: "string", const: d.STOP_PROJECT } }, required: ["type"], additionalProperties: !1 }, Runium_ActionToggleTrigger: { type: "object", properties: { type: { type: "string", enum: [d.ENABLE_TRIGGER, d.DISABLE_TRIGGER] }, triggerId: { type: "string" } }, required: ["type", "triggerId"], additionalProperties: !1 }, Runium_TaskConfig: { ...L(T.DEFAULT, { $ref: "#/$defs/Runium_TaskOptions" }) }, Runium_TaskOptions: { type: "object", properties: { command: { type: "string" }, arguments: { type: "array", items: { type: "string" } }, shell: { type: "boolean" }, cwd: { type: "string" }, env: { $ref: "#/$defs/Runium_Env" }, ttl: { type: "number" }, log: { $ref: "#/$defs/Runium_TaskLog" }, stopSignal: { type: "string" } }, required: ["command"], additionalProperties: !1 }, Runium_TaskRestartPolicy: { oneOf: [{ $ref: "#/$defs/Runium_TaskRestartPolicyAlways" }, { $ref: "#/$defs/Runium_TaskRestartPolicyOnFailure" }] }, Runium_TaskRestartPolicyAlways: { type: "object", required: ["policy"], properties: { policy: { const: m.ALWAYS }, delay: { type: "number" } }, additionalProperties: !1 }, Runium_TaskRestartPolicyOnFailure: { type: "object", required: ["policy"], properties: { policy: { const: m.ON_FAILURE }, delay: { type: "number" }, maxRetries: { type: "number" } }, additionalProperties: !1 }, Runium_TaskLog: { type: "object", properties: { stdout: { type: ["string", "null"] }, stderr: { type: ["string", "null"] } }, additionalProperties: !1 } } };
219
226
  return Object.freeze(e);
220
227
  }
221
- function at(e, t) {
228
+ function ct(e, t) {
222
229
  let s = structuredClone(e);
223
230
  return t.project && (s = (function(r, i) {
224
231
  return i && (r.properties = { ...i.properties || {}, ...r.properties }, r.required = Array.from(/* @__PURE__ */ new Set([...r.required ?? [], ...i.required ?? []]))), r;
@@ -228,11 +235,11 @@ function at(e, t) {
228
235
  if (i) {
229
236
  const o = new Set(r.properties.tasks.items.oneOf.map((c) => {
230
237
  const n = c.$ref.split("/").pop() || "";
231
- return r.$defs[n]?.properties?.type?.const || f.DEFAULT;
238
+ return r.$defs[n]?.properties?.type?.const || T.DEFAULT;
232
239
  })), a = {};
233
240
  for (const [c, n] of Object.entries(i)) {
234
241
  if (o.has(n.type)) throw new p(`Task type "${n.type}" already used in project schema`, "project-schema-task-type-already-used", { type: n.type });
235
- a[c] = D(n.type, n.options), r.properties.tasks.items.oneOf.push({ $ref: `#/$defs/${c}` }), o.add(n.type);
242
+ a[c] = L(n.type, n.options), r.properties.tasks.items.oneOf.push({ $ref: `#/$defs/${c}` }), o.add(n.type);
236
243
  }
237
244
  r.$defs = { ...a, ...r.$defs };
238
245
  }
@@ -245,7 +252,7 @@ function at(e, t) {
245
252
  }).flat()), a = {};
246
253
  for (const [c, n] of Object.entries(i)) {
247
254
  if (o.has(n.type)) throw new p(`Action type "${n.type}" already used in project schema`, "project-schema-action-type-already-used", { type: n.type });
248
- a[c] = it(n.type, n.payload), r.$defs.Runium_Action.oneOf.push({ $ref: `#/$defs/${c}` }), o.add(n.type);
255
+ a[c] = ot(n.type, n.payload), r.$defs.Runium_Action.oneOf.push({ $ref: `#/$defs/${c}` }), o.add(n.type);
249
256
  }
250
257
  r.$defs = { ...a, ...r.$defs };
251
258
  }
@@ -258,14 +265,14 @@ function at(e, t) {
258
265
  })), a = {};
259
266
  for (const [c, n] of Object.entries(i)) {
260
267
  if (o.has(n.type)) throw new p(`Trigger type "${n.type}" already used in project schema`, "project-schema-trigger-type-already-used", { type: n.type });
261
- a[c] = ot(n.type, n.payload), r.$defs.Runium_Trigger.oneOf.push({ $ref: `#/$defs/${c}` }), o.add(n.type);
268
+ a[c] = nt(n.type, n.payload), r.$defs.Runium_Trigger.oneOf.push({ $ref: `#/$defs/${c}` }), o.add(n.type);
262
269
  }
263
270
  r.$defs = { ...a, ...r.$defs };
264
271
  }
265
272
  return r;
266
273
  })(s, t.triggers)), Object.freeze(s);
267
274
  }
268
- class E {
275
+ class k {
269
276
  project;
270
277
  id;
271
278
  action;
@@ -280,7 +287,7 @@ class E {
280
287
  return this.disabled;
281
288
  }
282
289
  }
283
- class ct extends E {
290
+ class pt extends k {
284
291
  event;
285
292
  constructor(t, s) {
286
293
  super(t, s), this.event = t.event;
@@ -295,7 +302,7 @@ class ct extends E {
295
302
  this.project.processAction(this.action);
296
303
  };
297
304
  }
298
- class pt extends E {
305
+ class dt extends k {
299
306
  interval;
300
307
  intervalId = null;
301
308
  constructor(t, s) {
@@ -310,7 +317,7 @@ class pt extends E {
310
317
  this.intervalId && clearInterval(this.intervalId), this.disabled = !0, this.intervalId = null;
311
318
  }
312
319
  }
313
- class dt extends E {
320
+ class ut extends k {
314
321
  timeout;
315
322
  timeoutId = null;
316
323
  constructor(t, s) {
@@ -325,20 +332,20 @@ class dt extends E {
325
332
  this.timeoutId && clearTimeout(this.timeoutId), this.disabled = !0, this.timeoutId = null;
326
333
  }
327
334
  }
328
- var ut = ((e) => (e.STATE_CHANGE = "state-change", e.START_TASK = "start-task", e.RESTART_TASK = "restart-task", e.STOP_TASK = "stop-task", e.PROCESS_ACTION = "process-action", e.ENABLE_TRIGGER = "enable-trigger", e.DISABLE_TRIGGER = "disable-trigger", e.TASK_STATE_CHANGE = "task-state-change", e.TASK_STDOUT = "task-stdout", e.TASK_STDERR = "task-stderr", e))(ut || {}), gt = ((e) => (e.IDLE = "idle", e.STARTING = "starting", e.STARTED = "started", e.STOPPING = "stopping", e.STOPPED = "stopped", e))(gt || {}), ht = ((e) => (e.ACTION_PROCESSOR_ALREADY_REGISTERED = "project-action-processor-already-registered", e.ACTION_PROCESSOR_INCORRECT = "project-action-processor-incorrect", e.TASK_PROCESSOR_NOT_FOUND = "project-task-processor-not-found", e.TASK_PROCESSOR_ALREADY_REGISTERED = "project-task-processor-already-registered", e.TASK_PROCESSOR_INCORRECT = "project-task-processor-incorrect", e.TRIGGER_PROCESSOR_ALREADY_REGISTERED = "project-trigger-processor-already-registered", e.TRIGGER_PROCESSOR_INCORRECT = "project-trigger-processor-incorrect", e))(ht || {});
329
- class jt extends O {
335
+ var gt = ((e) => (e.STATE_CHANGE = "state-change", e.START_TASK = "start-task", e.RESTART_TASK = "restart-task", e.STOP_TASK = "stop-task", e.PROCESS_ACTION = "process-action", e.ENABLE_TRIGGER = "enable-trigger", e.DISABLE_TRIGGER = "disable-trigger", e.TASK_STATE_CHANGE = "task-state-change", e.TASK_STDOUT = "task-stdout", e.TASK_STDERR = "task-stderr", e))(gt || {}), ht = ((e) => (e.IDLE = "idle", e.STARTING = "starting", e.STARTED = "started", e.STOPPING = "stopping", e.STOPPED = "stopped", e))(ht || {}), lt = ((e) => (e.ACTION_PROCESSOR_ALREADY_REGISTERED = "project-action-processor-already-registered", e.ACTION_PROCESSOR_INCORRECT = "project-action-processor-incorrect", e.TASK_PROCESSOR_NOT_FOUND = "project-task-processor-not-found", e.TASK_PROCESSOR_ALREADY_REGISTERED = "project-task-processor-already-registered", e.TASK_PROCESSOR_INCORRECT = "project-task-processor-incorrect", e.TRIGGER_PROCESSOR_ALREADY_REGISTERED = "project-trigger-processor-already-registered", e.TRIGGER_PROCESSOR_INCORRECT = "project-trigger-processor-incorrect", e))(lt || {});
336
+ class wt extends v {
330
337
  constructor(t) {
331
338
  super(), this.config = t;
332
339
  }
333
- schema = nt();
334
- taskProcessors = /* @__PURE__ */ new Map([[f.DEFAULT, et]]);
340
+ schema = at();
341
+ taskProcessors = /* @__PURE__ */ new Map([[T.DEFAULT, st]]);
335
342
  actionProcessors = /* @__PURE__ */ new Map();
336
343
  triggerProcessors = /* @__PURE__ */ new Map();
337
344
  tasks = /* @__PURE__ */ new Map();
338
345
  triggers = /* @__PURE__ */ new Map();
339
346
  state = { timestamp: Date.now(), status: "idle" };
340
347
  validate() {
341
- tt(this.config, this.schema);
348
+ et(this.config, this.schema);
342
349
  }
343
350
  getConfig() {
344
351
  return { ...this.config };
@@ -354,8 +361,8 @@ class jt extends O {
354
361
  this.validate(), this.initTasks(), this.initTriggers(), this.updateState({ status: "starting" });
355
362
  const t = this.getTasksStartOrder();
356
363
  for (const s of t) if (this.tasks.has(s)) {
357
- const { instance: r, config: i } = this.tasks.get(s), { mode: o = R.IMMEDIATE, dependencies: a = [] } = i;
358
- o === R.IMMEDIATE && a.length === 0 && r.start();
364
+ const { instance: r, config: i } = this.tasks.get(s), { mode: o = f.IMMEDIATE, dependencies: a = [] } = i;
365
+ o === f.IMMEDIATE && a.length === 0 && r.start();
359
366
  }
360
367
  this.updateState({ status: "started" });
361
368
  }
@@ -370,7 +377,7 @@ class jt extends O {
370
377
  await Promise.allSettled(r), this.updateState({ status: "stopped" });
371
378
  }
372
379
  extendValidationSchema(t) {
373
- this.schema = at(this.schema, t);
380
+ this.schema = ct(this.schema, t);
374
381
  }
375
382
  registerAction(t, s) {
376
383
  if (this.actionProcessors.has(t)) throw new p(`Action processor for type "${t}" already registered`, "project-action-processor-already-registered", { type: t });
@@ -379,12 +386,12 @@ class jt extends O {
379
386
  }
380
387
  registerTask(t, s) {
381
388
  if (this.taskProcessors.has(t)) throw new p(`Task processor for type "${t}" already registered`, "project-task-processor-already-registered", { type: t });
382
- if (!(s.prototype instanceof C)) throw new p(`Task processor for type "${t}" must be a subclass of "RuniumTask"`, "project-task-processor-incorrect", { type: t });
389
+ if (!(s.prototype instanceof D)) throw new p(`Task processor for type "${t}" must be a subclass of "RuniumTask"`, "project-task-processor-incorrect", { type: t });
383
390
  this.taskProcessors.set(t, s);
384
391
  }
385
392
  registerTrigger(t, s) {
386
393
  if (this.triggerProcessors.has(t)) throw new p(`Trigger processor for type "${t}" already registered`, "project-trigger-processor-already-registered", { type: t });
387
- if (!(s.prototype instanceof E)) throw new p(`Trigger processor for type "${t}" must be a subclass of "RuniumTrigger"`, "project-trigger-processor-incorrect", { type: t });
394
+ if (!(s.prototype instanceof k)) throw new p(`Trigger processor for type "${t}" must be a subclass of "RuniumTrigger"`, "project-trigger-processor-incorrect", { type: t });
388
395
  this.triggerProcessors.set(t, s);
389
396
  }
390
397
  updateState(t) {
@@ -393,14 +400,14 @@ class jt extends O {
393
400
  initTasks() {
394
401
  this.tasks.clear();
395
402
  for (const t of this.config.tasks) {
396
- const s = t.type || f.DEFAULT, r = this.taskProcessors.get(s);
403
+ const s = t.type || T.DEFAULT, r = this.taskProcessors.get(s);
397
404
  if (!r) throw new p(`Task processor for type "${s}" not found`, "project-task-processor-not-found", { type: s });
398
405
  const i = new r(t.options);
399
- i.on(S.STATE_CHANGE, (o) => {
406
+ i.on(E.STATE_CHANGE, (o) => {
400
407
  this.emit("task-state-change", t.id, o), this.onTaskStateChange(t.id, o);
401
- }), i.on(S.STDOUT, (o) => {
408
+ }), i.on(E.STDOUT, (o) => {
402
409
  this.emit("task-stdout", t.id, o);
403
- }), i.on(S.STDERR, (o) => {
410
+ }), i.on(E.STDERR, (o) => {
404
411
  this.emit("task-stderr", t.id, o);
405
412
  }), this.tasks.set(t.id, { instance: i, config: t, dependencies: [...t.dependencies || []], dependents: null });
406
413
  }
@@ -423,7 +430,7 @@ class jt extends O {
423
430
  const { restart: a } = r;
424
431
  if (a && s.exitCode !== -1) {
425
432
  const { policy: c } = a;
426
- if (c === T.ALWAYS || c === T.ON_FAILURE && s.exitCode !== 0) {
433
+ if (c === m.ALWAYS || c === m.ON_FAILURE && s.exitCode !== 0) {
427
434
  const { maxRetries: n = 1 / 0, delay: u = 0 } = a;
428
435
  s.iteration <= n && setTimeout(i.restart.bind(i), u);
429
436
  }
@@ -434,7 +441,7 @@ class jt extends O {
434
441
  });
435
442
  }
436
443
  checkTaskStateCondition(t, s) {
437
- return typeof t == "string" ? M.evaluate(t, s) === !0 : typeof t == "object" ? Object.entries(t).every(([r, i]) => s[r] === i) : typeof t == "boolean" && t;
444
+ return typeof t == "string" ? q.evaluate(t, s) === !0 : typeof t == "object" ? Object.entries(t).every(([r, i]) => s[r] === i) : typeof t == "boolean" && t;
438
445
  }
439
446
  async startTask(t) {
440
447
  if (this.tasks.has(t)) {
@@ -456,10 +463,11 @@ class jt extends O {
456
463
  }
457
464
  isDependentTaskReady(t) {
458
465
  if (this.tasks.has(t)) {
459
- const { dependencies: s = [] } = this.tasks.get(t);
460
- for (const { taskId: r, condition: i } of s) {
461
- const { instance: o } = this.tasks.get(r);
462
- if (!this.checkTaskStateCondition(i, o.getState())) return !1;
466
+ const { dependencies: s = [], config: r } = this.tasks.get(t);
467
+ if (r.mode === f.IGNORE) return !1;
468
+ for (const { taskId: i, condition: o } of s) {
469
+ const { instance: a } = this.tasks.get(i);
470
+ if (!this.checkTaskStateCondition(o, a.getState())) return !1;
463
471
  }
464
472
  return !0;
465
473
  }
@@ -478,7 +486,7 @@ class jt extends O {
478
486
  return s;
479
487
  }
480
488
  processAction(t) {
481
- if (this.emit("process-action", t), z(t)) {
489
+ if (this.emit("process-action", t), Z(t)) {
482
490
  const s = this.actionProcessors.get(t.type);
483
491
  s && s(t.payload || {});
484
492
  } else switch (t.type) {
@@ -512,13 +520,13 @@ class jt extends O {
512
520
  i && (s = new i(r, t));
513
521
  } else switch (r.type) {
514
522
  case l.EVENT:
515
- s = new ct(r, t);
523
+ s = new pt(r, t);
516
524
  break;
517
525
  case l.INTERVAL:
518
- s = new pt(r, t);
526
+ s = new dt(r, t);
519
527
  break;
520
528
  case l.TIMEOUT:
521
- s = new dt(r, t);
529
+ s = new ut(r, t);
522
530
  }
523
531
  s && (this.triggers.set(r.id, s), r.disabled !== !0 && s.enable());
524
532
  }
@@ -540,38 +548,39 @@ class jt extends O {
540
548
  }
541
549
  }
542
550
  export {
543
- ct as EventTrigger,
544
- F as FileErrorCode,
545
- pt as IntervalTrigger,
546
- V as MacrosErrorCode,
547
- jt as Project,
551
+ pt as EventTrigger,
552
+ Y as FileErrorCode,
553
+ $ as ID_REGEX,
554
+ dt as IntervalTrigger,
555
+ J as MacrosErrorCode,
556
+ wt as Project,
548
557
  d as ProjectActionType,
549
- J as ProjectConfigErrorCode,
550
- ht as ProjectErrorCode,
551
- ut as ProjectEvent,
552
- st as ProjectSchemaErrorCode,
553
- gt as ProjectStatus,
554
- T as ProjectTaskRestartPolicyType,
555
- R as ProjectTaskStartMode,
556
- f as ProjectTaskType,
558
+ B as ProjectConfigErrorCode,
559
+ lt as ProjectErrorCode,
560
+ gt as ProjectEvent,
561
+ rt as ProjectSchemaErrorCode,
562
+ ht as ProjectStatus,
563
+ m as ProjectTaskRestartPolicyType,
564
+ f as ProjectTaskStartMode,
565
+ T as ProjectTaskType,
557
566
  l as ProjectTriggerType,
558
567
  p as RuniumError,
559
- C as RuniumTask,
560
- E as RuniumTrigger,
561
- $t as SILENT_EXIT_CODE,
562
- et as Task,
563
- S as TaskEvent,
568
+ D as RuniumTask,
569
+ k as RuniumTrigger,
570
+ jt as SILENT_EXIT_CODE,
571
+ st as Task,
572
+ E as TaskEvent,
564
573
  h as TaskStatus,
565
- dt as TimeoutTrigger,
566
- It as applyMacros,
567
- at as extendProjectSchema,
568
- nt as getProjectSchema,
569
- z as isCustomAction,
574
+ ut as TimeoutTrigger,
575
+ $t as applyMacros,
576
+ ct as extendProjectSchema,
577
+ at as getProjectSchema,
578
+ Z as isCustomAction,
570
579
  Q as isCustomTrigger,
571
- P as isProcessTaskAction,
572
- Et as isRuniumError,
573
- b as isToggleTriggerAction,
574
- At as readJsonFile,
575
- tt as validateProject,
576
- _t as writeJsonFile
580
+ b as isProcessTaskAction,
581
+ At as isRuniumError,
582
+ O as isToggleTriggerAction,
583
+ _t as readJsonFile,
584
+ et as validateProject,
585
+ It as writeJsonFile
577
586
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runium/core",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Runium Core",
5
5
  "author": "TheBeastApp",
6
6
  "license": "MIT",