lightflow-engine 0.1.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.
@@ -0,0 +1,54 @@
1
+ import { registerWorkflow } from "../src/index.js";
2
+ export async function parityWorkflow(opts) {
3
+ "use workflow";
4
+ const { step, sleep, getWritable, FatalError, getWorkflowMetadata } = await import("../src/index.js");
5
+ const { runId } = getWorkflowMetadata();
6
+ const writable = getWritable();
7
+ const started = Date.now();
8
+ let fatalCaught = false;
9
+ await writable.write("stage:start;");
10
+ try {
11
+ await step(async () => { throw new Error("transient"); });
12
+ }
13
+ catch {
14
+ fatalCaught = true;
15
+ }
16
+ const lease = `lrun-${runId}`;
17
+ const claimed = await step(async () => {
18
+ const pg = (await import("pg")).default;
19
+ const pool = new pg.Pool({ connectionString: process.env.APP_PG_URL, max: 4 });
20
+ const r = await pool.query(`UPDATE sessions SET lifecycle_run_id=$2 WHERE id=$1 AND lifecycle_run_id IS NULL`, [opts.sessionId, lease]);
21
+ await pool.end();
22
+ return (r.rowCount ?? 0) > 0;
23
+ });
24
+ await writable.write(`stage:lease:${claimed};`);
25
+ for (let i = 0; i < opts.ticks; i += 1) {
26
+ await sleep(new Date(Date.now() + 1000));
27
+ await writable.write(`stage:tick:${i + 1};`);
28
+ }
29
+ const persisted = await step(async () => {
30
+ const pg = (await import("pg")).default;
31
+ const pool = new pg.Pool({ connectionString: process.env.APP_PG_URL, max: 4 });
32
+ await pool.query(`INSERT INTO workflow_runs (id, chat_id, session_id, user_id, status, started_at, finished_at, total_duration_ms)
33
+ VALUES ($1,$2,'selftest-session','selftest-user','completed',now(),now(),$3)
34
+ ON CONFLICT (id) DO NOTHING`, [runId, opts.chatId, Math.round(Date.now() - started)]);
35
+ await pool.end();
36
+ return true;
37
+ });
38
+ await step(async () => {
39
+ const pg = (await import("pg")).default;
40
+ const pool = new pg.Pool({ connectionString: process.env.APP_PG_URL, max: 4 });
41
+ await pool.query(`UPDATE sessions SET lifecycle_run_id=NULL WHERE id=$1`, [opts.sessionId]);
42
+ await pool.end();
43
+ });
44
+ await writable.write("stage:done;");
45
+ await writable.close();
46
+ return {
47
+ ok: true, runId, ticks: opts.ticks,
48
+ leaseValue: claimed ? lease : null,
49
+ persisted, fatalCaught,
50
+ };
51
+ }
52
+ export function registerAll() {
53
+ registerWorkflow("entry-parity", parityWorkflow);
54
+ }
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "lightflow-engine",
3
+ "version": "0.1.0",
4
+ "description": "A tiny durable workflow engine for Node.js and Postgres: steps that run at most once, timers that survive crashes, streams that replay exactly once.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": "./dist/index.js",
11
+ "./pg": "./dist/pg-store.js"
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md",
16
+ "LICENSE"
17
+ ],
18
+ "keywords": [
19
+ "workflow",
20
+ "durable-execution",
21
+ "postgres",
22
+ "background-jobs",
23
+ "queue",
24
+ "temporal"
25
+ ],
26
+ "engines": {
27
+ "node": ">=20"
28
+ },
29
+ "scripts": {
30
+ "build": "tsc -p tsconfig.json",
31
+ "test": "node --test dist/test/smoke.js",
32
+ "prepublishOnly": "npm run build"
33
+ },
34
+ "dependencies": {
35
+ "pg": "^8.13.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^22.0.0",
39
+ "@types/pg": "^8.11.0",
40
+ "typescript": "^5.6.0"
41
+ },
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/thirdbase1/lightflow.git"
45
+ },
46
+ "bugs": {
47
+ "url": "https://github.com/thirdbase1/lightflow/issues"
48
+ },
49
+ "homepage": "https://github.com/thirdbase1/lightflow#readme"
50
+ }