@meetploy/emulator 1.7.0 → 1.9.0
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/bundler/bundler.js +49 -0
- package/dist/bundler/bundler.js.map +1 -1
- package/dist/dashboard-dist/assets/{main-qA3kxECS.css → main-B-euJxpr.css} +1 -1
- package/dist/dashboard-dist/assets/main-duAiLjPq.js +339 -0
- package/dist/dashboard-dist/index.html +2 -2
- package/dist/emulator.d.ts +1 -0
- package/dist/emulator.js +20 -0
- package/dist/emulator.js.map +1 -1
- package/dist/runtime/alarm-runtime.d.ts +1 -0
- package/dist/runtime/alarm-runtime.js +55 -0
- package/dist/runtime/alarm-runtime.js.map +1 -0
- package/dist/runtime/fs-runtime.d.ts +1 -0
- package/dist/runtime/fs-runtime.js +112 -0
- package/dist/runtime/fs-runtime.js.map +1 -0
- package/dist/services/alarm-service.d.ts +41 -0
- package/dist/services/alarm-service.js +125 -0
- package/dist/services/alarm-service.js.map +1 -0
- package/dist/services/cron-service.d.ts +6 -0
- package/dist/services/cron-service.js +176 -0
- package/dist/services/cron-service.js.map +1 -0
- package/dist/services/dashboard-routes.js +73 -0
- package/dist/services/dashboard-routes.js.map +1 -1
- package/dist/services/fs-service.d.ts +41 -0
- package/dist/services/fs-service.js +130 -0
- package/dist/services/fs-service.js.map +1 -0
- package/dist/services/mock-server.js +10 -0
- package/dist/services/mock-server.js.map +1 -1
- package/dist/services/workflow-service.spec.d.ts +1 -0
- package/dist/services/workflow-service.spec.js +258 -0
- package/dist/services/workflow-service.spec.js.map +1 -0
- package/dist/utils/sqlite.js +26 -0
- package/dist/utils/sqlite.js.map +1 -1
- package/package.json +1 -1
- package/dist/dashboard-dist/assets/main-UY1Z1kG0.js +0 -334
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import Database from "better-sqlite3";
|
|
3
|
+
import { Hono } from "hono";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
5
|
+
import { createWorkflowHandlers, startStalledWorkflowRecovery, } from "./workflow-service.js";
|
|
6
|
+
const SCHEMA = `
|
|
7
|
+
CREATE TABLE IF NOT EXISTS workflow_executions (
|
|
8
|
+
id TEXT PRIMARY KEY,
|
|
9
|
+
workflow_name TEXT NOT NULL,
|
|
10
|
+
status TEXT DEFAULT 'pending',
|
|
11
|
+
input TEXT,
|
|
12
|
+
output TEXT,
|
|
13
|
+
error TEXT,
|
|
14
|
+
started_at INTEGER,
|
|
15
|
+
completed_at INTEGER,
|
|
16
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now'))
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
CREATE TABLE IF NOT EXISTS workflow_steps (
|
|
20
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
21
|
+
execution_id TEXT NOT NULL,
|
|
22
|
+
step_name TEXT NOT NULL,
|
|
23
|
+
step_index INTEGER NOT NULL,
|
|
24
|
+
status TEXT DEFAULT 'pending',
|
|
25
|
+
output TEXT,
|
|
26
|
+
error TEXT,
|
|
27
|
+
duration_ms INTEGER,
|
|
28
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
29
|
+
FOREIGN KEY (execution_id) REFERENCES workflow_executions(id)
|
|
30
|
+
);
|
|
31
|
+
`;
|
|
32
|
+
function createTestApp(db) {
|
|
33
|
+
const handlers = createWorkflowHandlers(db);
|
|
34
|
+
const app = new Hono();
|
|
35
|
+
app.post("/workflow/trigger", handlers.triggerHandler);
|
|
36
|
+
app.post("/workflow/status", handlers.statusHandler);
|
|
37
|
+
app.post("/workflow/step/start", handlers.stepStartHandler);
|
|
38
|
+
app.post("/workflow/step/complete", handlers.stepCompleteHandler);
|
|
39
|
+
app.post("/workflow/step/fail", handlers.stepFailHandler);
|
|
40
|
+
app.post("/workflow/complete", handlers.completeHandler);
|
|
41
|
+
app.post("/workflow/fail", handlers.failHandler);
|
|
42
|
+
return app;
|
|
43
|
+
}
|
|
44
|
+
function post(app, path, body) {
|
|
45
|
+
return app.request(path, {
|
|
46
|
+
method: "POST",
|
|
47
|
+
headers: { "Content-Type": "application/json" },
|
|
48
|
+
body: JSON.stringify(body),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
describe("workflow step idempotency and resume", () => {
|
|
52
|
+
let db;
|
|
53
|
+
let app;
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
db = new Database(":memory:");
|
|
56
|
+
db.exec(SCHEMA);
|
|
57
|
+
app = createTestApp(db);
|
|
58
|
+
});
|
|
59
|
+
afterEach(() => {
|
|
60
|
+
db.close();
|
|
61
|
+
});
|
|
62
|
+
function insertExecution(id, opts = {}) {
|
|
63
|
+
const now = Math.floor(Date.now() / 1000);
|
|
64
|
+
db.prepare(`INSERT INTO workflow_executions (id, workflow_name, status, input, started_at, created_at)
|
|
65
|
+
VALUES (?, ?, ?, ?, ?, ?)`).run(id, opts.workflowName ?? "test_workflow", opts.status ?? "running", opts.input ? JSON.stringify(opts.input) : null, opts.startedAt ?? now, now);
|
|
66
|
+
}
|
|
67
|
+
function insertStep(executionId, stepName, stepIndex, opts = {}) {
|
|
68
|
+
const now = Math.floor(Date.now() / 1000);
|
|
69
|
+
db.prepare(`INSERT INTO workflow_steps (execution_id, step_name, step_index, status, output, error, created_at)
|
|
70
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`).run(executionId, stepName, stepIndex, opts.status ?? "running", opts.output ? JSON.stringify(opts.output) : null, opts.error ?? null, now);
|
|
71
|
+
}
|
|
72
|
+
test("completed step returns cached output (idempotency)", async () => {
|
|
73
|
+
const executionId = randomUUID();
|
|
74
|
+
insertExecution(executionId);
|
|
75
|
+
insertStep(executionId, "step_1", 0, {
|
|
76
|
+
status: "completed",
|
|
77
|
+
output: { result: 42 },
|
|
78
|
+
});
|
|
79
|
+
const res = await post(app, "/workflow/step/start", {
|
|
80
|
+
executionId,
|
|
81
|
+
stepName: "step_1",
|
|
82
|
+
stepIndex: 0,
|
|
83
|
+
});
|
|
84
|
+
const body = (await res.json());
|
|
85
|
+
expect(body.success).toBe(true);
|
|
86
|
+
expect(body.alreadyCompleted).toBe(true);
|
|
87
|
+
expect(body.output).toEqual({ result: 42 });
|
|
88
|
+
});
|
|
89
|
+
test("running step is reset and returned as not completed (resume after crash)", async () => {
|
|
90
|
+
const executionId = randomUUID();
|
|
91
|
+
insertExecution(executionId);
|
|
92
|
+
insertStep(executionId, "step_2", 1, { status: "running" });
|
|
93
|
+
const res = await post(app, "/workflow/step/start", {
|
|
94
|
+
executionId,
|
|
95
|
+
stepName: "step_2",
|
|
96
|
+
stepIndex: 1,
|
|
97
|
+
});
|
|
98
|
+
const body = (await res.json());
|
|
99
|
+
expect(body.success).toBe(true);
|
|
100
|
+
expect(body.alreadyCompleted).toBe(false);
|
|
101
|
+
const step = db
|
|
102
|
+
.prepare(`SELECT status, error FROM workflow_steps WHERE execution_id = ? AND step_name = ?`)
|
|
103
|
+
.get(executionId, "step_2");
|
|
104
|
+
expect(step.status).toBe("running");
|
|
105
|
+
expect(step.error).toBeNull();
|
|
106
|
+
});
|
|
107
|
+
test("failed step is reset and returned as not completed (resume after crash)", async () => {
|
|
108
|
+
const executionId = randomUUID();
|
|
109
|
+
insertExecution(executionId);
|
|
110
|
+
insertStep(executionId, "step_3", 2, {
|
|
111
|
+
status: "failed",
|
|
112
|
+
error: "previous error",
|
|
113
|
+
});
|
|
114
|
+
const res = await post(app, "/workflow/step/start", {
|
|
115
|
+
executionId,
|
|
116
|
+
stepName: "step_3",
|
|
117
|
+
stepIndex: 2,
|
|
118
|
+
});
|
|
119
|
+
const body = (await res.json());
|
|
120
|
+
expect(body.success).toBe(true);
|
|
121
|
+
expect(body.alreadyCompleted).toBe(false);
|
|
122
|
+
const step = db
|
|
123
|
+
.prepare(`SELECT status, error FROM workflow_steps WHERE execution_id = ? AND step_name = ?`)
|
|
124
|
+
.get(executionId, "step_3");
|
|
125
|
+
expect(step.status).toBe("running");
|
|
126
|
+
expect(step.error).toBeNull();
|
|
127
|
+
});
|
|
128
|
+
test("new step is created when none exists", async () => {
|
|
129
|
+
const executionId = randomUUID();
|
|
130
|
+
insertExecution(executionId);
|
|
131
|
+
const res = await post(app, "/workflow/step/start", {
|
|
132
|
+
executionId,
|
|
133
|
+
stepName: "new_step",
|
|
134
|
+
stepIndex: 0,
|
|
135
|
+
});
|
|
136
|
+
const body = (await res.json());
|
|
137
|
+
expect(body.success).toBe(true);
|
|
138
|
+
expect(body.alreadyCompleted).toBe(false);
|
|
139
|
+
const step = db
|
|
140
|
+
.prepare(`SELECT status FROM workflow_steps WHERE execution_id = ? AND step_name = ?`)
|
|
141
|
+
.get(executionId, "new_step");
|
|
142
|
+
expect(step.status).toBe("running");
|
|
143
|
+
});
|
|
144
|
+
test("full workflow replay: completed steps skipped, pending steps re-execute", async () => {
|
|
145
|
+
const executionId = randomUUID();
|
|
146
|
+
insertExecution(executionId);
|
|
147
|
+
for (let i = 0; i < 5; i++) {
|
|
148
|
+
insertStep(executionId, `step_${i}`, i, {
|
|
149
|
+
status: "completed",
|
|
150
|
+
output: { value: i * 10 },
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
insertStep(executionId, "step_5", 5, { status: "running" });
|
|
154
|
+
for (let i = 0; i < 10; i++) {
|
|
155
|
+
const res = await post(app, "/workflow/step/start", {
|
|
156
|
+
executionId,
|
|
157
|
+
stepName: `step_${i}`,
|
|
158
|
+
stepIndex: i,
|
|
159
|
+
});
|
|
160
|
+
const body = (await res.json());
|
|
161
|
+
expect(body.success).toBe(true);
|
|
162
|
+
if (i < 5) {
|
|
163
|
+
expect(body.alreadyCompleted).toBe(true);
|
|
164
|
+
expect(body.output).toEqual({ value: i * 10 });
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
expect(body.alreadyCompleted).toBe(false);
|
|
168
|
+
}
|
|
169
|
+
if (!body.alreadyCompleted) {
|
|
170
|
+
await post(app, "/workflow/step/complete", {
|
|
171
|
+
executionId,
|
|
172
|
+
stepName: `step_${i}`,
|
|
173
|
+
output: { value: i * 10 },
|
|
174
|
+
durationMs: 50,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const steps = db
|
|
179
|
+
.prepare(`SELECT step_name, status FROM workflow_steps WHERE execution_id = ? ORDER BY step_index`)
|
|
180
|
+
.all(executionId);
|
|
181
|
+
expect(steps).toHaveLength(10);
|
|
182
|
+
for (const step of steps) {
|
|
183
|
+
expect(step.status).toBe("completed");
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
describe("stalled workflow recovery", () => {
|
|
188
|
+
let db;
|
|
189
|
+
beforeEach(() => {
|
|
190
|
+
db = new Database(":memory:");
|
|
191
|
+
db.exec(SCHEMA);
|
|
192
|
+
vi.useFakeTimers();
|
|
193
|
+
});
|
|
194
|
+
afterEach(() => {
|
|
195
|
+
vi.useRealTimers();
|
|
196
|
+
vi.unstubAllGlobals();
|
|
197
|
+
db.close();
|
|
198
|
+
});
|
|
199
|
+
test("recovers workflows that have been running longer than the stall timeout", async () => {
|
|
200
|
+
const fetchSpy = vi.fn().mockResolvedValue(new Response("ok"));
|
|
201
|
+
vi.stubGlobal("fetch", fetchSpy);
|
|
202
|
+
const executionId = randomUUID();
|
|
203
|
+
const tenMinutesAgo = Math.floor(Date.now() / 1000) - 600;
|
|
204
|
+
db.prepare(`INSERT INTO workflow_executions (id, workflow_name, status, input, started_at, created_at)
|
|
205
|
+
VALUES (?, ?, 'running', ?, ?, ?)`).run(executionId, "stalled_workflow", JSON.stringify({ data: 1 }), tenMinutesAgo, tenMinutesAgo);
|
|
206
|
+
db.prepare(`INSERT INTO workflow_steps (execution_id, step_name, step_index, status, created_at)
|
|
207
|
+
VALUES (?, ?, ?, 'running', ?)`).run(executionId, "stuck_step", 0, tenMinutesAgo);
|
|
208
|
+
const interval = startStalledWorkflowRecovery(db, "http://localhost:9999", 100);
|
|
209
|
+
await vi.advanceTimersByTimeAsync(200);
|
|
210
|
+
clearInterval(interval);
|
|
211
|
+
const step = db
|
|
212
|
+
.prepare(`SELECT status FROM workflow_steps WHERE execution_id = ? AND step_name = ?`)
|
|
213
|
+
.get(executionId, "stuck_step");
|
|
214
|
+
expect(step.status).toBe("pending");
|
|
215
|
+
const execution = db
|
|
216
|
+
.prepare(`SELECT started_at FROM workflow_executions WHERE id = ?`)
|
|
217
|
+
.get(executionId);
|
|
218
|
+
expect(execution.started_at).toBeGreaterThan(tenMinutesAgo);
|
|
219
|
+
expect(fetchSpy).toHaveBeenCalledWith("http://localhost:9999", expect.objectContaining({
|
|
220
|
+
method: "POST",
|
|
221
|
+
headers: expect.objectContaining({
|
|
222
|
+
"X-Ploy-Workflow-Execution": "true",
|
|
223
|
+
"X-Ploy-Workflow-Name": "stalled_workflow",
|
|
224
|
+
"X-Ploy-Execution-Id": executionId,
|
|
225
|
+
}),
|
|
226
|
+
}));
|
|
227
|
+
});
|
|
228
|
+
test("does not recover workflows that are still within the stall timeout", async () => {
|
|
229
|
+
const fetchSpy = vi.fn().mockResolvedValue(new Response("ok"));
|
|
230
|
+
vi.stubGlobal("fetch", fetchSpy);
|
|
231
|
+
const executionId = randomUUID();
|
|
232
|
+
const oneMinuteAgo = Math.floor(Date.now() / 1000) - 60;
|
|
233
|
+
db.prepare(`INSERT INTO workflow_executions (id, workflow_name, status, input, started_at, created_at)
|
|
234
|
+
VALUES (?, ?, 'running', ?, ?, ?)`).run(executionId, "recent_workflow", null, oneMinuteAgo, oneMinuteAgo);
|
|
235
|
+
const interval = startStalledWorkflowRecovery(db, "http://localhost:9999", 100);
|
|
236
|
+
await vi.advanceTimersByTimeAsync(200);
|
|
237
|
+
clearInterval(interval);
|
|
238
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
239
|
+
const execution = db
|
|
240
|
+
.prepare(`SELECT status FROM workflow_executions WHERE id = ?`)
|
|
241
|
+
.get(executionId);
|
|
242
|
+
expect(execution.status).toBe("running");
|
|
243
|
+
});
|
|
244
|
+
test("does not recover completed or failed workflows", async () => {
|
|
245
|
+
const fetchSpy = vi.fn().mockResolvedValue(new Response("ok"));
|
|
246
|
+
vi.stubGlobal("fetch", fetchSpy);
|
|
247
|
+
const tenMinutesAgo = Math.floor(Date.now() / 1000) - 600;
|
|
248
|
+
db.prepare(`INSERT INTO workflow_executions (id, workflow_name, status, input, started_at, created_at)
|
|
249
|
+
VALUES (?, ?, 'completed', null, ?, ?)`).run(randomUUID(), "done_workflow", tenMinutesAgo, tenMinutesAgo);
|
|
250
|
+
db.prepare(`INSERT INTO workflow_executions (id, workflow_name, status, input, started_at, created_at)
|
|
251
|
+
VALUES (?, ?, 'failed', null, ?, ?)`).run(randomUUID(), "failed_workflow", tenMinutesAgo, tenMinutesAgo);
|
|
252
|
+
const interval = startStalledWorkflowRecovery(db, "http://localhost:9999", 100);
|
|
253
|
+
await vi.advanceTimersByTimeAsync(200);
|
|
254
|
+
clearInterval(interval);
|
|
255
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
//# sourceMappingURL=workflow-service.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-service.spec.js","sourceRoot":"","sources":["../../src/services/workflow-service.spec.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/sqlite.js
CHANGED
|
@@ -110,6 +110,32 @@ CREATE TABLE IF NOT EXISTS state_entries (
|
|
|
110
110
|
value TEXT NOT NULL,
|
|
111
111
|
PRIMARY KEY (state_name, key)
|
|
112
112
|
);
|
|
113
|
+
|
|
114
|
+
-- File storage entries table (metadata for stored files)
|
|
115
|
+
CREATE TABLE IF NOT EXISTS fs_entries (
|
|
116
|
+
fs_name TEXT NOT NULL,
|
|
117
|
+
key TEXT NOT NULL,
|
|
118
|
+
content_type TEXT NOT NULL DEFAULT 'application/octet-stream',
|
|
119
|
+
size INTEGER NOT NULL DEFAULT 0,
|
|
120
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
121
|
+
PRIMARY KEY (fs_name, key)
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
-- Cron executions table
|
|
125
|
+
CREATE TABLE IF NOT EXISTS cron_executions (
|
|
126
|
+
id TEXT PRIMARY KEY,
|
|
127
|
+
cron_name TEXT NOT NULL,
|
|
128
|
+
cron_expression TEXT NOT NULL,
|
|
129
|
+
status TEXT DEFAULT 'running',
|
|
130
|
+
error TEXT,
|
|
131
|
+
duration_ms INTEGER,
|
|
132
|
+
triggered_at INTEGER NOT NULL,
|
|
133
|
+
completed_at INTEGER,
|
|
134
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now'))
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
CREATE INDEX IF NOT EXISTS idx_cron_executions_name
|
|
138
|
+
ON cron_executions(cron_name, triggered_at);
|
|
113
139
|
`;
|
|
114
140
|
export function initializeDatabases(projectDir) {
|
|
115
141
|
const dataDir = ensureDataDir(projectDir);
|
package/dist/utils/sqlite.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/utils/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,eAAe,GAAG
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../src/utils/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuIvB,CAAC;AAQF,MAAM,UAAU,mBAAmB,CAAC,UAAkB;IACrD,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,IAAI,GAAG,EAA6B,CAAC;IAEzD,MAAM,UAAU,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;IAC9D,UAAU,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACxC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAEjC,SAAS,aAAa,CAAC,WAAmB;QACzC,IAAI,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,EAAE,CAAC;YACT,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,WAAW,KAAK,CAAC,CAAC,CAAC;YAC5D,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;YAChC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,EAAE,CAAC;IACX,CAAC;IAED,SAAS,KAAK;QACb,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,KAAK,MAAM,EAAE,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,EAAE,CAAC,KAAK,EAAE,CAAC;QACZ,CAAC;QACD,WAAW,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,OAAO;QACN,UAAU;QACV,aAAa;QACb,KAAK;KACL,CAAC;AACH,CAAC"}
|