@melra/runtime-core 0.3.0-alpha.10

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 (71) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +45 -0
  3. package/dist/circuit-breaker.d.ts +35 -0
  4. package/dist/circuit-breaker.d.ts.map +1 -0
  5. package/dist/circuit-breaker.js +56 -0
  6. package/dist/circuit-breaker.js.map +1 -0
  7. package/dist/circuit-breaker.test.d.ts +2 -0
  8. package/dist/circuit-breaker.test.d.ts.map +1 -0
  9. package/dist/circuit-breaker.test.js +51 -0
  10. package/dist/circuit-breaker.test.js.map +1 -0
  11. package/dist/index.d.ts +9 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +11 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/payload-cipher.d.ts +8 -0
  16. package/dist/payload-cipher.d.ts.map +1 -0
  17. package/dist/payload-cipher.js +47 -0
  18. package/dist/payload-cipher.js.map +1 -0
  19. package/dist/payload-cipher.test.d.ts +2 -0
  20. package/dist/payload-cipher.test.d.ts.map +1 -0
  21. package/dist/payload-cipher.test.js +33 -0
  22. package/dist/payload-cipher.test.js.map +1 -0
  23. package/dist/retry-guard.d.ts +21 -0
  24. package/dist/retry-guard.d.ts.map +1 -0
  25. package/dist/retry-guard.js +56 -0
  26. package/dist/retry-guard.js.map +1 -0
  27. package/dist/retry-guard.test.d.ts +2 -0
  28. package/dist/retry-guard.test.d.ts.map +1 -0
  29. package/dist/retry-guard.test.js +45 -0
  30. package/dist/retry-guard.test.js.map +1 -0
  31. package/dist/task-controller.d.ts +60 -0
  32. package/dist/task-controller.d.ts.map +1 -0
  33. package/dist/task-controller.js +456 -0
  34. package/dist/task-controller.js.map +1 -0
  35. package/dist/task-controller.test.d.ts +2 -0
  36. package/dist/task-controller.test.d.ts.map +1 -0
  37. package/dist/task-controller.test.js +486 -0
  38. package/dist/task-controller.test.js.map +1 -0
  39. package/dist/verification-gate.d.ts +18 -0
  40. package/dist/verification-gate.d.ts.map +1 -0
  41. package/dist/verification-gate.js +29 -0
  42. package/dist/verification-gate.js.map +1 -0
  43. package/dist/verification-gate.test.d.ts +2 -0
  44. package/dist/verification-gate.test.d.ts.map +1 -0
  45. package/dist/verification-gate.test.js +42 -0
  46. package/dist/verification-gate.test.js.map +1 -0
  47. package/dist/workflow-controller.d.ts +40 -0
  48. package/dist/workflow-controller.d.ts.map +1 -0
  49. package/dist/workflow-controller.js +877 -0
  50. package/dist/workflow-controller.js.map +1 -0
  51. package/dist/workflow-controller.test.d.ts +2 -0
  52. package/dist/workflow-controller.test.d.ts.map +1 -0
  53. package/dist/workflow-controller.test.js +785 -0
  54. package/dist/workflow-controller.test.js.map +1 -0
  55. package/dist/workflow-events.d.ts +4 -0
  56. package/dist/workflow-events.d.ts.map +1 -0
  57. package/dist/workflow-events.js +121 -0
  58. package/dist/workflow-events.js.map +1 -0
  59. package/dist/workflow-events.test.d.ts +2 -0
  60. package/dist/workflow-events.test.d.ts.map +1 -0
  61. package/dist/workflow-events.test.js +113 -0
  62. package/dist/workflow-events.test.js.map +1 -0
  63. package/dist/workflow-graph.d.ts +8 -0
  64. package/dist/workflow-graph.d.ts.map +1 -0
  65. package/dist/workflow-graph.js +107 -0
  66. package/dist/workflow-graph.js.map +1 -0
  67. package/dist/workflow-graph.test.d.ts +2 -0
  68. package/dist/workflow-graph.test.d.ts.map +1 -0
  69. package/dist/workflow-graph.test.js +169 -0
  70. package/dist/workflow-graph.test.js.map +1 -0
  71. package/package.json +36 -0
