flowfram-runtime 1.0.2
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 +151 -0
- package/dist/ServerFlowRuntime.d.ts +303 -0
- package/dist/ServerFlowRuntime.d.ts.map +1 -0
- package/dist/ServerFlowRuntime.js +5269 -0
- package/dist/ServerFlowRuntime.js.map +1 -0
- package/dist/cli.d.ts +17 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +184 -0
- package/dist/cli.js.map +1 -0
- package/dist/logger.d.ts +17 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +53 -0
- package/dist/logger.js.map +1 -0
- package/dist/persistence.d.ts +39 -0
- package/dist/persistence.d.ts.map +1 -0
- package/dist/persistence.js +138 -0
- package/dist/persistence.js.map +1 -0
- package/dist/server.d.ts +23 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1050 -0
- package/dist/server.js.map +1 -0
- package/package.json +73 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* FlowRed Runtime CLI
|
|
5
|
+
*
|
|
6
|
+
* A distributed runtime execution engine for FlowRed/FRAM flows.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* flowfram-runtime [options]
|
|
10
|
+
*
|
|
11
|
+
* Options:
|
|
12
|
+
* --port, -p Port to listen on (default: 3001)
|
|
13
|
+
* --host Host to bind to (default: 0.0.0.0)
|
|
14
|
+
* --help Show this help message
|
|
15
|
+
* --version, -v Show version number
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
34
|
+
var ownKeys = function(o) {
|
|
35
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
+
var ar = [];
|
|
37
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
return ownKeys(o);
|
|
41
|
+
};
|
|
42
|
+
return function (mod) {
|
|
43
|
+
if (mod && mod.__esModule) return mod;
|
|
44
|
+
var result = {};
|
|
45
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
+
__setModuleDefault(result, mod);
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
const server_1 = require("./server");
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
const args = process.argv.slice(2);
|
|
55
|
+
// Get package.json for version info
|
|
56
|
+
function getPackageInfo() {
|
|
57
|
+
try {
|
|
58
|
+
const pkgPath = path.resolve(__dirname, '../package.json');
|
|
59
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
60
|
+
return { version: pkg.version, name: pkg.name };
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return { version: '1.0.0', name: 'flowfram-runtime' };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Parse command line arguments
|
|
67
|
+
function parseArgs() {
|
|
68
|
+
const config = {
|
|
69
|
+
port: parseInt(process.env.PORT || '3001', 10),
|
|
70
|
+
host: process.env.HOST || '0.0.0.0',
|
|
71
|
+
help: false,
|
|
72
|
+
version: false,
|
|
73
|
+
};
|
|
74
|
+
for (let i = 0; i < args.length; i++) {
|
|
75
|
+
const arg = args[i];
|
|
76
|
+
if (arg === '--help' || arg === '-h') {
|
|
77
|
+
config.help = true;
|
|
78
|
+
}
|
|
79
|
+
else if (arg === '--version' || arg === '-v') {
|
|
80
|
+
config.version = true;
|
|
81
|
+
}
|
|
82
|
+
else if (arg === '--port' || arg === '-p') {
|
|
83
|
+
const nextArg = args[++i];
|
|
84
|
+
if (nextArg) {
|
|
85
|
+
config.port = parseInt(nextArg, 10);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else if (arg === '--host') {
|
|
89
|
+
const nextArg = args[++i];
|
|
90
|
+
if (nextArg) {
|
|
91
|
+
config.host = nextArg;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return config;
|
|
96
|
+
}
|
|
97
|
+
function showHelp() {
|
|
98
|
+
const pkg = getPackageInfo();
|
|
99
|
+
console.log(`
|
|
100
|
+
FlowRed Runtime Service v${pkg.version}
|
|
101
|
+
|
|
102
|
+
A distributed runtime execution engine for FlowRed/FRAM flows.
|
|
103
|
+
|
|
104
|
+
USAGE:
|
|
105
|
+
flowfram-runtime [options]
|
|
106
|
+
|
|
107
|
+
OPTIONS:
|
|
108
|
+
--port, -p <port> Port to listen on (default: 3001, env: PORT)
|
|
109
|
+
--host <host> Host to bind to (default: 0.0.0.0, env: HOST)
|
|
110
|
+
--help, -h Show this help message
|
|
111
|
+
--version, -v Show version number
|
|
112
|
+
|
|
113
|
+
ENVIRONMENT VARIABLES:
|
|
114
|
+
PORT Server port (default: 3001)
|
|
115
|
+
HOST Server host (default: 0.0.0.0)
|
|
116
|
+
LOG_LEVEL Logging level: debug, info, warn, error (default: info)
|
|
117
|
+
|
|
118
|
+
EXAMPLES:
|
|
119
|
+
# Start on default port 3001
|
|
120
|
+
flowfram-runtime
|
|
121
|
+
|
|
122
|
+
# Start on custom port
|
|
123
|
+
flowfram-runtime --port 8080
|
|
124
|
+
|
|
125
|
+
# Start with environment variable
|
|
126
|
+
PORT=8080 flowfram-runtime
|
|
127
|
+
|
|
128
|
+
ENDPOINTS:
|
|
129
|
+
POST /deploy Deploy a flow
|
|
130
|
+
POST /inject Inject a message into a node
|
|
131
|
+
POST /batch-run Run multiple iterations
|
|
132
|
+
POST /stop Stop a running flow
|
|
133
|
+
GET /events SSE stream for real-time events
|
|
134
|
+
GET /health Health check endpoint
|
|
135
|
+
|
|
136
|
+
For more information, visit: https://flowfram.com/agent
|
|
137
|
+
`);
|
|
138
|
+
}
|
|
139
|
+
function showVersion() {
|
|
140
|
+
const pkg = getPackageInfo();
|
|
141
|
+
console.log(`flowfram-runtime v${pkg.version}`);
|
|
142
|
+
}
|
|
143
|
+
async function main() {
|
|
144
|
+
const config = parseArgs();
|
|
145
|
+
if (config.help) {
|
|
146
|
+
showHelp();
|
|
147
|
+
process.exit(0);
|
|
148
|
+
}
|
|
149
|
+
if (config.version) {
|
|
150
|
+
showVersion();
|
|
151
|
+
process.exit(0);
|
|
152
|
+
}
|
|
153
|
+
// Set environment variables for the server
|
|
154
|
+
process.env.PORT = String(config.port);
|
|
155
|
+
process.env.HOST = config.host;
|
|
156
|
+
try {
|
|
157
|
+
const server = await (0, server_1.createServer)({
|
|
158
|
+
port: config.port,
|
|
159
|
+
host: config.host,
|
|
160
|
+
});
|
|
161
|
+
// Handle graceful shutdown
|
|
162
|
+
const shutdown = () => {
|
|
163
|
+
console.log('\nShutting down...');
|
|
164
|
+
server.close(() => {
|
|
165
|
+
console.log('Server stopped.');
|
|
166
|
+
process.exit(0);
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
process.on('SIGINT', shutdown);
|
|
170
|
+
process.on('SIGTERM', shutdown);
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
if (error.code === 'EADDRINUSE') {
|
|
174
|
+
console.error(`Error: Port ${config.port} is already in use.`);
|
|
175
|
+
console.error(`Try using a different port: flowfram-runtime --port <port>`);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
console.error('Failed to start server:', error.message);
|
|
179
|
+
}
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
main();
|
|
184
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger utility that respects LOG_LEVEL environment variable
|
|
3
|
+
* Levels: debug < info < warn < error
|
|
4
|
+
*
|
|
5
|
+
* Default level is 'warn' for production — only warnings and errors are shown.
|
|
6
|
+
* Set LOG_LEVEL=info for operational logs (deploy/stop/startup).
|
|
7
|
+
* Set LOG_LEVEL=debug for full tracing (per-node, per-message, validation).
|
|
8
|
+
*/
|
|
9
|
+
export declare const logger: {
|
|
10
|
+
debug: (...args: unknown[]) => void;
|
|
11
|
+
info: (...args: unknown[]) => void;
|
|
12
|
+
warn: (...args: unknown[]) => void;
|
|
13
|
+
error: (...args: unknown[]) => void;
|
|
14
|
+
always: (...args: unknown[]) => void;
|
|
15
|
+
};
|
|
16
|
+
export default logger;
|
|
17
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAqBH,eAAO,MAAM,MAAM;qBACA,OAAO,EAAE;oBAMV,OAAO,EAAE;oBAMT,OAAO,EAAE;qBAMR,OAAO,EAAE;sBAOR,OAAO,EAAE;CAG5B,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Logger utility that respects LOG_LEVEL environment variable
|
|
4
|
+
* Levels: debug < info < warn < error
|
|
5
|
+
*
|
|
6
|
+
* Default level is 'warn' for production — only warnings and errors are shown.
|
|
7
|
+
* Set LOG_LEVEL=info for operational logs (deploy/stop/startup).
|
|
8
|
+
* Set LOG_LEVEL=debug for full tracing (per-node, per-message, validation).
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.logger = void 0;
|
|
12
|
+
const LOG_LEVELS = {
|
|
13
|
+
debug: 0,
|
|
14
|
+
info: 1,
|
|
15
|
+
warn: 2,
|
|
16
|
+
error: 3,
|
|
17
|
+
};
|
|
18
|
+
function getConfiguredLevel() {
|
|
19
|
+
const level = (process.env.LOG_LEVEL || "warn").toLowerCase();
|
|
20
|
+
return LOG_LEVELS[level] ?? LOG_LEVELS.warn;
|
|
21
|
+
}
|
|
22
|
+
// Read level dynamically so .env changes after import are picked up
|
|
23
|
+
function currentLevel() {
|
|
24
|
+
return getConfiguredLevel();
|
|
25
|
+
}
|
|
26
|
+
exports.logger = {
|
|
27
|
+
debug: (...args) => {
|
|
28
|
+
if (currentLevel() <= LOG_LEVELS.debug) {
|
|
29
|
+
console.log(...args);
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
info: (...args) => {
|
|
33
|
+
if (currentLevel() <= LOG_LEVELS.info) {
|
|
34
|
+
console.log(...args);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
warn: (...args) => {
|
|
38
|
+
if (currentLevel() <= LOG_LEVELS.warn) {
|
|
39
|
+
console.warn(...args);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
error: (...args) => {
|
|
43
|
+
if (currentLevel() <= LOG_LEVELS.error) {
|
|
44
|
+
console.error(...args);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
// Always log regardless of level (for startup banner, etc.)
|
|
48
|
+
always: (...args) => {
|
|
49
|
+
console.log(...args);
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
exports.default = exports.logger;
|
|
53
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAIH,MAAM,UAAU,GAA6B;IAC3C,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,SAAS,kBAAkB;IACzB,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC,WAAW,EAAc,CAAC;IAC1E,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED,oEAAoE;AACpE,SAAS,YAAY;IACnB,OAAO,kBAAkB,EAAE,CAAC;AAC9B,CAAC;AAEY,QAAA,MAAM,GAAG;IACpB,KAAK,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAC5B,IAAI,YAAY,EAAE,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,IAAI,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAC3B,IAAI,YAAY,EAAE,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,IAAI,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAC3B,IAAI,YAAY,EAAE,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,KAAK,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAC5B,IAAI,YAAY,EAAE,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACvC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,MAAM,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAC7B,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACvB,CAAC;CACF,CAAC;AAEF,kBAAe,cAAM,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime State Persistence
|
|
3
|
+
*
|
|
4
|
+
* Persists deployed flows to disk so they survive runtime restarts.
|
|
5
|
+
* Uses a simple JSON file-based storage.
|
|
6
|
+
*/
|
|
7
|
+
interface PersistedFlow {
|
|
8
|
+
flowId: string;
|
|
9
|
+
flowData: any;
|
|
10
|
+
deployedAt: number;
|
|
11
|
+
tenantId?: string;
|
|
12
|
+
}
|
|
13
|
+
interface PersistedState {
|
|
14
|
+
version: string;
|
|
15
|
+
flows: PersistedFlow[];
|
|
16
|
+
lastUpdated: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Load persisted state from disk
|
|
20
|
+
*/
|
|
21
|
+
export declare function loadPersistedState(): PersistedState | null;
|
|
22
|
+
/**
|
|
23
|
+
* Save state to disk
|
|
24
|
+
*/
|
|
25
|
+
export declare function savePersistedState(flows: Map<string, {
|
|
26
|
+
flowData: any;
|
|
27
|
+
deployedAt: number;
|
|
28
|
+
tenantId?: string;
|
|
29
|
+
}>): void;
|
|
30
|
+
/**
|
|
31
|
+
* Remove a flow from persisted state
|
|
32
|
+
*/
|
|
33
|
+
export declare function removePersistedFlow(flowId: string): void;
|
|
34
|
+
/**
|
|
35
|
+
* Clear all persisted state
|
|
36
|
+
*/
|
|
37
|
+
export declare function clearPersistedState(): void;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=persistence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;CACrB;AAYD;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,GAAG,IAAI,CAkB1D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAoBrH;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAcxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAS1C"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Runtime State Persistence
|
|
4
|
+
*
|
|
5
|
+
* Persists deployed flows to disk so they survive runtime restarts.
|
|
6
|
+
* Uses a simple JSON file-based storage.
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
42
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.loadPersistedState = loadPersistedState;
|
|
46
|
+
exports.savePersistedState = savePersistedState;
|
|
47
|
+
exports.removePersistedFlow = removePersistedFlow;
|
|
48
|
+
exports.clearPersistedState = clearPersistedState;
|
|
49
|
+
const fs = __importStar(require("fs"));
|
|
50
|
+
const path = __importStar(require("path"));
|
|
51
|
+
const logger_1 = __importDefault(require("./logger"));
|
|
52
|
+
const DATA_DIR = process.env.RUNTIME_DATA_DIR || './data';
|
|
53
|
+
const FLOWS_FILE = path.join(DATA_DIR, 'deployed-flows.json');
|
|
54
|
+
/**
|
|
55
|
+
* Ensure data directory exists
|
|
56
|
+
*/
|
|
57
|
+
function ensureDataDir() {
|
|
58
|
+
if (!fs.existsSync(DATA_DIR)) {
|
|
59
|
+
fs.mkdirSync(DATA_DIR, { recursive: true });
|
|
60
|
+
logger_1.default.info(`[Persistence] Created data directory: ${DATA_DIR}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Load persisted state from disk
|
|
65
|
+
*/
|
|
66
|
+
function loadPersistedState() {
|
|
67
|
+
try {
|
|
68
|
+
ensureDataDir();
|
|
69
|
+
if (!fs.existsSync(FLOWS_FILE)) {
|
|
70
|
+
logger_1.default.info('[Persistence] No persisted state found');
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const data = fs.readFileSync(FLOWS_FILE, 'utf-8');
|
|
74
|
+
const state = JSON.parse(data);
|
|
75
|
+
logger_1.default.info(`[Persistence] Loaded ${state.flows.length} persisted flows`);
|
|
76
|
+
return state;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
logger_1.default.error('[Persistence] Error loading state:', error);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Save state to disk
|
|
85
|
+
*/
|
|
86
|
+
function savePersistedState(flows) {
|
|
87
|
+
try {
|
|
88
|
+
ensureDataDir();
|
|
89
|
+
const state = {
|
|
90
|
+
version: '1.0',
|
|
91
|
+
flows: Array.from(flows.entries()).map(([flowId, data]) => ({
|
|
92
|
+
flowId,
|
|
93
|
+
flowData: data.flowData,
|
|
94
|
+
deployedAt: data.deployedAt,
|
|
95
|
+
tenantId: data.tenantId,
|
|
96
|
+
})),
|
|
97
|
+
lastUpdated: Date.now(),
|
|
98
|
+
};
|
|
99
|
+
fs.writeFileSync(FLOWS_FILE, JSON.stringify(state, null, 2));
|
|
100
|
+
logger_1.default.info(`[Persistence] Saved ${state.flows.length} flows to disk`);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
logger_1.default.error('[Persistence] Error saving state:', error);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Remove a flow from persisted state
|
|
108
|
+
*/
|
|
109
|
+
function removePersistedFlow(flowId) {
|
|
110
|
+
try {
|
|
111
|
+
const state = loadPersistedState();
|
|
112
|
+
if (!state)
|
|
113
|
+
return;
|
|
114
|
+
state.flows = state.flows.filter(f => f.flowId !== flowId);
|
|
115
|
+
state.lastUpdated = Date.now();
|
|
116
|
+
ensureDataDir();
|
|
117
|
+
fs.writeFileSync(FLOWS_FILE, JSON.stringify(state, null, 2));
|
|
118
|
+
logger_1.default.info(`[Persistence] Removed flow ${flowId} from disk`);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
logger_1.default.error('[Persistence] Error removing flow:', error);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Clear all persisted state
|
|
126
|
+
*/
|
|
127
|
+
function clearPersistedState() {
|
|
128
|
+
try {
|
|
129
|
+
if (fs.existsSync(FLOWS_FILE)) {
|
|
130
|
+
fs.unlinkSync(FLOWS_FILE);
|
|
131
|
+
logger_1.default.info('[Persistence] Cleared all persisted state');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
logger_1.default.error('[Persistence] Error clearing state:', error);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=persistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence.js","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlowRed Runtime Service
|
|
3
|
+
*
|
|
4
|
+
* Distributed runtime execution engine with REST API + SSE events.
|
|
5
|
+
*
|
|
6
|
+
* Endpoints:
|
|
7
|
+
* - POST /deploy - Deploy a flow
|
|
8
|
+
* - POST /stop - Stop a flow
|
|
9
|
+
* - POST /inject - Execute an inject node
|
|
10
|
+
* - GET /status - Get runtime status
|
|
11
|
+
* - GET /events - SSE endpoint for real-time events
|
|
12
|
+
* - GET /health - Health check
|
|
13
|
+
*/
|
|
14
|
+
import { Application } from "express";
|
|
15
|
+
declare const app: Application;
|
|
16
|
+
export interface ServerOptions {
|
|
17
|
+
port?: number;
|
|
18
|
+
host?: string;
|
|
19
|
+
silent?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function createServer(options?: ServerOptions): Promise<ReturnType<typeof app.listen>>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAqBH,OAAgB,EAAqB,WAAW,EAAE,MAAM,SAAS,CAAC;AAUlE,QAAA,MAAM,GAAG,EAAE,WAAuB,CAAC;AA6lCnC,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,YAAY,CAC1B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,UAAU,CAAC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CA+CxC"}
|