@motiadev/core 0.0.27 → 0.0.29
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/index.d.ts +10 -9
- package/dist/index.js +23 -9
- package/dist/src/LoggerFactory.d.ts +14 -0
- package/dist/src/LoggerFactory.js +14 -0
- package/dist/src/call-step-file.js +9 -1
- package/dist/src/cron-handler.d.ts +2 -2
- package/dist/src/cron-handler.js +3 -3
- package/dist/src/get-step-config.js +10 -2
- package/dist/src/logger.d.ts +5 -4
- package/dist/src/logger.js +31 -24
- package/dist/src/pretty-print.d.ts +1 -0
- package/dist/src/pretty-print.js +66 -0
- package/dist/src/server.d.ts +5 -1
- package/dist/src/server.js +19 -11
- package/dist/src/state/adapters/default-state-adapter.d.ts +2 -0
- package/dist/src/state/adapters/default-state-adapter.js +21 -9
- package/dist/src/state/adapters/memory-state-adapter.d.ts +2 -0
- package/dist/src/state/adapters/memory-state-adapter.js +10 -0
- package/dist/src/state/adapters/redis-state-adapter.d.ts +2 -0
- package/dist/src/state/adapters/redis-state-adapter.js +10 -0
- package/dist/src/state/state-adapter.d.ts +2 -0
- package/dist/src/step-handlers.js +2 -5
- package/package.json +1 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export * from './src/types';
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
export
|
|
10
|
-
export
|
|
2
|
+
export { createServer, MotiaServer } from './src/server';
|
|
3
|
+
export { createStepHandlers, MotiaEventManager } from './src/step-handlers';
|
|
4
|
+
export { createEventManager } from './src/event-manager';
|
|
5
|
+
export { globalLogger, Logger } from './src/logger';
|
|
6
|
+
export { createStateAdapter } from './src/state/create-state-adapter';
|
|
7
|
+
export { setupCronHandlers, CronManager } from './src/cron-handler';
|
|
8
|
+
export { isApiStep, isCronStep, isEventStep, isNoopStep } from './src/guards';
|
|
9
|
+
export { LockedData } from './src/locked-data';
|
|
10
|
+
export { getStepConfig } from './src/get-step-config';
|
|
11
|
+
export { StateAdapter } from './src/state/state-adapter';
|
package/dist/index.js
CHANGED
|
@@ -14,13 +14,27 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.getStepConfig = exports.LockedData = exports.isNoopStep = exports.isEventStep = exports.isCronStep = exports.isApiStep = exports.setupCronHandlers = exports.createStateAdapter = exports.Logger = exports.globalLogger = exports.createEventManager = exports.createStepHandlers = exports.createServer = void 0;
|
|
17
18
|
__exportStar(require("./src/types"), exports);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
var server_1 = require("./src/server");
|
|
20
|
+
Object.defineProperty(exports, "createServer", { enumerable: true, get: function () { return server_1.createServer; } });
|
|
21
|
+
var step_handlers_1 = require("./src/step-handlers");
|
|
22
|
+
Object.defineProperty(exports, "createStepHandlers", { enumerable: true, get: function () { return step_handlers_1.createStepHandlers; } });
|
|
23
|
+
var event_manager_1 = require("./src/event-manager");
|
|
24
|
+
Object.defineProperty(exports, "createEventManager", { enumerable: true, get: function () { return event_manager_1.createEventManager; } });
|
|
25
|
+
var logger_1 = require("./src/logger");
|
|
26
|
+
Object.defineProperty(exports, "globalLogger", { enumerable: true, get: function () { return logger_1.globalLogger; } });
|
|
27
|
+
Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_1.Logger; } });
|
|
28
|
+
var create_state_adapter_1 = require("./src/state/create-state-adapter");
|
|
29
|
+
Object.defineProperty(exports, "createStateAdapter", { enumerable: true, get: function () { return create_state_adapter_1.createStateAdapter; } });
|
|
30
|
+
var cron_handler_1 = require("./src/cron-handler");
|
|
31
|
+
Object.defineProperty(exports, "setupCronHandlers", { enumerable: true, get: function () { return cron_handler_1.setupCronHandlers; } });
|
|
32
|
+
var guards_1 = require("./src/guards");
|
|
33
|
+
Object.defineProperty(exports, "isApiStep", { enumerable: true, get: function () { return guards_1.isApiStep; } });
|
|
34
|
+
Object.defineProperty(exports, "isCronStep", { enumerable: true, get: function () { return guards_1.isCronStep; } });
|
|
35
|
+
Object.defineProperty(exports, "isEventStep", { enumerable: true, get: function () { return guards_1.isEventStep; } });
|
|
36
|
+
Object.defineProperty(exports, "isNoopStep", { enumerable: true, get: function () { return guards_1.isNoopStep; } });
|
|
37
|
+
var locked_data_1 = require("./src/locked-data");
|
|
38
|
+
Object.defineProperty(exports, "LockedData", { enumerable: true, get: function () { return locked_data_1.LockedData; } });
|
|
39
|
+
var get_step_config_1 = require("./src/get-step-config");
|
|
40
|
+
Object.defineProperty(exports, "getStepConfig", { enumerable: true, get: function () { return get_step_config_1.getStepConfig; } });
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Server } from 'socket.io';
|
|
2
|
+
import { Logger } from './logger';
|
|
3
|
+
type CreateLogger = {
|
|
4
|
+
traceId: string;
|
|
5
|
+
flows?: string[];
|
|
6
|
+
stepName: string;
|
|
7
|
+
};
|
|
8
|
+
export declare class LoggerFactory {
|
|
9
|
+
private readonly isVerbose;
|
|
10
|
+
private readonly socketServer;
|
|
11
|
+
constructor(isVerbose: boolean, socketServer: Server);
|
|
12
|
+
create({ stepName, traceId, flows }: CreateLogger): Logger;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LoggerFactory = void 0;
|
|
4
|
+
const logger_1 = require("./logger");
|
|
5
|
+
class LoggerFactory {
|
|
6
|
+
constructor(isVerbose, socketServer) {
|
|
7
|
+
this.isVerbose = isVerbose;
|
|
8
|
+
this.socketServer = socketServer;
|
|
9
|
+
}
|
|
10
|
+
create({ stepName, traceId, flows }) {
|
|
11
|
+
return new logger_1.Logger(traceId, flows, stepName, this.isVerbose, this.socketServer);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.LoggerFactory = LoggerFactory;
|
|
@@ -70,12 +70,20 @@ const callStepFile = (options) => {
|
|
|
70
70
|
child.stderr?.on('data', (data) => logger.error(Buffer.from(data).toString()));
|
|
71
71
|
child.on('close', (code) => {
|
|
72
72
|
if (code !== 0 && code !== null) {
|
|
73
|
-
reject(
|
|
73
|
+
reject(`Process exited with code ${code}`);
|
|
74
74
|
}
|
|
75
75
|
else {
|
|
76
76
|
resolve(result);
|
|
77
77
|
}
|
|
78
78
|
});
|
|
79
|
+
child.on('error', (error) => {
|
|
80
|
+
if (error.code === 'ENOENT') {
|
|
81
|
+
reject(`Executable ${command} not found`);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
reject(error);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
79
87
|
});
|
|
80
88
|
};
|
|
81
89
|
exports.callStepFile = callStepFile;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Server } from 'socket.io';
|
|
2
1
|
import { LockedData } from './locked-data';
|
|
3
2
|
import { StateAdapter } from './state/state-adapter';
|
|
4
3
|
import { CronConfig, EventManager, Step } from './types';
|
|
4
|
+
import { LoggerFactory } from './LoggerFactory';
|
|
5
5
|
export type CronManager = {
|
|
6
6
|
createCronJob: (step: Step<CronConfig>) => void;
|
|
7
7
|
removeCronJob: (step: Step<CronConfig>) => void;
|
|
8
8
|
close: () => void;
|
|
9
9
|
};
|
|
10
|
-
export declare const setupCronHandlers: (lockedData: LockedData, eventManager: EventManager, state: StateAdapter,
|
|
10
|
+
export declare const setupCronHandlers: (lockedData: LockedData, eventManager: EventManager, state: StateAdapter, loggerFactory: LoggerFactory) => {
|
|
11
11
|
createCronJob: (step: Step<CronConfig>) => void;
|
|
12
12
|
removeCronJob: (step: Step<CronConfig>) => void;
|
|
13
13
|
close: () => void;
|
package/dist/src/cron-handler.js
CHANGED
|
@@ -38,12 +38,12 @@ const crypto_1 = require("crypto");
|
|
|
38
38
|
const cron = __importStar(require("node-cron"));
|
|
39
39
|
const call_step_file_1 = require("./call-step-file");
|
|
40
40
|
const logger_1 = require("./logger");
|
|
41
|
-
const setupCronHandlers = (lockedData, eventManager, state,
|
|
41
|
+
const setupCronHandlers = (lockedData, eventManager, state, loggerFactory) => {
|
|
42
42
|
const cronJobs = new Map();
|
|
43
43
|
const printer = lockedData.printer;
|
|
44
44
|
const createCronJob = (step) => {
|
|
45
45
|
const { config, filePath } = step;
|
|
46
|
-
const { cron: cronExpression, name: stepName } = config;
|
|
46
|
+
const { cron: cronExpression, name: stepName, flows } = config;
|
|
47
47
|
if (!cron.validate(cronExpression)) {
|
|
48
48
|
logger_1.globalLogger.error('[cron handler] invalid cron expression', {
|
|
49
49
|
expression: cronExpression,
|
|
@@ -58,7 +58,7 @@ const setupCronHandlers = (lockedData, eventManager, state, socketServer) => {
|
|
|
58
58
|
});
|
|
59
59
|
const task = cron.schedule(cronExpression, async () => {
|
|
60
60
|
const traceId = (0, crypto_1.randomUUID)();
|
|
61
|
-
const logger =
|
|
61
|
+
const logger = loggerFactory.create({ traceId, flows, stepName });
|
|
62
62
|
try {
|
|
63
63
|
await (0, call_step_file_1.callStepFile)({
|
|
64
64
|
contextInFirstArg: true,
|
|
@@ -47,10 +47,18 @@ const getStepConfig = (file) => {
|
|
|
47
47
|
return; // Config was already resolved
|
|
48
48
|
}
|
|
49
49
|
else if (code !== 0) {
|
|
50
|
-
reject(
|
|
50
|
+
reject(`Process exited with code ${code}`);
|
|
51
51
|
}
|
|
52
52
|
else if (!config) {
|
|
53
|
-
reject(
|
|
53
|
+
reject(`No config found for file ${file}`);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
child.on('error', (error) => {
|
|
57
|
+
if (error.code === 'ENOENT') {
|
|
58
|
+
reject(`Executable ${command} not found`);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
reject(error);
|
|
54
62
|
}
|
|
55
63
|
});
|
|
56
64
|
});
|
package/dist/src/logger.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { Server } from 'socket.io';
|
|
2
2
|
export declare class BaseLogger {
|
|
3
|
+
readonly isVerbose: boolean;
|
|
3
4
|
private readonly meta;
|
|
4
|
-
|
|
5
|
-
constructor(meta?: Record<string, unknown>);
|
|
5
|
+
constructor(isVerbose?: boolean, meta?: Record<string, unknown>);
|
|
6
6
|
child(meta?: Record<string, unknown>): this;
|
|
7
|
+
private _log;
|
|
7
8
|
info(message: string, args?: unknown): void;
|
|
8
9
|
error(message: string, args?: unknown): void;
|
|
9
10
|
debug(message: string, args?: unknown): void;
|
|
10
11
|
warn(message: string, args?: unknown): void;
|
|
11
|
-
log(args:
|
|
12
|
+
log(args: any): void;
|
|
12
13
|
}
|
|
13
14
|
export declare class Logger extends BaseLogger {
|
|
14
15
|
private readonly traceId;
|
|
@@ -16,7 +17,7 @@ export declare class Logger extends BaseLogger {
|
|
|
16
17
|
private readonly step;
|
|
17
18
|
private readonly socketServer?;
|
|
18
19
|
private emitLog;
|
|
19
|
-
constructor(traceId: string, flows: string[] | undefined, step: string, socketServer?: Server | undefined);
|
|
20
|
+
constructor(traceId: string, flows: string[] | undefined, step: string, isVerbose: boolean, socketServer?: Server | undefined);
|
|
20
21
|
child(meta?: Record<string, unknown>): this;
|
|
21
22
|
log(message: any): void;
|
|
22
23
|
info: (message: string, args?: unknown) => void;
|
package/dist/src/logger.js
CHANGED
|
@@ -1,44 +1,51 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.globalLogger = exports.Logger = exports.BaseLogger = void 0;
|
|
7
|
-
const
|
|
8
|
-
const
|
|
4
|
+
const pretty_print_1 = require("./pretty-print");
|
|
5
|
+
const logLevel = process.env.LOG_LEVEL ?? 'info';
|
|
6
|
+
const isDebugEnabled = logLevel === 'debug';
|
|
7
|
+
const isInfoEnabled = ['info', 'debug'].includes(logLevel);
|
|
8
|
+
const isWarnEnabled = ['warn', 'info', 'debug', 'trace'].includes(logLevel);
|
|
9
9
|
class BaseLogger {
|
|
10
|
-
constructor(meta = {}) {
|
|
10
|
+
constructor(isVerbose = false, meta = {}) {
|
|
11
|
+
this.isVerbose = isVerbose;
|
|
11
12
|
this.meta = meta;
|
|
12
|
-
this.logger = (0, pino_1.default)({
|
|
13
|
-
level: process.env.LOG_LEVEL || 'info',
|
|
14
|
-
formatters: { level: (level) => ({ level }) },
|
|
15
|
-
base: null,
|
|
16
|
-
mixin: () => meta,
|
|
17
|
-
});
|
|
18
13
|
}
|
|
19
14
|
child(meta = {}) {
|
|
20
|
-
return new BaseLogger({ ...this.meta, ...meta });
|
|
15
|
+
return new BaseLogger(this.isVerbose, { ...this.meta, ...meta });
|
|
16
|
+
}
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
18
|
+
_log(level, msg, args) {
|
|
19
|
+
const time = Date.now();
|
|
20
|
+
(0, pretty_print_1.prettyPrint)({ level, time, msg, ...this.meta, ...(args ?? {}) }, !this.isVerbose);
|
|
21
21
|
}
|
|
22
22
|
info(message, args) {
|
|
23
|
-
|
|
23
|
+
if (isInfoEnabled) {
|
|
24
|
+
this._log('info', message, args);
|
|
25
|
+
}
|
|
24
26
|
}
|
|
25
27
|
error(message, args) {
|
|
26
|
-
this.
|
|
28
|
+
this._log('error', message, args);
|
|
27
29
|
}
|
|
28
30
|
debug(message, args) {
|
|
29
|
-
|
|
31
|
+
if (isDebugEnabled) {
|
|
32
|
+
this._log('debug', message, args);
|
|
33
|
+
}
|
|
30
34
|
}
|
|
31
35
|
warn(message, args) {
|
|
32
|
-
|
|
36
|
+
if (isWarnEnabled) {
|
|
37
|
+
this._log('warn', message, args);
|
|
38
|
+
}
|
|
33
39
|
}
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
41
|
log(args) {
|
|
35
|
-
this.
|
|
42
|
+
this._log('info', args.msg, args);
|
|
36
43
|
}
|
|
37
44
|
}
|
|
38
45
|
exports.BaseLogger = BaseLogger;
|
|
39
46
|
class Logger extends BaseLogger {
|
|
40
|
-
constructor(traceId, flows, step, socketServer) {
|
|
41
|
-
super({ traceId, flows, step });
|
|
47
|
+
constructor(traceId, flows, step, isVerbose, socketServer) {
|
|
48
|
+
super(isVerbose, { traceId, flows, step });
|
|
42
49
|
this.traceId = traceId;
|
|
43
50
|
this.flows = flows;
|
|
44
51
|
this.step = step;
|
|
@@ -52,8 +59,8 @@ class Logger extends BaseLogger {
|
|
|
52
59
|
this.emitLog('error', message, args);
|
|
53
60
|
};
|
|
54
61
|
this.debug = (message, args) => {
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
if (isDebugEnabled) {
|
|
63
|
+
super.debug(message, args);
|
|
57
64
|
this.emitLog('debug', message, args);
|
|
58
65
|
}
|
|
59
66
|
};
|
|
@@ -74,11 +81,11 @@ class Logger extends BaseLogger {
|
|
|
74
81
|
};
|
|
75
82
|
}
|
|
76
83
|
child(meta = {}) {
|
|
77
|
-
return new Logger(this.traceId, this.flows, meta.step, this.socketServer);
|
|
84
|
+
return new Logger(this.traceId, this.flows, meta.step, this.isVerbose, this.socketServer);
|
|
78
85
|
}
|
|
79
86
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
80
87
|
log(message) {
|
|
81
|
-
|
|
88
|
+
super.log(message);
|
|
82
89
|
this.emitLog(message.level, message.msg, message);
|
|
83
90
|
}
|
|
84
91
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const prettyPrint: (json: Record<string, any>, excludeDetails?: boolean) => void;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.prettyPrint = void 0;
|
|
7
|
+
const colors_1 = __importDefault(require("colors"));
|
|
8
|
+
const stepTag = (step) => colors_1.default.bold(colors_1.default.cyan(step));
|
|
9
|
+
const timestampTag = (timestamp) => colors_1.default.gray(timestamp);
|
|
10
|
+
const traceIdTag = (traceId) => colors_1.default.gray(traceId);
|
|
11
|
+
const levelTags = {
|
|
12
|
+
error: colors_1.default.red('[ERROR]'),
|
|
13
|
+
info: colors_1.default.blue('[INFO]'),
|
|
14
|
+
warn: colors_1.default.yellow('[WARN]'),
|
|
15
|
+
debug: colors_1.default.gray('[DEBUG]'),
|
|
16
|
+
trace: colors_1.default.gray('[TRACE]'),
|
|
17
|
+
};
|
|
18
|
+
const numericTag = (value) => colors_1.default.green(value);
|
|
19
|
+
const stringTag = (value) => colors_1.default.cyan(value);
|
|
20
|
+
const booleanTag = (value) => colors_1.default.blue(value);
|
|
21
|
+
const arrayBrackets = ['[', ']'].map((s) => colors_1.default.gray(s));
|
|
22
|
+
const objectBrackets = ['{', '}'].map((s) => colors_1.default.gray(s));
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
|
+
const prettyPrintObject = (obj, depth = 0, parentIsLast = false, prefix = '') => {
|
|
25
|
+
const tab = prefix + (depth === 0 ? '' : parentIsLast ? '│ ' : '│ ');
|
|
26
|
+
if (depth > 2) {
|
|
27
|
+
return `${tab} └ ${colors_1.default.gray('[...]')}`;
|
|
28
|
+
}
|
|
29
|
+
const entries = Object.entries(obj);
|
|
30
|
+
return entries
|
|
31
|
+
.map(([key, value], index) => {
|
|
32
|
+
const isLast = index === entries.length - 1;
|
|
33
|
+
const isObject = typeof value === 'object' && value !== null;
|
|
34
|
+
const prefix = isLast && !isObject ? '└' : '├';
|
|
35
|
+
if (isObject) {
|
|
36
|
+
const subObject = prettyPrintObject(value, depth + 1, isLast, tab);
|
|
37
|
+
const [start, end] = Array.isArray(value) ? arrayBrackets : objectBrackets;
|
|
38
|
+
return `${tab}${prefix} ${key}: ${start}\n${subObject}\n${tab}${isLast ? '└' : '│'} ${end}`;
|
|
39
|
+
}
|
|
40
|
+
let printedValue = value;
|
|
41
|
+
if (typeof value === 'number') {
|
|
42
|
+
printedValue = numericTag(String(value));
|
|
43
|
+
}
|
|
44
|
+
else if (typeof value === 'boolean') {
|
|
45
|
+
printedValue = booleanTag(String(value));
|
|
46
|
+
}
|
|
47
|
+
else if (typeof value === 'string') {
|
|
48
|
+
printedValue = stringTag(value);
|
|
49
|
+
}
|
|
50
|
+
return `${tab}${prefix} ${key}: ${printedValue}`;
|
|
51
|
+
})
|
|
52
|
+
.join('\n');
|
|
53
|
+
};
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
55
|
+
const prettyPrint = (json, excludeDetails = false) => {
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
57
|
+
const { time, traceId, msg, flows, level, step, ...details } = json;
|
|
58
|
+
const levelTag = levelTags[level];
|
|
59
|
+
const timestamp = timestampTag(`[${new Date(time).toLocaleTimeString()}]`);
|
|
60
|
+
const objectHasKeys = Object.keys(details).length > 0;
|
|
61
|
+
console.log(`${timestamp} ${traceIdTag(traceId)} ${levelTag} ${stepTag(step)} ${msg}`);
|
|
62
|
+
if (objectHasKeys && !excludeDetails) {
|
|
63
|
+
console.log(prettyPrintObject(details));
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
exports.prettyPrint = prettyPrint;
|
package/dist/src/server.d.ts
CHANGED
|
@@ -14,4 +14,8 @@ export type MotiaServer = {
|
|
|
14
14
|
addRoute: (step: Step<ApiRouteConfig>) => void;
|
|
15
15
|
cronManager: CronManager;
|
|
16
16
|
};
|
|
17
|
-
|
|
17
|
+
type MotiaServerConfig = {
|
|
18
|
+
isVerbose: boolean;
|
|
19
|
+
};
|
|
20
|
+
export declare const createServer: (lockedData: LockedData, eventManager: EventManager, state: StateAdapter, config: MotiaServerConfig) => Promise<MotiaServer>;
|
|
21
|
+
export {};
|
package/dist/src/server.js
CHANGED
|
@@ -15,18 +15,20 @@ const guards_1 = require("./guards");
|
|
|
15
15
|
const logger_1 = require("./logger");
|
|
16
16
|
const steps_1 = require("./steps");
|
|
17
17
|
const call_step_file_1 = require("./call-step-file");
|
|
18
|
-
const
|
|
18
|
+
const LoggerFactory_1 = require("./LoggerFactory");
|
|
19
|
+
const createServer = async (lockedData, eventManager, state, config) => {
|
|
19
20
|
const printer = lockedData.printer;
|
|
20
21
|
const app = (0, express_1.default)();
|
|
21
22
|
const server = http_1.default.createServer(app);
|
|
22
23
|
const io = new socket_io_1.Server(server);
|
|
24
|
+
const loggerFactory = new LoggerFactory_1.LoggerFactory(config.isVerbose, io);
|
|
23
25
|
const allSteps = [...steps_1.systemSteps, ...lockedData.activeSteps];
|
|
24
|
-
const cronManager = (0, cron_handler_1.setupCronHandlers)(lockedData, eventManager, state,
|
|
26
|
+
const cronManager = (0, cron_handler_1.setupCronHandlers)(lockedData, eventManager, state, loggerFactory);
|
|
25
27
|
const asyncHandler = (step) => {
|
|
26
28
|
return async (req, res) => {
|
|
27
29
|
const traceId = (0, crypto_1.randomUUID)();
|
|
28
|
-
const { name, flows } = step.config;
|
|
29
|
-
const logger =
|
|
30
|
+
const { name: stepName, flows } = step.config;
|
|
31
|
+
const logger = loggerFactory.create({ traceId, flows, stepName });
|
|
30
32
|
logger.debug('[API] Received request, processing step', { path: req.path });
|
|
31
33
|
const request = {
|
|
32
34
|
body: req.body,
|
|
@@ -69,15 +71,21 @@ const createServer = async (lockedData, eventManager, state) => {
|
|
|
69
71
|
const addRoute = (step) => {
|
|
70
72
|
const { method, path } = step.config;
|
|
71
73
|
logger_1.globalLogger.debug('[API] Registering route', step.config);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
router.
|
|
77
|
-
|
|
78
|
-
|
|
74
|
+
const handler = asyncHandler(step);
|
|
75
|
+
const methods = {
|
|
76
|
+
GET: () => router.get(path, handler),
|
|
77
|
+
POST: () => router.post(path, handler),
|
|
78
|
+
PUT: () => router.put(path, handler),
|
|
79
|
+
DELETE: () => router.delete(path, handler),
|
|
80
|
+
PATCH: () => router.patch(path, handler),
|
|
81
|
+
OPTIONS: () => router.options(path, handler),
|
|
82
|
+
HEAD: () => router.head(path, handler),
|
|
83
|
+
};
|
|
84
|
+
const methodHandler = methods[method];
|
|
85
|
+
if (!methodHandler) {
|
|
79
86
|
throw new Error(`Unsupported method: ${method}`);
|
|
80
87
|
}
|
|
88
|
+
methodHandler();
|
|
81
89
|
};
|
|
82
90
|
const removeRoute = (step) => {
|
|
83
91
|
const { path, method } = step.config;
|
|
@@ -10,6 +10,8 @@ export declare class FileStateAdapter implements StateAdapter {
|
|
|
10
10
|
set<T>(traceId: string, key: string, value: T): Promise<void>;
|
|
11
11
|
delete(traceId: string, key: string): Promise<void>;
|
|
12
12
|
clear(traceId: string): Promise<void>;
|
|
13
|
+
keys(traceId: string): Promise<string[]>;
|
|
14
|
+
traceIds(): Promise<string[]>;
|
|
13
15
|
cleanup(): Promise<void>;
|
|
14
16
|
private _makeKey;
|
|
15
17
|
private _readFile;
|
|
@@ -59,31 +59,43 @@ class FileStateAdapter {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
async get(traceId, key) {
|
|
62
|
-
const data =
|
|
62
|
+
const data = this._readFile();
|
|
63
63
|
const fullKey = this._makeKey(traceId, key);
|
|
64
64
|
return data[fullKey] ? JSON.parse(data[fullKey]) : null;
|
|
65
65
|
}
|
|
66
66
|
async set(traceId, key, value) {
|
|
67
|
-
const data =
|
|
67
|
+
const data = this._readFile();
|
|
68
68
|
const fullKey = this._makeKey(traceId, key);
|
|
69
69
|
data[fullKey] = JSON.stringify(value);
|
|
70
|
-
|
|
70
|
+
this._writeFile(data);
|
|
71
71
|
}
|
|
72
72
|
async delete(traceId, key) {
|
|
73
|
-
const data =
|
|
73
|
+
const data = this._readFile();
|
|
74
74
|
const fullKey = this._makeKey(traceId, key);
|
|
75
75
|
delete data[fullKey];
|
|
76
|
-
|
|
76
|
+
this._writeFile(data);
|
|
77
77
|
}
|
|
78
78
|
async clear(traceId) {
|
|
79
|
-
const data =
|
|
79
|
+
const data = this._readFile();
|
|
80
80
|
const pattern = this._makeKey(traceId, '');
|
|
81
81
|
for (const key in data) {
|
|
82
82
|
if (key.startsWith(pattern)) {
|
|
83
83
|
delete data[key];
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
-
|
|
86
|
+
this._writeFile(data);
|
|
87
|
+
}
|
|
88
|
+
async keys(traceId) {
|
|
89
|
+
const data = this._readFile();
|
|
90
|
+
return Object.keys(data)
|
|
91
|
+
.filter((key) => key.startsWith(this._makeKey(traceId, '')))
|
|
92
|
+
.map((key) => key.replace(this._makeKey(traceId, ''), ''));
|
|
93
|
+
}
|
|
94
|
+
async traceIds() {
|
|
95
|
+
const data = this._readFile();
|
|
96
|
+
const traceIds = new Set();
|
|
97
|
+
Object.keys(data).forEach((key) => traceIds.add(key.split(':')[0]));
|
|
98
|
+
return Array.from(traceIds);
|
|
87
99
|
}
|
|
88
100
|
async cleanup() {
|
|
89
101
|
// No cleanup needed for file system
|
|
@@ -91,11 +103,11 @@ class FileStateAdapter {
|
|
|
91
103
|
_makeKey(traceId, key) {
|
|
92
104
|
return `${traceId}:${key}`;
|
|
93
105
|
}
|
|
94
|
-
|
|
106
|
+
_readFile() {
|
|
95
107
|
const content = fs_1.default.readFileSync(this.filePath, 'utf-8');
|
|
96
108
|
return JSON.parse(content);
|
|
97
109
|
}
|
|
98
|
-
|
|
110
|
+
_writeFile(data) {
|
|
99
111
|
fs_1.default.writeFileSync(this.filePath, JSON.stringify(data, null, 2), 'utf-8');
|
|
100
112
|
}
|
|
101
113
|
}
|
|
@@ -6,6 +6,8 @@ export declare class MemoryStateAdapter implements StateAdapter {
|
|
|
6
6
|
set<T>(traceId: string, key: string, value: T): Promise<void>;
|
|
7
7
|
delete(traceId: string, key: string): Promise<void>;
|
|
8
8
|
clear(traceId: string): Promise<void>;
|
|
9
|
+
keys(traceId: string): Promise<string[]>;
|
|
10
|
+
traceIds(): Promise<string[]>;
|
|
9
11
|
cleanup(): Promise<void>;
|
|
10
12
|
private _makeKey;
|
|
11
13
|
}
|
|
@@ -28,6 +28,16 @@ class MemoryStateAdapter {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
+
async keys(traceId) {
|
|
32
|
+
return Object.keys(this.state)
|
|
33
|
+
.filter((key) => key.startsWith(this._makeKey(traceId, '')))
|
|
34
|
+
.map((key) => key.replace(this._makeKey(traceId, ''), ''));
|
|
35
|
+
}
|
|
36
|
+
async traceIds() {
|
|
37
|
+
const traceIds = new Set();
|
|
38
|
+
Object.keys(this.state).forEach((key) => traceIds.add(key.split(':')[0]));
|
|
39
|
+
return Array.from(traceIds);
|
|
40
|
+
}
|
|
31
41
|
async cleanup() {
|
|
32
42
|
// No cleanup needed for file system
|
|
33
43
|
}
|
|
@@ -14,6 +14,8 @@ export declare class RedisStateAdapter implements StateAdapter {
|
|
|
14
14
|
set<T>(traceId: string, key: string, value: T): Promise<void>;
|
|
15
15
|
delete(traceId: string, key: string): Promise<void>;
|
|
16
16
|
clear(traceId: string): Promise<void>;
|
|
17
|
+
keys(traceId: string): Promise<string[]>;
|
|
18
|
+
traceIds(): Promise<string[]>;
|
|
17
19
|
cleanup(): Promise<void>;
|
|
18
20
|
_makeKey(traceId: string, key: string): string;
|
|
19
21
|
}
|
|
@@ -34,6 +34,16 @@ class RedisStateAdapter {
|
|
|
34
34
|
await this.client.del(keys);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
+
async keys(traceId) {
|
|
38
|
+
const pattern = this._makeKey(traceId, '*');
|
|
39
|
+
const keys = await this.client.keys(pattern);
|
|
40
|
+
return keys.map((key) => key.replace(this._makeKey(traceId, ''), ''));
|
|
41
|
+
}
|
|
42
|
+
async traceIds() {
|
|
43
|
+
const pattern = `${this.prefix}:*`;
|
|
44
|
+
const keys = await this.client.keys(pattern);
|
|
45
|
+
return keys.map((key) => key.split(':')[1]);
|
|
46
|
+
}
|
|
37
47
|
async cleanup() {
|
|
38
48
|
await this.client.quit();
|
|
39
49
|
}
|
|
@@ -38,11 +38,8 @@ const createStepHandlers = (lockedData, eventManager, state) => {
|
|
|
38
38
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
filePath,
|
|
44
|
-
step: name,
|
|
45
|
-
});
|
|
41
|
+
const message = typeof error === 'string' ? error : error.message;
|
|
42
|
+
logger.error(message);
|
|
46
43
|
}
|
|
47
44
|
},
|
|
48
45
|
});
|
package/package.json
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@motiadev/core",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.29",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"body-parser": "^1.20.3",
|
|
7
7
|
"colors": "^1.4.0",
|
|
8
8
|
"express": "^4.21.2",
|
|
9
9
|
"ioredis": "^5.4.2",
|
|
10
10
|
"node-cron": "^3.0.3",
|
|
11
|
-
"pino": "^9.6.0",
|
|
12
11
|
"socket.io": "^4.8.1",
|
|
13
12
|
"ts-node": "^10.9.2",
|
|
14
13
|
"tsconfig-paths": "^4.2.0",
|