@@ -0,0 +1,169 @@
1
+ // Copyright 2026 XAGI Labs Private Limited
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { describe, expect, it } from "vitest";
4
+ import { WorkflowDefinitionSchema, } from "@melra/protocol";
5
+ import { readyNodeIds, validateWorkflow } from "./workflow-graph.js";
6
+ const definitionId = "11111111-1111-4111-8111-111111111111";
7
+ function operation(id, dependsOn = []) {
8
+ return {
9
+ id,
10
+ type: "operation",
11
+ dependsOn,
12
+ request: {
13
+ goal: `Run ${id}`,
14
+ operation: { kind: "system", action: "info" },
15
+ constraints: [],
16
+ forbiddenEffects: [],
17
+ requiredEvidence: [],
18
+ budget: {
19
+ maxDurationMs: 120_000,
20
+ maxRetries: 2,
21
+ maxSteps: 10,
22
+ },
23
+ },
24
+ };
25
+ }
26
+ function definition(nodes) {
27
+ return WorkflowDefinitionSchema.parse({
28
+ schemaVersion: "1.0.0",
29
+ id: definitionId,
30
+ version: 1,
31
+ name: "Graph test",
32
+ nodes,
33
+ });
34
+ }
35
+ const invalidGraphs = [
36
+ {
37
+ nodes: [operation("same"), operation("same")],
38
+ error: "workflow_node_id_duplicate",
39
+ },
40
+ {
41
+ nodes: [operation("node", ["missing"])],
42
+ error: "workflow_dependency_missing:node:missing",
43
+ },
44
+ {
45
+ nodes: [operation("node", ["node"])],
46
+ error: "workflow_node_self_dependency:node",
47
+ },
48
+ {
49
+ nodes: [operation("a", ["b"]), operation("b", ["a"])],
50
+ error: "workflow_dependency_cycle",
51
+ },
52
+ {
53
+ nodes: [
54
+ { id: "approve", type: "approval", dependsOn: [], forNodeId: "missing" },
55
+ ],
56
+ error: "workflow_approval_target_missing:approve",
57
+ },
58
+ {
59
+ nodes: [
60
+ { id: "approve", type: "approval", dependsOn: [], forNodeId: "target" },
61
+ operation("target"),
62
+ ],
63
+ error: "workflow_approval_must_precede_target:approve",
64
+ },
65
+ {
66
+ nodes: [
67
+ {
68
+ id: "undo",
69
+ type: "compensation",
70
+ dependsOn: [],
71
+ forNodeId: "missing",
72
+ request: operation("request").request,
73
+ },
74
+ ],
75
+ error: "workflow_compensation_target_missing:undo",
76
+ },
77
+ {
78
+ nodes: [
79
+ { id: "checkpoint", type: "checkpoint", dependsOn: [] },
80
+ {
81
+ id: "undo",
82
+ type: "compensation",
83
+ dependsOn: [],
84
+ forNodeId: "checkpoint",
85
+ request: operation("request").request,
86
+ },
87
+ ],
88
+ error: "workflow_compensation_target_not_operation:undo",
89
+ },
90
+ {
91
+ nodes: [
92
+ {
93
+ id: "condition",
94
+ type: "condition",
95
+ dependsOn: [],
96
+ sourceNodeId: "missing",
97
+ predicate: { type: "result_equals", path: "ok", value: true },
98
+ whenTrue: [],
99
+ whenFalse: [],
100
+ },
101
+ ],
102
+ error: "workflow_condition_source_missing:condition",
103
+ },
104
+ {
105
+ nodes: [
106
+ { id: "checkpoint", type: "checkpoint", dependsOn: [] },
107
+ {
108
+ id: "condition",
109
+ type: "condition",
110
+ dependsOn: [],
111
+ sourceNodeId: "checkpoint",
112
+ predicate: { type: "result_equals", path: "ok", value: true },
113
+ whenTrue: [],
114
+ whenFalse: [],
115
+ },
116
+ ],
117
+ error: "workflow_condition_source_not_operation:condition",
118
+ },
119
+ ];
120
+ describe("workflow graph", () => {
121
+ it("emits deterministic lexical topological layers", () => {
122
+ const graph = validateWorkflow(definition([
123
+ operation("write-b", ["inspect"]),
124
+ { id: "checkpoint", type: "checkpoint", dependsOn: ["write-a", "write-b"] },
125
+ operation("inspect"),
126
+ operation("write-a", ["inspect"]),
127
+ ]));
128
+ expect(graph.layers).toEqual([
129
+ ["inspect"],
130
+ ["write-a", "write-b"],
131
+ ["checkpoint"],
132
+ ]);
133
+ });
134
+ it.each(invalidGraphs)("rejects invalid graphs with $error", ({ nodes, error }) => {
135
+ expect(() => validateWorkflow(definition(nodes))).toThrow(error);
136
+ });
137
+ it("rejects definitions above the node bound with a stable error", () => {
138
+ const oversized = {
139
+ schemaVersion: "1.0.0",
140
+ id: definitionId,
141
+ version: 1,
142
+ name: "Oversized",
143
+ nodes: Array.from({ length: 501 }, (_, index) => operation(`node-${index}`)),
144
+ };
145
+ expect(() => validateWorkflow(oversized)).toThrow("workflow_node_limit_exceeded");
146
+ });
147
+ it("selects ready normal nodes in lexical order", () => {
148
+ const graph = validateWorkflow(definition([
149
+ operation("source"),
150
+ operation("z-ready", ["source"]),
151
+ operation("a-ready", ["source"]),
152
+ {
153
+ id: "undo",
154
+ type: "compensation",
155
+ dependsOn: ["source"],
156
+ forNodeId: "source",
157
+ request: operation("request").request,
158
+ },
159
+ ]));
160
+ const states = {
161
+ source: { status: "verified_complete", taskIds: [] },
162
+ "z-ready": { status: "pending", taskIds: [] },
163
+ "a-ready": { status: "pending", taskIds: [] },
164
+ undo: { status: "pending", taskIds: [] },
165
+ };
166
+ expect(readyNodeIds(graph, states)).toEqual(["a-ready", "z-ready"]);
167
+ });
168
+ });
169
+ //# sourceMappingURL=workflow-graph.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-graph.test.js","sourceRoot":"","sources":["../src/workflow-graph.test.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@melra/runtime-core",
3
+ "version": "0.3.0-alpha.10",
4
+ "description": "Durable task and workflow execution, recovery, budgets, retries, and verification for MELRA.",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/XAGI-Lab/melra.git",
9
+ "directory": "packages/runtime-core"
10
+ },
11
+ "homepage": "https://github.com/XAGI-Lab/melra#readme",
12
+ "bugs": "https://github.com/XAGI-Lab/melra/issues",
13
+ "type": "module",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "dependencies": {
24
+ "@melra/policy-core": "0.3.0-alpha.10",
25
+ "@melra/protocol": "0.3.0-alpha.10",
26
+ "@melra/receipt-schema": "0.3.0-alpha.10",
27
+ "@melra/storage-sqlite": "0.3.0-alpha.10",
28
+ "@melra/verifier-core": "0.3.0-alpha.10"
29
+ },
30
+ "scripts": {
31
+ "build": "tsc -p tsconfig.json",
32
+ "clean": "rm -rf dist",
33
+ "test": "vitest run",
34
+ "typecheck": "tsc -p tsconfig.json --noEmit"
35
+ }
36
+ }