workplane 0.2.0 → 0.3.1
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/README.md +127 -34
- package/dist/cli.js +430 -1
- package/dist/cli.js.map +1 -1
- package/dist/node.js.map +1 -1
- package/dist/server.js +174 -92
- package/dist/server.js.map +1 -1
- package/package.json +5 -6
package/dist/server.js
CHANGED
|
@@ -1,9 +1,126 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __esm = (fn, res) => function __init() {
|
|
5
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
+
};
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// ../dbos/src/index.ts
|
|
13
|
+
var src_exports = {};
|
|
14
|
+
__export(src_exports, {
|
|
15
|
+
DbosWorkflows: () => DbosWorkflows,
|
|
16
|
+
createDbosWorkflows: () => createDbosWorkflows
|
|
17
|
+
});
|
|
18
|
+
import { DBOS } from "@dbos-inc/dbos-sdk";
|
|
19
|
+
function createDbosWorkflows(store) {
|
|
20
|
+
return new DbosWorkflows(store);
|
|
21
|
+
}
|
|
22
|
+
var DbosWorkflows;
|
|
23
|
+
var init_src = __esm({
|
|
24
|
+
"../dbos/src/index.ts"() {
|
|
25
|
+
"use strict";
|
|
26
|
+
DbosWorkflows = class {
|
|
27
|
+
registered;
|
|
28
|
+
constructor(store) {
|
|
29
|
+
const createTask = DBOS.registerWorkflow(
|
|
30
|
+
async (input) => DBOS.runStep(() => store.createTask(input), { name: "store-create-task" }),
|
|
31
|
+
{ name: "createTaskWorkflow" }
|
|
32
|
+
);
|
|
33
|
+
const retryTask = DBOS.registerWorkflow(
|
|
34
|
+
async (taskId) => DBOS.runStep(() => store.retryTask(taskId), { name: "store-retry-task" }),
|
|
35
|
+
{ name: "retryTaskWorkflow" }
|
|
36
|
+
);
|
|
37
|
+
const cancelTask = DBOS.registerWorkflow(
|
|
38
|
+
async (taskId) => DBOS.runStep(() => store.cancelTask(taskId), { name: "store-cancel-task" }),
|
|
39
|
+
{ name: "cancelTaskWorkflow" }
|
|
40
|
+
);
|
|
41
|
+
const updateRunStatus = DBOS.registerWorkflow(
|
|
42
|
+
async (runId, status, error) => DBOS.runStep(() => store.updateRunStatus(runId, status, error), { name: "store-update-run-status" }),
|
|
43
|
+
{ name: "updateRunStatusWorkflow" }
|
|
44
|
+
);
|
|
45
|
+
const appendRunLogs = DBOS.registerWorkflow(
|
|
46
|
+
async (runId, logs) => DBOS.runStep(() => store.appendRunLogs(runId, logs), { name: "store-append-run-logs" }),
|
|
47
|
+
{ name: "appendRunLogsWorkflow" }
|
|
48
|
+
);
|
|
49
|
+
const createArtifact = DBOS.registerWorkflow(
|
|
50
|
+
async (runId, input) => DBOS.runStep(() => store.createArtifact(runId, input), { name: "store-create-artifact" }),
|
|
51
|
+
{ name: "createArtifactWorkflow" }
|
|
52
|
+
);
|
|
53
|
+
const appendInputEvent = DBOS.registerWorkflow(
|
|
54
|
+
async (runId, input) => DBOS.runStep(() => store.appendInputEvent(runId, input), { name: "store-append-input-event" }),
|
|
55
|
+
{ name: "appendInputEventWorkflow" }
|
|
56
|
+
);
|
|
57
|
+
const markInputDelivered = DBOS.registerWorkflow(
|
|
58
|
+
async (runId, sequence) => DBOS.runStep(() => store.markInputDelivered(runId, sequence), { name: "store-mark-input-delivered" }),
|
|
59
|
+
{ name: "markInputDeliveredWorkflow" }
|
|
60
|
+
);
|
|
61
|
+
this.registered = {
|
|
62
|
+
createTask,
|
|
63
|
+
retryTask,
|
|
64
|
+
cancelTask,
|
|
65
|
+
updateRunStatus,
|
|
66
|
+
appendRunLogs,
|
|
67
|
+
createArtifact,
|
|
68
|
+
appendInputEvent,
|
|
69
|
+
markInputDelivered
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
async launch(options) {
|
|
73
|
+
DBOS.setConfig({
|
|
74
|
+
name: options.appName,
|
|
75
|
+
systemDatabaseUrl: options.systemDatabaseUrl
|
|
76
|
+
});
|
|
77
|
+
await DBOS.launch({
|
|
78
|
+
conductorKey: options.conductorKey,
|
|
79
|
+
conductorURL: options.conductorUrl
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async shutdown() {
|
|
83
|
+
await DBOS.shutdown();
|
|
84
|
+
}
|
|
85
|
+
async createTask(input) {
|
|
86
|
+
const handle = await DBOS.startWorkflow(this.registered.createTask)(input);
|
|
87
|
+
return handle.getResult();
|
|
88
|
+
}
|
|
89
|
+
async retryTask(taskId) {
|
|
90
|
+
const handle = await DBOS.startWorkflow(this.registered.retryTask)(taskId);
|
|
91
|
+
return handle.getResult();
|
|
92
|
+
}
|
|
93
|
+
async cancelTask(taskId) {
|
|
94
|
+
const handle = await DBOS.startWorkflow(this.registered.cancelTask)(taskId);
|
|
95
|
+
return handle.getResult();
|
|
96
|
+
}
|
|
97
|
+
async updateRunStatus(runId, status, error) {
|
|
98
|
+
const handle = await DBOS.startWorkflow(this.registered.updateRunStatus)(runId, status, error);
|
|
99
|
+
return handle.getResult();
|
|
100
|
+
}
|
|
101
|
+
async appendRunLogs(runId, logs) {
|
|
102
|
+
const handle = await DBOS.startWorkflow(this.registered.appendRunLogs)(runId, logs);
|
|
103
|
+
return handle.getResult();
|
|
104
|
+
}
|
|
105
|
+
async createArtifact(runId, input) {
|
|
106
|
+
const handle = await DBOS.startWorkflow(this.registered.createArtifact)(runId, input);
|
|
107
|
+
return handle.getResult();
|
|
108
|
+
}
|
|
109
|
+
async appendInputEvent(runId, input) {
|
|
110
|
+
const handle = await DBOS.startWorkflow(this.registered.appendInputEvent)(runId, input);
|
|
111
|
+
return handle.getResult();
|
|
112
|
+
}
|
|
113
|
+
async markInputDelivered(runId, sequence) {
|
|
114
|
+
const handle = await DBOS.startWorkflow(this.registered.markInputDelivered)(runId, sequence);
|
|
115
|
+
await handle.getResult();
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
});
|
|
2
120
|
|
|
3
121
|
// ../server/src/index.ts
|
|
4
122
|
import { createServer } from "http";
|
|
5
123
|
import { URL } from "url";
|
|
6
|
-
import { DBOS as DBOS2 } from "@dbos-inc/dbos-sdk";
|
|
7
124
|
import { ZodError } from "zod";
|
|
8
125
|
|
|
9
126
|
// ../core/src/config.ts
|
|
@@ -476,68 +593,37 @@ var PgStore = class {
|
|
|
476
593
|
}
|
|
477
594
|
};
|
|
478
595
|
|
|
479
|
-
// ../server/src/workflows.ts
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
{ name: "appendRunLogsWorkflow" }
|
|
511
|
-
);
|
|
512
|
-
const createArtifact = DBOS.registerWorkflow(
|
|
513
|
-
async (runId, input) => DBOS.runStep(() => store.createArtifact(runId, input), {
|
|
514
|
-
name: "store-create-artifact"
|
|
515
|
-
}),
|
|
516
|
-
{ name: "createArtifactWorkflow" }
|
|
517
|
-
);
|
|
518
|
-
const appendInputEvent = DBOS.registerWorkflow(
|
|
519
|
-
async (runId, input) => DBOS.runStep(() => store.appendInputEvent(runId, input), {
|
|
520
|
-
name: "store-append-input-event"
|
|
521
|
-
}),
|
|
522
|
-
{ name: "appendInputEventWorkflow" }
|
|
523
|
-
);
|
|
524
|
-
const markInputDelivered = DBOS.registerWorkflow(
|
|
525
|
-
async (runId, sequence) => DBOS.runStep(() => store.markInputDelivered(runId, sequence), {
|
|
526
|
-
name: "store-mark-input-delivered"
|
|
527
|
-
}),
|
|
528
|
-
{ name: "markInputDeliveredWorkflow" }
|
|
529
|
-
);
|
|
530
|
-
return {
|
|
531
|
-
createTask,
|
|
532
|
-
retryTask,
|
|
533
|
-
cancelTask,
|
|
534
|
-
updateRunStatus,
|
|
535
|
-
appendRunLogs,
|
|
536
|
-
createArtifact,
|
|
537
|
-
appendInputEvent,
|
|
538
|
-
markInputDelivered
|
|
539
|
-
};
|
|
540
|
-
}
|
|
596
|
+
// ../server/src/workflows-vanilla.ts
|
|
597
|
+
var VanillaWorkflows = class {
|
|
598
|
+
constructor(store) {
|
|
599
|
+
this.store = store;
|
|
600
|
+
}
|
|
601
|
+
store;
|
|
602
|
+
createTask(input) {
|
|
603
|
+
return this.store.createTask(input);
|
|
604
|
+
}
|
|
605
|
+
retryTask(taskId) {
|
|
606
|
+
return this.store.retryTask(taskId);
|
|
607
|
+
}
|
|
608
|
+
cancelTask(taskId) {
|
|
609
|
+
return this.store.cancelTask(taskId);
|
|
610
|
+
}
|
|
611
|
+
updateRunStatus(runId, status, error) {
|
|
612
|
+
return this.store.updateRunStatus(runId, status, error);
|
|
613
|
+
}
|
|
614
|
+
appendRunLogs(runId, logs) {
|
|
615
|
+
return this.store.appendRunLogs(runId, logs);
|
|
616
|
+
}
|
|
617
|
+
createArtifact(runId, input) {
|
|
618
|
+
return this.store.createArtifact(runId, input);
|
|
619
|
+
}
|
|
620
|
+
appendInputEvent(runId, input) {
|
|
621
|
+
return this.store.appendInputEvent(runId, input);
|
|
622
|
+
}
|
|
623
|
+
markInputDelivered(runId, sequence) {
|
|
624
|
+
return this.store.markInputDelivered(runId, sequence);
|
|
625
|
+
}
|
|
626
|
+
};
|
|
541
627
|
|
|
542
628
|
// ../server/src/validation.ts
|
|
543
629
|
import { z as z2 } from "zod";
|
|
@@ -753,22 +839,26 @@ function writeJson(res, statusCode, payload) {
|
|
|
753
839
|
res.setHeader("content-type", "application/json");
|
|
754
840
|
res.end(json);
|
|
755
841
|
}
|
|
842
|
+
async function buildWorkflows(store, config) {
|
|
843
|
+
if (process.env.WORKPLANE_USE_DBOS === "true") {
|
|
844
|
+
const { createDbosWorkflows: createDbosWorkflows2 } = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
845
|
+
const dbos = createDbosWorkflows2(store);
|
|
846
|
+
await dbos.launch({
|
|
847
|
+
appName: process.env.DBOS_APPLICATION_NAME ?? "workplane-server",
|
|
848
|
+
systemDatabaseUrl: config.databaseUrl,
|
|
849
|
+
conductorKey: process.env.DBOS_CONDUCTOR_KEY,
|
|
850
|
+
conductorUrl: process.env.DBOS_CONDUCTOR_URL
|
|
851
|
+
});
|
|
852
|
+
return { workflows: dbos, shutdown: () => dbos.shutdown() };
|
|
853
|
+
}
|
|
854
|
+
return { workflows: new VanillaWorkflows(store), shutdown: async () => {
|
|
855
|
+
} };
|
|
856
|
+
}
|
|
756
857
|
async function main() {
|
|
757
858
|
const config = loadServerConfig();
|
|
758
859
|
const pool = getPool(config.databaseUrl);
|
|
759
860
|
const store = new PgStore(pool);
|
|
760
|
-
const workflows =
|
|
761
|
-
const appName = process.env.DBOS_APPLICATION_NAME ?? "workplane-server";
|
|
762
|
-
const conductorKey = process.env.DBOS_CONDUCTOR_KEY;
|
|
763
|
-
const conductorUrl = process.env.DBOS_CONDUCTOR_URL;
|
|
764
|
-
DBOS2.setConfig({
|
|
765
|
-
name: appName,
|
|
766
|
-
systemDatabaseUrl: config.databaseUrl
|
|
767
|
-
});
|
|
768
|
-
await DBOS2.launch({
|
|
769
|
-
conductorKey,
|
|
770
|
-
conductorURL: conductorUrl
|
|
771
|
-
});
|
|
861
|
+
const { workflows, shutdown: shutdownWorkflows } = await buildWorkflows(store, config);
|
|
772
862
|
const server = createServer(async (req, res) => {
|
|
773
863
|
try {
|
|
774
864
|
if (!req.url || !req.method) {
|
|
@@ -788,13 +878,12 @@ async function main() {
|
|
|
788
878
|
if (req.method === "POST" && url.pathname === "/tasks") {
|
|
789
879
|
const body = await readJson(req);
|
|
790
880
|
const validated = validateCreateTaskInput(body);
|
|
791
|
-
const
|
|
881
|
+
const task = await workflows.createTask({
|
|
792
882
|
kind: validated.kind,
|
|
793
883
|
adapter: validated.adapter,
|
|
794
884
|
payload: validated.payload,
|
|
795
885
|
requires: validated.requires ?? []
|
|
796
886
|
});
|
|
797
|
-
const task = await handle.getResult();
|
|
798
887
|
writeJson(res, 201, task);
|
|
799
888
|
return;
|
|
800
889
|
}
|
|
@@ -816,8 +905,7 @@ async function main() {
|
|
|
816
905
|
}
|
|
817
906
|
if (req.method === "POST" && /^\/tasks\/[^/]+\/retry$/.test(url.pathname)) {
|
|
818
907
|
const taskId = url.pathname.split("/")[2];
|
|
819
|
-
const
|
|
820
|
-
const task = await handle.getResult();
|
|
908
|
+
const task = await workflows.retryTask(taskId);
|
|
821
909
|
if (!task) {
|
|
822
910
|
writeJson(res, 409, { error: "task is not retryable" });
|
|
823
911
|
return;
|
|
@@ -827,8 +915,7 @@ async function main() {
|
|
|
827
915
|
}
|
|
828
916
|
if (req.method === "POST" && /^\/tasks\/[^/]+\/cancel$/.test(url.pathname)) {
|
|
829
917
|
const taskId = url.pathname.split("/")[2];
|
|
830
|
-
const
|
|
831
|
-
const task = await handle.getResult();
|
|
918
|
+
const task = await workflows.cancelTask(taskId);
|
|
832
919
|
if (!task) {
|
|
833
920
|
writeJson(res, 409, { error: "task is not cancellable" });
|
|
834
921
|
return;
|
|
@@ -881,8 +968,7 @@ async function main() {
|
|
|
881
968
|
if (req.method === "POST" && /^\/runs\/[^/]+\/status$/.test(url.pathname)) {
|
|
882
969
|
const runId = url.pathname.split("/")[2];
|
|
883
970
|
const body = await readJson(req);
|
|
884
|
-
const
|
|
885
|
-
const run = await handle.getResult();
|
|
971
|
+
const run = await workflows.updateRunStatus(runId, body.status, body.error);
|
|
886
972
|
if (!run) {
|
|
887
973
|
writeJson(res, 404, { error: "run not found" });
|
|
888
974
|
return;
|
|
@@ -893,16 +979,14 @@ async function main() {
|
|
|
893
979
|
if (req.method === "POST" && /^\/runs\/[^/]+\/logs$/.test(url.pathname)) {
|
|
894
980
|
const runId = url.pathname.split("/")[2];
|
|
895
981
|
const body = await readJson(req);
|
|
896
|
-
const
|
|
897
|
-
const inserted = await handle.getResult();
|
|
982
|
+
const inserted = await workflows.appendRunLogs(runId, body.logs ?? []);
|
|
898
983
|
writeJson(res, 200, { inserted });
|
|
899
984
|
return;
|
|
900
985
|
}
|
|
901
986
|
if (req.method === "POST" && /^\/runs\/[^/]+\/artifacts$/.test(url.pathname)) {
|
|
902
987
|
const runId = url.pathname.split("/")[2];
|
|
903
988
|
const body = await readJson(req);
|
|
904
|
-
const
|
|
905
|
-
const artifact = await handle.getResult();
|
|
989
|
+
const artifact = await workflows.createArtifact(runId, body);
|
|
906
990
|
writeJson(res, 201, artifact);
|
|
907
991
|
return;
|
|
908
992
|
}
|
|
@@ -919,8 +1003,7 @@ async function main() {
|
|
|
919
1003
|
}
|
|
920
1004
|
const body = await readJson(req);
|
|
921
1005
|
const validated = validateInputEvent(body);
|
|
922
|
-
const
|
|
923
|
-
const event = await handle.getResult();
|
|
1006
|
+
const event = await workflows.appendInputEvent(runId, validated);
|
|
924
1007
|
writeJson(res, 201, event);
|
|
925
1008
|
return;
|
|
926
1009
|
}
|
|
@@ -935,8 +1018,7 @@ async function main() {
|
|
|
935
1018
|
const parts = url.pathname.split("/");
|
|
936
1019
|
const runId = parts[2];
|
|
937
1020
|
const sequence = Number(parts[4]);
|
|
938
|
-
|
|
939
|
-
await handle.getResult();
|
|
1021
|
+
await workflows.markInputDelivered(runId, sequence);
|
|
940
1022
|
writeJson(res, 200, { ok: true });
|
|
941
1023
|
return;
|
|
942
1024
|
}
|
|
@@ -959,7 +1041,7 @@ async function main() {
|
|
|
959
1041
|
`);
|
|
960
1042
|
});
|
|
961
1043
|
const shutdown = async () => {
|
|
962
|
-
await
|
|
1044
|
+
await shutdownWorkflows();
|
|
963
1045
|
await pool.end();
|
|
964
1046
|
server.close();
|
|
965
1047
|
process.exit(0);
|