@motiadev/core 0.15.5-beta.174-069425 → 0.15.5-beta.174-384621
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/src/logger.d.mts +1 -0
- package/dist/src/logger.d.mts.map +1 -1
- package/dist/src/logger.mjs +4 -0
- package/dist/src/logger.mjs.map +1 -1
- package/dist/src/observability/tracer.mjs.map +1 -1
- package/dist/src/process-communication/process-manager.mjs +9 -3
- package/dist/src/process-communication/process-manager.mjs.map +1 -1
- package/dist/src/python/can-access.py +2 -2
- package/dist/src/python/get-config.py +2 -2
- package/dist/src/python/python-runner.py +2 -2
- package/dist/src/socket-server.mjs +31 -13
- package/dist/src/socket-server.mjs.map +1 -1
- package/dist/src/step-handler-rpc-processor.mjs +1 -0
- package/dist/src/step-handler-rpc-processor.mjs.map +1 -1
- package/dist/src/step-handler-rpc-stdin-processor.mjs +1 -0
- package/dist/src/step-handler-rpc-stdin-processor.mjs.map +1 -1
- package/package.json +1 -1
package/dist/src/logger.d.mts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.mts","names":[],"sources":["../../src/logger.ts"],"sourcesContent":[],"mappings":";KA6BY,WAAA;AAAA,cAEC,MAAA,CAFU;EAEV,SAAM,SAAA,EAAA,OAAA;EAaQ,iBAAA,IAAA;EACS,iBAAA,aAAA;EAGtB;;;;;;;;;0CAJa,yCACS;cAGtB,0BAA0B;;;;;;;wBA8ChB"}
|
|
1
|
+
{"version":3,"file":"logger.d.mts","names":[],"sources":["../../src/logger.ts"],"sourcesContent":[],"mappings":";KA6BY,WAAA;AAAA,cAEC,MAAA,CAFU;EAEV,SAAM,SAAA,EAAA,OAAA;EAaQ,iBAAA,IAAA;EACS,iBAAA,aAAA;EAGtB;;;;;;;;;0CAJa,yCACS;cAGtB,0BAA0B;;;;;;;wBA8ChB;2BAIG"}
|
package/dist/src/logger.mjs
CHANGED
|
@@ -71,6 +71,10 @@ var Logger = class Logger {
|
|
|
71
71
|
addListener(listener) {
|
|
72
72
|
this.listeners.push(listener);
|
|
73
73
|
}
|
|
74
|
+
removeListener(listener) {
|
|
75
|
+
const index = this.listeners.indexOf(listener);
|
|
76
|
+
if (index > -1) this.listeners.splice(index, 1);
|
|
77
|
+
}
|
|
74
78
|
};
|
|
75
79
|
const globalLogger = new Logger();
|
|
76
80
|
|
package/dist/src/logger.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.mjs","names":["levelMap: Record<string, number>","isVerbose: boolean","meta: Record<string, unknown>","coreListeners: LogListener[]"],"sources":["../../src/logger.ts"],"sourcesContent":["import { prettyPrint } from './pretty-print'\n\nconst LEVELS = {\n NOTSET: 0,\n DEBUG: 10,\n INFO: 20,\n WARNING: 30,\n ERROR: 40,\n CRITICAL: 50,\n} as const\n\nconst levelMap: Record<string, number> = {\n debug: LEVELS.DEBUG,\n info: LEVELS.INFO,\n warn: LEVELS.WARNING,\n warning: LEVELS.WARNING,\n error: LEVELS.ERROR,\n critical: LEVELS.CRITICAL,\n}\n\nconst getLogLevel = (): number => {\n const level = process.env.LOG_LEVEL ?? 'info'\n return levelMap[level] ?? LEVELS.INFO\n}\n\nconst shouldLog = (messageLevel: number): boolean => {\n return messageLevel >= getLogLevel()\n}\n\nexport type LogListener = (level: string, msg: string, args?: unknown) => void\n\nexport class Logger {\n /**\n * Why do we need two level of listeners?\n *\n * Core listeners pass along to children loggers.\n *\n * However, base listeners do not pass along to children loggers.\n * Those are specific to each logger in the hierarchy.\n */\n private readonly listeners: LogListener[] = []\n\n constructor(\n readonly isVerbose: boolean = false,\n private readonly meta: Record<string, unknown> = {},\n private readonly coreListeners: LogListener[] = [],\n ) {}\n\n child(meta: Record<string, unknown>): Logger {\n return new Logger(this.isVerbose, { ...this.meta, ...meta }, this.coreListeners)\n }\n\n private _log(level: string, msg: string, args?: any) {\n const time = Date.now()\n const meta = { ...this.meta, ...(args ?? {}) }\n prettyPrint({ level, time, msg, ...meta }, !this.isVerbose)\n\n this.coreListeners.forEach((listener) => listener(level, msg, meta))\n this.listeners.forEach((listener) => listener(level, msg, meta))\n }\n\n info(message: string, args?: unknown) {\n if (shouldLog(LEVELS.INFO)) {\n this._log('info', message, args)\n }\n }\n\n error(message: string, args?: unknown) {\n if (shouldLog(LEVELS.ERROR)) {\n this._log('error', message, args)\n }\n }\n\n debug(message: string, args?: unknown) {\n if (shouldLog(LEVELS.DEBUG)) {\n this._log('debug', message, args)\n }\n }\n\n warn(message: string, args?: unknown) {\n if (shouldLog(LEVELS.WARNING)) {\n this._log('warn', message, args)\n }\n }\n\n log(args: any) {\n const level = args.level ?? 'info'\n const messageLevel = levelMap[level] ?? LEVELS.INFO\n\n if (!shouldLog(messageLevel)) return\n\n this._log(level, args.msg, args)\n }\n\n addListener(listener: LogListener) {\n this.listeners.push(listener)\n }\n}\n\nexport const globalLogger = new Logger()\n"],"mappings":";;;AAEA,MAAM,SAAS;CACb,QAAQ;CACR,OAAO;CACP,MAAM;CACN,SAAS;CACT,OAAO;CACP,UAAU;CACX;AAED,MAAMA,WAAmC;CACvC,OAAO,OAAO;CACd,MAAM,OAAO;CACb,MAAM,OAAO;CACb,SAAS,OAAO;CAChB,OAAO,OAAO;CACd,UAAU,OAAO;CAClB;AAED,MAAM,oBAA4B;AAEhC,QAAO,SADO,QAAQ,IAAI,aAAa,WACb,OAAO;;AAGnC,MAAM,aAAa,iBAAkC;AACnD,QAAO,gBAAgB,aAAa;;AAKtC,IAAa,SAAb,MAAa,OAAO;CAWlB,YACE,AAASC,YAAqB,OAC9B,AAAiBC,OAAgC,EAAE,EACnD,AAAiBC,gBAA+B,EAAE,EAClD;EAHS;EACQ;EACA;mBALyB,EAAE;;CAQ9C,MAAM,MAAuC;AAC3C,SAAO,IAAI,OAAO,KAAK,WAAW;GAAE,GAAG,KAAK;GAAM,GAAG;GAAM,EAAE,KAAK,cAAc;;CAGlF,AAAQ,KAAK,OAAe,KAAa,MAAY;EACnD,MAAM,OAAO,KAAK,KAAK;EACvB,MAAM,OAAO;GAAE,GAAG,KAAK;GAAM,GAAI,QAAQ,EAAE;GAAG;AAC9C,cAAY;GAAE;GAAO;GAAM;GAAK,GAAG;GAAM,EAAE,CAAC,KAAK,UAAU;AAE3D,OAAK,cAAc,SAAS,aAAa,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,OAAK,UAAU,SAAS,aAAa,SAAS,OAAO,KAAK,KAAK,CAAC;;CAGlE,KAAK,SAAiB,MAAgB;AACpC,MAAI,UAAU,OAAO,KAAK,CACxB,MAAK,KAAK,QAAQ,SAAS,KAAK;;CAIpC,MAAM,SAAiB,MAAgB;AACrC,MAAI,UAAU,OAAO,MAAM,CACzB,MAAK,KAAK,SAAS,SAAS,KAAK;;CAIrC,MAAM,SAAiB,MAAgB;AACrC,MAAI,UAAU,OAAO,MAAM,CACzB,MAAK,KAAK,SAAS,SAAS,KAAK;;CAIrC,KAAK,SAAiB,MAAgB;AACpC,MAAI,UAAU,OAAO,QAAQ,CAC3B,MAAK,KAAK,QAAQ,SAAS,KAAK;;CAIpC,IAAI,MAAW;EACb,MAAM,QAAQ,KAAK,SAAS;AAG5B,MAAI,CAAC,UAFgB,SAAS,UAAU,OAAO,KAEnB,CAAE;AAE9B,OAAK,KAAK,OAAO,KAAK,KAAK,KAAK;;CAGlC,YAAY,UAAuB;AACjC,OAAK,UAAU,KAAK,SAAS;;;
|
|
1
|
+
{"version":3,"file":"logger.mjs","names":["levelMap: Record<string, number>","isVerbose: boolean","meta: Record<string, unknown>","coreListeners: LogListener[]"],"sources":["../../src/logger.ts"],"sourcesContent":["import { prettyPrint } from './pretty-print'\n\nconst LEVELS = {\n NOTSET: 0,\n DEBUG: 10,\n INFO: 20,\n WARNING: 30,\n ERROR: 40,\n CRITICAL: 50,\n} as const\n\nconst levelMap: Record<string, number> = {\n debug: LEVELS.DEBUG,\n info: LEVELS.INFO,\n warn: LEVELS.WARNING,\n warning: LEVELS.WARNING,\n error: LEVELS.ERROR,\n critical: LEVELS.CRITICAL,\n}\n\nconst getLogLevel = (): number => {\n const level = process.env.LOG_LEVEL ?? 'info'\n return levelMap[level] ?? LEVELS.INFO\n}\n\nconst shouldLog = (messageLevel: number): boolean => {\n return messageLevel >= getLogLevel()\n}\n\nexport type LogListener = (level: string, msg: string, args?: unknown) => void\n\nexport class Logger {\n /**\n * Why do we need two level of listeners?\n *\n * Core listeners pass along to children loggers.\n *\n * However, base listeners do not pass along to children loggers.\n * Those are specific to each logger in the hierarchy.\n */\n private readonly listeners: LogListener[] = []\n\n constructor(\n readonly isVerbose: boolean = false,\n private readonly meta: Record<string, unknown> = {},\n private readonly coreListeners: LogListener[] = [],\n ) {}\n\n child(meta: Record<string, unknown>): Logger {\n return new Logger(this.isVerbose, { ...this.meta, ...meta }, this.coreListeners)\n }\n\n private _log(level: string, msg: string, args?: any) {\n const time = Date.now()\n const meta = { ...this.meta, ...(args ?? {}) }\n prettyPrint({ level, time, msg, ...meta }, !this.isVerbose)\n\n this.coreListeners.forEach((listener) => listener(level, msg, meta))\n this.listeners.forEach((listener) => listener(level, msg, meta))\n }\n\n info(message: string, args?: unknown) {\n if (shouldLog(LEVELS.INFO)) {\n this._log('info', message, args)\n }\n }\n\n error(message: string, args?: unknown) {\n if (shouldLog(LEVELS.ERROR)) {\n this._log('error', message, args)\n }\n }\n\n debug(message: string, args?: unknown) {\n if (shouldLog(LEVELS.DEBUG)) {\n this._log('debug', message, args)\n }\n }\n\n warn(message: string, args?: unknown) {\n if (shouldLog(LEVELS.WARNING)) {\n this._log('warn', message, args)\n }\n }\n\n log(args: any) {\n const level = args.level ?? 'info'\n const messageLevel = levelMap[level] ?? LEVELS.INFO\n\n if (!shouldLog(messageLevel)) return\n\n this._log(level, args.msg, args)\n }\n\n addListener(listener: LogListener) {\n this.listeners.push(listener)\n }\n\n removeListener(listener: LogListener) {\n const index = this.listeners.indexOf(listener)\n if (index > -1) {\n this.listeners.splice(index, 1)\n }\n }\n}\n\nexport const globalLogger = new Logger()\n"],"mappings":";;;AAEA,MAAM,SAAS;CACb,QAAQ;CACR,OAAO;CACP,MAAM;CACN,SAAS;CACT,OAAO;CACP,UAAU;CACX;AAED,MAAMA,WAAmC;CACvC,OAAO,OAAO;CACd,MAAM,OAAO;CACb,MAAM,OAAO;CACb,SAAS,OAAO;CAChB,OAAO,OAAO;CACd,UAAU,OAAO;CAClB;AAED,MAAM,oBAA4B;AAEhC,QAAO,SADO,QAAQ,IAAI,aAAa,WACb,OAAO;;AAGnC,MAAM,aAAa,iBAAkC;AACnD,QAAO,gBAAgB,aAAa;;AAKtC,IAAa,SAAb,MAAa,OAAO;CAWlB,YACE,AAASC,YAAqB,OAC9B,AAAiBC,OAAgC,EAAE,EACnD,AAAiBC,gBAA+B,EAAE,EAClD;EAHS;EACQ;EACA;mBALyB,EAAE;;CAQ9C,MAAM,MAAuC;AAC3C,SAAO,IAAI,OAAO,KAAK,WAAW;GAAE,GAAG,KAAK;GAAM,GAAG;GAAM,EAAE,KAAK,cAAc;;CAGlF,AAAQ,KAAK,OAAe,KAAa,MAAY;EACnD,MAAM,OAAO,KAAK,KAAK;EACvB,MAAM,OAAO;GAAE,GAAG,KAAK;GAAM,GAAI,QAAQ,EAAE;GAAG;AAC9C,cAAY;GAAE;GAAO;GAAM;GAAK,GAAG;GAAM,EAAE,CAAC,KAAK,UAAU;AAE3D,OAAK,cAAc,SAAS,aAAa,SAAS,OAAO,KAAK,KAAK,CAAC;AACpE,OAAK,UAAU,SAAS,aAAa,SAAS,OAAO,KAAK,KAAK,CAAC;;CAGlE,KAAK,SAAiB,MAAgB;AACpC,MAAI,UAAU,OAAO,KAAK,CACxB,MAAK,KAAK,QAAQ,SAAS,KAAK;;CAIpC,MAAM,SAAiB,MAAgB;AACrC,MAAI,UAAU,OAAO,MAAM,CACzB,MAAK,KAAK,SAAS,SAAS,KAAK;;CAIrC,MAAM,SAAiB,MAAgB;AACrC,MAAI,UAAU,OAAO,MAAM,CACzB,MAAK,KAAK,SAAS,SAAS,KAAK;;CAIrC,KAAK,SAAiB,MAAgB;AACpC,MAAI,UAAU,OAAO,QAAQ,CAC3B,MAAK,KAAK,QAAQ,SAAS,KAAK;;CAIpC,IAAI,MAAW;EACb,MAAM,QAAQ,KAAK,SAAS;AAG5B,MAAI,CAAC,UAFgB,SAAS,UAAU,OAAO,KAEnB,CAAE;AAE9B,OAAK,KAAK,OAAO,KAAK,KAAK,KAAK;;CAGlC,YAAY,UAAuB;AACjC,OAAK,UAAU,KAAK,SAAS;;CAG/B,eAAe,UAAuB;EACpC,MAAM,QAAQ,KAAK,UAAU,QAAQ,SAAS;AAC9C,MAAI,QAAQ,GACV,MAAK,UAAU,OAAO,OAAO,EAAE;;;AAKrC,MAAa,eAAe,IAAI,QAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracer.mjs","names":["traceStream: MotiaStream<Trace>","traceGroupStream: MotiaStream<TraceGroup>","traceGroup: TraceGroup","traceStreamAdapter: MotiaStream<Trace>","traceGroupStreamAdapter: MotiaStream<TraceGroup>"],"sources":["../../../src/observability/tracer.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"tracer.mjs","names":["traceStream: MotiaStream<Trace>","traceGroupStream: MotiaStream<TraceGroup>","traceGroup: TraceGroup","traceStreamAdapter: MotiaStream<Trace>","traceGroupStreamAdapter: MotiaStream<TraceGroup>"],"sources":["../../../src/observability/tracer.ts"],"sourcesContent":["import type { LockedData } from '../locked-data'\nimport type { Logger } from '../logger'\nimport type { Step } from '../types'\nimport type { MotiaStream } from '../types-stream'\nimport { createTrace } from './create-trace'\nimport type { TracerFactory } from './index'\nimport { RedisTraceStreamAdapter } from './redis-trace-stream-adapter'\nimport { StreamTracer } from './stream-tracer'\nimport { TraceManager } from './trace-manager'\nimport type { Trace, TraceGroup } from './types'\n\nexport class BaseTracerFactory implements TracerFactory {\n constructor(\n private readonly traceStream: MotiaStream<Trace>,\n private readonly traceGroupStream: MotiaStream<TraceGroup>,\n ) {}\n\n private async getAllGroups() {\n return await this.traceGroupStream.getGroup('default')\n }\n\n private async deleteGroup(group: TraceGroup) {\n const traces = await this.traceStream.getGroup(group.id)\n\n for (const trace of traces) {\n await this.traceStream.delete(group.id, trace.id)\n }\n await this.traceGroupStream.delete('default', group.id)\n }\n\n async clear() {\n const groups = await this.getAllGroups()\n\n for (const group of groups) {\n await this.deleteGroup(group)\n }\n }\n\n async createTracer(traceId: string, step: Step, logger: Logger) {\n const traceGroup: TraceGroup = {\n id: traceId,\n name: step.config.name,\n lastActivity: Date.now(),\n metadata: {\n completedSteps: 0,\n activeSteps: 0,\n totalSteps: 0,\n },\n correlationId: undefined,\n status: 'running',\n startTime: Date.now(),\n }\n\n const trace = createTrace(traceGroup, step)\n const manager = new TraceManager(this.traceStream, this.traceGroupStream, traceGroup, trace)\n\n return new StreamTracer(manager, traceGroup, trace, logger)\n }\n\n async attachToTrace(traceId: string, step: Step, logger: Logger) {\n const existingGroup = await this.traceGroupStream.get('default', traceId)\n\n if (!existingGroup) {\n return this.createTracer(traceId, step, logger)\n }\n\n const trace = createTrace(existingGroup, step)\n const manager = new TraceManager(this.traceStream, this.traceGroupStream, existingGroup, trace)\n\n return new StreamTracer(manager, existingGroup, trace, logger)\n }\n}\n\nexport const createTracerFactory = (lockedData: LockedData): TracerFactory => {\n if (!lockedData.redisClient) {\n throw new Error(\n 'Redis client is required for tracer factory. Please provide a redisClient when creating LockedData.',\n )\n }\n\n const traceStreamName = 'motia-trace'\n const traceStreamAdapter: MotiaStream<Trace> = new RedisTraceStreamAdapter(traceStreamName, lockedData.redisClient)\n\n const traceStream = lockedData.createStream<Trace>({\n filePath: traceStreamName,\n hidden: true,\n config: {\n name: traceStreamName,\n baseConfig: { storageType: 'custom', factory: () => traceStreamAdapter },\n schema: null as never,\n },\n })()\n\n const traceGroupName = 'motia-trace-group'\n const traceGroupStreamAdapter: MotiaStream<TraceGroup> = new RedisTraceStreamAdapter(\n traceGroupName,\n lockedData.redisClient,\n )\n\n const traceGroupStream = lockedData.createStream<TraceGroup>({\n filePath: traceGroupName,\n hidden: true,\n config: {\n name: traceGroupName,\n baseConfig: { storageType: 'custom', factory: () => traceGroupStreamAdapter },\n schema: null as never,\n },\n })()\n\n return new BaseTracerFactory(traceStream, traceGroupStream)\n}\n"],"mappings":";;;;;;AAWA,IAAa,oBAAb,MAAwD;CACtD,YACE,AAAiBA,aACjB,AAAiBC,kBACjB;EAFiB;EACA;;CAGnB,MAAc,eAAe;AAC3B,SAAO,MAAM,KAAK,iBAAiB,SAAS,UAAU;;CAGxD,MAAc,YAAY,OAAmB;EAC3C,MAAM,SAAS,MAAM,KAAK,YAAY,SAAS,MAAM,GAAG;AAExD,OAAK,MAAM,SAAS,OAClB,OAAM,KAAK,YAAY,OAAO,MAAM,IAAI,MAAM,GAAG;AAEnD,QAAM,KAAK,iBAAiB,OAAO,WAAW,MAAM,GAAG;;CAGzD,MAAM,QAAQ;EACZ,MAAM,SAAS,MAAM,KAAK,cAAc;AAExC,OAAK,MAAM,SAAS,OAClB,OAAM,KAAK,YAAY,MAAM;;CAIjC,MAAM,aAAa,SAAiB,MAAY,QAAgB;EAC9D,MAAMC,aAAyB;GAC7B,IAAI;GACJ,MAAM,KAAK,OAAO;GAClB,cAAc,KAAK,KAAK;GACxB,UAAU;IACR,gBAAgB;IAChB,aAAa;IACb,YAAY;IACb;GACD,eAAe;GACf,QAAQ;GACR,WAAW,KAAK,KAAK;GACtB;EAED,MAAM,QAAQ,YAAY,YAAY,KAAK;AAG3C,SAAO,IAAI,aAFK,IAAI,aAAa,KAAK,aAAa,KAAK,kBAAkB,YAAY,MAAM,EAE3D,YAAY,OAAO,OAAO;;CAG7D,MAAM,cAAc,SAAiB,MAAY,QAAgB;EAC/D,MAAM,gBAAgB,MAAM,KAAK,iBAAiB,IAAI,WAAW,QAAQ;AAEzE,MAAI,CAAC,cACH,QAAO,KAAK,aAAa,SAAS,MAAM,OAAO;EAGjD,MAAM,QAAQ,YAAY,eAAe,KAAK;AAG9C,SAAO,IAAI,aAFK,IAAI,aAAa,KAAK,aAAa,KAAK,kBAAkB,eAAe,MAAM,EAE9D,eAAe,OAAO,OAAO;;;AAIlE,MAAa,uBAAuB,eAA0C;AAC5E,KAAI,CAAC,WAAW,YACd,OAAM,IAAI,MACR,sGACD;CAGH,MAAM,kBAAkB;CACxB,MAAMC,qBAAyC,IAAI,wBAAwB,iBAAiB,WAAW,YAAY;CAEnH,MAAM,cAAc,WAAW,aAAoB;EACjD,UAAU;EACV,QAAQ;EACR,QAAQ;GACN,MAAM;GACN,YAAY;IAAE,aAAa;IAAU,eAAe;IAAoB;GACxE,QAAQ;GACT;EACF,CAAC,EAAE;CAEJ,MAAM,iBAAiB;CACvB,MAAMC,0BAAmD,IAAI,wBAC3D,gBACA,WAAW,YACZ;AAYD,QAAO,IAAI,kBAAkB,aAVJ,WAAW,aAAyB;EAC3D,UAAU;EACV,QAAQ;EACR,QAAQ;GACN,MAAM;GACN,YAAY;IAAE,aAAa;IAAU,eAAe;IAAyB;GAC7E,QAAQ;GACT;EACF,CAAC,EAAE,CAEuD"}
|
|
@@ -48,11 +48,17 @@ var ProcessManager = class {
|
|
|
48
48
|
}
|
|
49
49
|
kill() {
|
|
50
50
|
if (this.child) this.child.kill("SIGKILL");
|
|
51
|
-
this.child = void 0;
|
|
52
51
|
}
|
|
53
52
|
close() {
|
|
54
|
-
if (this.
|
|
55
|
-
|
|
53
|
+
if (this.child) {
|
|
54
|
+
this.child.removeAllListeners();
|
|
55
|
+
this.child.stdout?.removeAllListeners();
|
|
56
|
+
this.child.stderr?.removeAllListeners();
|
|
57
|
+
}
|
|
58
|
+
if (this.processor) {
|
|
59
|
+
this.processor.close();
|
|
60
|
+
this.processor = void 0;
|
|
61
|
+
}
|
|
56
62
|
}
|
|
57
63
|
get process() {
|
|
58
64
|
return this.child;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-manager.mjs","names":["options: ProcessManagerOptions"],"sources":["../../../src/process-communication/process-manager.ts"],"sourcesContent":["import { type ChildProcess, spawn } from 'child_process'\nimport type { Logger } from '../logger'\nimport { RpcProcessor } from '../step-handler-rpc-processor'\nimport { RpcStdinProcessor } from '../step-handler-rpc-stdin-processor'\nimport { type CommunicationType, createCommunicationConfig } from './communication-config'\nimport type { MessageCallback, RpcHandler, RpcProcessorInterface } from './rpc-processor-interface'\n\nexport interface ProcessManagerOptions {\n command: string\n args: string[]\n logger: Logger\n context?: string\n projectRoot?: string\n}\n\nexport class ProcessManager {\n private child?: ChildProcess\n private processor?: RpcProcessorInterface\n private communicationType?: CommunicationType\n\n constructor(private options: ProcessManagerOptions) {}\n\n async spawn(): Promise<ChildProcess> {\n const { command, args, logger, context = 'Process', projectRoot } = this.options\n\n // Get communication configuration\n const commConfig = createCommunicationConfig(command, projectRoot)\n this.communicationType = commConfig.type\n\n logger.debug(`[${context}] Spawning process`, {\n command,\n args,\n communicationType: this.communicationType,\n })\n\n // Spawn the process\n this.child = spawn(command, args, commConfig.spawnOptions)\n\n // Create appropriate processor based on communication type\n this.processor = this.communicationType === 'rpc' ? new RpcStdinProcessor(this.child) : new RpcProcessor(this.child)\n\n // Initialize the processor\n await this.processor.init()\n\n return this.child\n }\n\n handler<TInput, TOutput = unknown>(method: string, handler: RpcHandler<TInput, TOutput>): void {\n if (!this.processor) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n this.processor.handler(method, handler)\n }\n\n onMessage<T = unknown>(callback: MessageCallback<T>): void {\n if (!this.processor) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n this.processor.onMessage(callback)\n }\n\n onProcessClose(callback: (code: number | null) => void): void {\n if (!this.child) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n this.child.on('close', callback)\n }\n\n onProcessError(callback: (error: Error & { code?: string }) => void): void {\n if (!this.child) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n this.child.on('error', callback)\n }\n\n onStderr(callback: (data: Buffer) => void): void {\n if (!this.child) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n this.child.stderr?.on('data', callback)\n }\n\n onStdout(callback: (data: Buffer) => void): void {\n if (!this.child) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n // Only for non-RPC mode (in RPC mode, stdout is used for communication)\n if (this.communicationType !== 'rpc') {\n this.child.stdout?.on('data', callback)\n }\n }\n\n kill(): void {\n if (this.child) {\n this.child.kill('SIGKILL')\n }\n
|
|
1
|
+
{"version":3,"file":"process-manager.mjs","names":["options: ProcessManagerOptions"],"sources":["../../../src/process-communication/process-manager.ts"],"sourcesContent":["import { type ChildProcess, spawn } from 'child_process'\nimport type { Logger } from '../logger'\nimport { RpcProcessor } from '../step-handler-rpc-processor'\nimport { RpcStdinProcessor } from '../step-handler-rpc-stdin-processor'\nimport { type CommunicationType, createCommunicationConfig } from './communication-config'\nimport type { MessageCallback, RpcHandler, RpcProcessorInterface } from './rpc-processor-interface'\n\nexport interface ProcessManagerOptions {\n command: string\n args: string[]\n logger: Logger\n context?: string\n projectRoot?: string\n}\n\nexport class ProcessManager {\n private child?: ChildProcess\n private processor?: RpcProcessorInterface\n private communicationType?: CommunicationType\n\n constructor(private options: ProcessManagerOptions) {}\n\n async spawn(): Promise<ChildProcess> {\n const { command, args, logger, context = 'Process', projectRoot } = this.options\n\n // Get communication configuration\n const commConfig = createCommunicationConfig(command, projectRoot)\n this.communicationType = commConfig.type\n\n logger.debug(`[${context}] Spawning process`, {\n command,\n args,\n communicationType: this.communicationType,\n })\n\n // Spawn the process\n this.child = spawn(command, args, commConfig.spawnOptions)\n\n // Create appropriate processor based on communication type\n this.processor = this.communicationType === 'rpc' ? new RpcStdinProcessor(this.child) : new RpcProcessor(this.child)\n\n // Initialize the processor\n await this.processor.init()\n\n return this.child\n }\n\n handler<TInput, TOutput = unknown>(method: string, handler: RpcHandler<TInput, TOutput>): void {\n if (!this.processor) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n this.processor.handler(method, handler)\n }\n\n onMessage<T = unknown>(callback: MessageCallback<T>): void {\n if (!this.processor) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n this.processor.onMessage(callback)\n }\n\n onProcessClose(callback: (code: number | null) => void): void {\n if (!this.child) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n this.child.on('close', callback)\n }\n\n onProcessError(callback: (error: Error & { code?: string }) => void): void {\n if (!this.child) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n this.child.on('error', callback)\n }\n\n onStderr(callback: (data: Buffer) => void): void {\n if (!this.child) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n this.child.stderr?.on('data', callback)\n }\n\n onStdout(callback: (data: Buffer) => void): void {\n if (!this.child) {\n throw new Error('Process not spawned yet. Call spawn() first.')\n }\n // Only for non-RPC mode (in RPC mode, stdout is used for communication)\n if (this.communicationType !== 'rpc') {\n this.child.stdout?.on('data', callback)\n }\n }\n\n kill(): void {\n if (this.child) {\n this.child.kill('SIGKILL')\n }\n }\n\n close(): void {\n if (this.child) {\n this.child.removeAllListeners()\n this.child.stdout?.removeAllListeners()\n this.child.stderr?.removeAllListeners()\n }\n if (this.processor) {\n this.processor.close()\n this.processor = undefined\n }\n }\n\n get process(): ChildProcess | undefined {\n return this.child\n }\n\n get commType(): CommunicationType | undefined {\n return this.communicationType\n }\n}\n"],"mappings":";;;;;;AAeA,IAAa,iBAAb,MAA4B;CAK1B,YAAY,AAAQA,SAAgC;EAAhC;;CAEpB,MAAM,QAA+B;EACnC,MAAM,EAAE,SAAS,MAAM,QAAQ,UAAU,WAAW,gBAAgB,KAAK;EAGzE,MAAM,aAAa,0BAA0B,SAAS,YAAY;AAClE,OAAK,oBAAoB,WAAW;AAEpC,SAAO,MAAM,IAAI,QAAQ,qBAAqB;GAC5C;GACA;GACA,mBAAmB,KAAK;GACzB,CAAC;AAGF,OAAK,QAAQ,MAAM,SAAS,MAAM,WAAW,aAAa;AAG1D,OAAK,YAAY,KAAK,sBAAsB,QAAQ,IAAI,kBAAkB,KAAK,MAAM,GAAG,IAAI,aAAa,KAAK,MAAM;AAGpH,QAAM,KAAK,UAAU,MAAM;AAE3B,SAAO,KAAK;;CAGd,QAAmC,QAAgB,SAA4C;AAC7F,MAAI,CAAC,KAAK,UACR,OAAM,IAAI,MAAM,+CAA+C;AAEjE,OAAK,UAAU,QAAQ,QAAQ,QAAQ;;CAGzC,UAAuB,UAAoC;AACzD,MAAI,CAAC,KAAK,UACR,OAAM,IAAI,MAAM,+CAA+C;AAEjE,OAAK,UAAU,UAAU,SAAS;;CAGpC,eAAe,UAA+C;AAC5D,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,+CAA+C;AAEjE,OAAK,MAAM,GAAG,SAAS,SAAS;;CAGlC,eAAe,UAA4D;AACzE,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,+CAA+C;AAEjE,OAAK,MAAM,GAAG,SAAS,SAAS;;CAGlC,SAAS,UAAwC;AAC/C,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,+CAA+C;AAEjE,OAAK,MAAM,QAAQ,GAAG,QAAQ,SAAS;;CAGzC,SAAS,UAAwC;AAC/C,MAAI,CAAC,KAAK,MACR,OAAM,IAAI,MAAM,+CAA+C;AAGjE,MAAI,KAAK,sBAAsB,MAC7B,MAAK,MAAM,QAAQ,GAAG,QAAQ,SAAS;;CAI3C,OAAa;AACX,MAAI,KAAK,MACP,MAAK,MAAM,KAAK,UAAU;;CAI9B,QAAc;AACZ,MAAI,KAAK,OAAO;AACd,QAAK,MAAM,oBAAoB;AAC/B,QAAK,MAAM,QAAQ,oBAAoB;AACvC,QAAK,MAAM,QAAQ,oBAAoB;;AAEzC,MAAI,KAAK,WAAW;AAClB,QAAK,UAAU,OAAO;AACtB,QAAK,YAAY;;;CAIrB,IAAI,UAAoC;AACtC,SAAO,KAAK;;CAGd,IAAI,WAA0C;AAC5C,SAAO,KAAK"}
|
|
@@ -24,9 +24,9 @@ def get_can_access(config):
|
|
|
24
24
|
async def run_python_module(file_path: str, payload: dict) -> None:
|
|
25
25
|
try:
|
|
26
26
|
path = Path(file_path).resolve()
|
|
27
|
-
steps_dir = next((p for p in path.parents if p.name
|
|
27
|
+
steps_dir = next((p for p in path.parents if p.name in ("src", "steps")), None)
|
|
28
28
|
if steps_dir is None:
|
|
29
|
-
raise RuntimeError("Could not find 'steps' directory in path")
|
|
29
|
+
raise RuntimeError("Could not find 'src' or 'steps' directory in path")
|
|
30
30
|
|
|
31
31
|
project_root = steps_dir.parent
|
|
32
32
|
project_parent = project_root.parent
|
|
@@ -23,9 +23,9 @@ def sendMessage(text):
|
|
|
23
23
|
async def run_python_module(file_path: str) -> None:
|
|
24
24
|
try:
|
|
25
25
|
path = Path(file_path).resolve()
|
|
26
|
-
steps_dir = next((p for p in path.parents if p.name
|
|
26
|
+
steps_dir = next((p for p in path.parents if p.name in ("src", "steps")), None)
|
|
27
27
|
if steps_dir is None:
|
|
28
|
-
raise RuntimeError("Could not find 'steps' directory in path")
|
|
28
|
+
raise RuntimeError("Could not find 'src' or 'steps' directory in path")
|
|
29
29
|
|
|
30
30
|
project_root = steps_dir.parent
|
|
31
31
|
project_parent = project_root.parent
|
|
@@ -24,9 +24,9 @@ async def run_python_module(file_path: str, rpc: RpcSender, args: Dict) -> None:
|
|
|
24
24
|
"""Execute a Python module with the given arguments"""
|
|
25
25
|
try:
|
|
26
26
|
path = Path(file_path).resolve()
|
|
27
|
-
steps_dir = next((p for p in path.parents if p.name
|
|
27
|
+
steps_dir = next((p for p in path.parents if p.name in ("src", "steps")), None)
|
|
28
28
|
if steps_dir is None:
|
|
29
|
-
raise RuntimeError("Could not find 'steps' directory in path")
|
|
29
|
+
raise RuntimeError("Could not find 'src' or 'steps' directory in path")
|
|
30
30
|
|
|
31
31
|
project_root = steps_dir.parent
|
|
32
32
|
project_parent = project_root.parent
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { globalLogger } from "./logger.mjs";
|
|
2
2
|
import { getRoom, sendAccessDenied, sendError } from "./socket-server/helpers.mjs";
|
|
3
|
-
import { WebSocketServer } from "ws";
|
|
3
|
+
import { WebSocket, WebSocketServer } from "ws";
|
|
4
4
|
|
|
5
5
|
//#region src/socket-server.ts
|
|
6
6
|
const AUTH_ERROR_CODE = 401;
|
|
@@ -37,9 +37,9 @@ const createSocketServer = ({ server, onJoin, onJoinGroup, authenticate, authori
|
|
|
37
37
|
};
|
|
38
38
|
socketServer.on("connection", async (socket, request) => {
|
|
39
39
|
authContexts.set(socket, request.authContext);
|
|
40
|
-
subscriptions.set(socket, /* @__PURE__ */ new
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
subscriptions.set(socket, /* @__PURE__ */ new Map());
|
|
41
|
+
let messageQueue = Promise.resolve();
|
|
42
|
+
const processMessage = async (message) => {
|
|
43
43
|
if (message.type === "join") {
|
|
44
44
|
if (!await isAuthorized(socket, message.data)) {
|
|
45
45
|
sendAccessDenied(socket, message.data);
|
|
@@ -78,15 +78,30 @@ const createSocketServer = ({ server, onJoin, onJoinGroup, authenticate, authori
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
rooms[room].set(message.data.subscriptionId, socket);
|
|
81
|
-
subscriptions.get(socket)?.
|
|
81
|
+
subscriptions.get(socket)?.set(message.data.subscriptionId, room);
|
|
82
82
|
} else if (message.type === "leave") {
|
|
83
|
+
if (!message.data.subscriptionId) {
|
|
84
|
+
globalLogger.error("[Socket Server] Subscription ID is required for leave message");
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
83
87
|
const room = getRoom(message.data);
|
|
84
|
-
if (rooms[room])
|
|
88
|
+
if (rooms[room]) {
|
|
89
|
+
rooms[room].delete(message.data.subscriptionId);
|
|
90
|
+
if (rooms[room].size === 0) delete rooms[room];
|
|
91
|
+
}
|
|
92
|
+
subscriptions.get(socket)?.delete(message.data.subscriptionId);
|
|
85
93
|
}
|
|
94
|
+
};
|
|
95
|
+
socket.on("message", (payload) => {
|
|
96
|
+
const message = JSON.parse(payload.toString());
|
|
97
|
+
messageQueue = messageQueue.then(() => processMessage(message)).catch((error) => {
|
|
98
|
+
globalLogger.error("[Socket Server] Error processing message", error);
|
|
99
|
+
});
|
|
86
100
|
});
|
|
87
101
|
socket.on("close", () => {
|
|
88
|
-
subscriptions.get(socket)?.forEach((
|
|
102
|
+
subscriptions.get(socket)?.forEach((room, subscriptionId) => {
|
|
89
103
|
rooms[room]?.delete(subscriptionId);
|
|
104
|
+
if (rooms[room]?.size === 0) delete rooms[room];
|
|
90
105
|
});
|
|
91
106
|
subscriptions.delete(socket);
|
|
92
107
|
authContexts.delete(socket);
|
|
@@ -102,18 +117,21 @@ const createSocketServer = ({ server, onJoin, onJoinGroup, authenticate, authori
|
|
|
102
117
|
timestamp: Date.now(),
|
|
103
118
|
...message
|
|
104
119
|
});
|
|
105
|
-
|
|
106
|
-
socket.
|
|
107
|
-
|
|
120
|
+
const safeSend = (socket) => {
|
|
121
|
+
if (socket.readyState === WebSocket.OPEN) try {
|
|
122
|
+
socket.send(eventMessage);
|
|
123
|
+
} catch (error) {
|
|
124
|
+
globalLogger.debug("[Socket Server] Failed to send message to socket", error);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
if (rooms[groupRoom]) rooms[groupRoom].forEach(safeSend);
|
|
108
128
|
if (id) {
|
|
109
129
|
const itemRoom = getRoom({
|
|
110
130
|
groupId,
|
|
111
131
|
streamName,
|
|
112
132
|
id
|
|
113
133
|
});
|
|
114
|
-
if (rooms[itemRoom]) rooms[itemRoom].forEach(
|
|
115
|
-
socket.send(eventMessage);
|
|
116
|
-
});
|
|
134
|
+
if (rooms[itemRoom]) rooms[itemRoom].forEach(safeSend);
|
|
117
135
|
}
|
|
118
136
|
};
|
|
119
137
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket-server.mjs","names":["authRequest: StreamAuthRequest","rooms: Record<string, Map<string, WebSocket>>","subscriptions: Map<WebSocket,
|
|
1
|
+
{"version":3,"file":"socket-server.mjs","names":["authRequest: StreamAuthRequest","rooms: Record<string, Map<string, WebSocket>>","subscriptions: Map<WebSocket, Map<string, string>>","authContexts: Map<WebSocket, unknown>","messageQueue: Promise<void>","resultMessage: EventMessage<typeof item>","resultMessage: EventMessage<typeof items>","message: Message"],"sources":["../../src/socket-server.ts"],"sourcesContent":["import type { Server } from 'http'\nimport { WebSocket, WebSocketServer } from 'ws'\nimport { globalLogger } from './logger'\nimport {\n type BaseMessage,\n type EventMessage,\n getRoom,\n type JoinMessage,\n sendAccessDenied,\n sendError,\n} from './socket-server/helpers'\nimport type { StreamAuthRequest } from './types/app-config-types'\n\ntype Message = { type: 'join' | 'leave'; data: JoinMessage }\n\ntype Props = {\n server: Server\n onJoin: <TData>(streamName: string, groupId: string, id: string) => Promise<TData>\n onJoinGroup: <TData>(streamName: string, groupId: string) => Promise<TData[] | undefined>\n authenticate?: (request: StreamAuthRequest) => Promise<unknown | null> | unknown | null\n authorize?: (\n subscription: { streamName: string; groupId: string; id?: string },\n authContext?: unknown,\n ) => Promise<boolean> | boolean\n}\n\nconst AUTH_ERROR_CODE = 401\nexport const createSocketServer = ({ server, onJoin, onJoinGroup, authenticate, authorize }: Props) => {\n const socketServer = new WebSocketServer({\n server,\n verifyClient: async (info, callback) => {\n if (authenticate) {\n try {\n const authRequest: StreamAuthRequest = {\n headers: info.req.headers,\n url: info.req.url,\n }\n info.req.authContext = await authenticate(authRequest)\n callback(true)\n } catch {\n globalLogger.debug('[Socket Server] Authentication failed')\n callback(false, AUTH_ERROR_CODE, 'Authentication failed')\n }\n } else {\n callback(true)\n }\n },\n })\n const rooms: Record<string, Map<string, WebSocket>> = {}\n const subscriptions: Map<WebSocket, Map<string, string>> = new Map()\n const authContexts: Map<WebSocket, unknown> = new Map()\n\n const isAuthorized = async (socket: WebSocket, data: BaseMessage): Promise<boolean> => {\n if (!authorize) {\n return true\n }\n\n try {\n const authContext = authContexts.get(socket)\n const result = await authorize(data, authContext)\n return result !== false\n } catch (error) {\n sendError(socket, data, error as Error)\n globalLogger.error('[Socket Server] Failed to authorize stream subscription')\n return false\n }\n }\n\n socketServer.on('connection', async (socket, request) => {\n authContexts.set(socket, request.authContext)\n\n subscriptions.set(socket, new Map())\n\n // Message queue to ensure messages are processed in order\n // This prevents race conditions where async join handlers allow leave to overtake join\n let messageQueue: Promise<void> = Promise.resolve()\n\n const processMessage = async (message: Message) => {\n if (message.type === 'join') {\n const authorized = await isAuthorized(socket, message.data)\n\n if (!authorized) {\n sendAccessDenied(socket, message.data)\n return\n }\n\n const room = getRoom(message.data)\n\n if (!rooms[room]) {\n rooms[room] = new Map()\n }\n\n if (message.data.id) {\n const item = await onJoin(message.data.streamName, message.data.groupId, message.data.id)\n\n if (item) {\n const resultMessage: EventMessage<typeof item> = {\n timestamp: Date.now(),\n streamName: message.data.streamName,\n groupId: message.data.groupId,\n id: message.data.id,\n event: { type: 'sync', data: item },\n }\n\n socket.send(JSON.stringify(resultMessage))\n }\n } else {\n const items = await onJoinGroup(message.data.streamName, message.data.groupId)\n\n if (items) {\n const resultMessage: EventMessage<typeof items> = {\n timestamp: Date.now(),\n streamName: message.data.streamName,\n groupId: message.data.groupId,\n event: { type: 'sync', data: items },\n }\n\n socket.send(JSON.stringify(resultMessage))\n }\n }\n\n rooms[room].set(message.data.subscriptionId, socket)\n subscriptions.get(socket)?.set(message.data.subscriptionId, room)\n } else if (message.type === 'leave') {\n if (!message.data.subscriptionId) {\n globalLogger.error('[Socket Server] Subscription ID is required for leave message')\n return\n }\n\n const room = getRoom(message.data)\n if (rooms[room]) {\n rooms[room].delete(message.data.subscriptionId)\n if (rooms[room].size === 0) {\n delete rooms[room]\n }\n }\n\n subscriptions.get(socket)?.delete(message.data.subscriptionId)\n }\n }\n\n socket.on('message', (payload: Buffer) => {\n const message: Message = JSON.parse(payload.toString())\n // Chain messages to ensure they are processed in order\n messageQueue = messageQueue\n .then(() => processMessage(message))\n .catch((error) => {\n globalLogger.error('[Socket Server] Error processing message', error)\n })\n })\n\n socket.on('close', () => {\n subscriptions.get(socket)?.forEach((room, subscriptionId) => {\n rooms[room]?.delete(subscriptionId)\n\n if (rooms[room]?.size === 0) {\n delete rooms[room]\n }\n })\n subscriptions.delete(socket)\n authContexts.delete(socket)\n })\n })\n\n const pushEvent = <TData>(message: Omit<EventMessage<TData>, 'timestamp'>) => {\n const { groupId, streamName, id } = message\n const groupRoom = getRoom({ streamName, groupId })\n const eventMessage = JSON.stringify({ timestamp: Date.now(), ...message })\n\n const safeSend = (socket: WebSocket) => {\n if (socket.readyState === WebSocket.OPEN) {\n try {\n socket.send(eventMessage)\n } catch (error) {\n globalLogger.debug('[Socket Server] Failed to send message to socket', error)\n }\n }\n }\n\n if (rooms[groupRoom]) {\n rooms[groupRoom].forEach(safeSend)\n }\n\n if (id) {\n const itemRoom = getRoom({ groupId, streamName, id })\n\n if (rooms[itemRoom]) {\n rooms[itemRoom].forEach(safeSend)\n }\n }\n }\n\n return { pushEvent, socketServer }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-handler-rpc-processor.mjs","names":["child: ChildProcess"],"sources":["../../src/step-handler-rpc-processor.ts"],"sourcesContent":["import type { ChildProcess } from 'child_process'\nimport type {\n MessageCallback,\n RpcHandler,\n RpcProcessorInterface,\n} from './process-communication/rpc-processor-interface'\n\nexport type RpcMessage = {\n type: 'rpc_request'\n id: string | undefined\n method: string\n args: unknown\n}\n\nexport class RpcProcessor implements RpcProcessorInterface {\n private handlers: Record<string, RpcHandler<any, any>> = {}\n\n private messageCallback?: MessageCallback<any>\n private isClosed = false\n\n constructor(private child: ChildProcess) {}\n\n handler<TInput, TOutput = unknown>(method: string, handler: RpcHandler<TInput, TOutput>) {\n this.handlers[method] = handler\n }\n\n onMessage<T = unknown>(callback: MessageCallback<T>): void {\n this.messageCallback = callback\n }\n\n async handle(method: string, input: unknown) {\n const handler = this.handlers[method]\n if (!handler) {\n throw new Error(`Handler for method ${method} not found`)\n }\n return handler(input)\n }\n\n private response(id: string | undefined, result: unknown, error: unknown) {\n if (id && !this.isClosed && this.child.send && this.child.connected) {\n const responseMessage = {\n type: 'rpc_response',\n id,\n result: error ? undefined : result,\n error: error ? String(error) : undefined,\n }\n this.child.send(responseMessage)\n }\n }\n\n async init() {\n this.child.on('message', (msg: any) => {\n // Call generic message callback if registered\n if (this.messageCallback) {\n this.messageCallback(msg)\n }\n\n // Handle RPC requests specifically\n if (msg && msg.type === 'rpc_request') {\n const { id, method, args } = msg as RpcMessage\n this.handle(method, args)\n .then((result) => this.response(id, result, null))\n .catch((error) => this.response(id, null, error))\n }\n })\n\n this.child.on('exit', () => {\n this.isClosed = true\n })\n this.child.on('close', () => {\n this.isClosed = true\n })\n this.child.on('disconnect', () => {\n this.isClosed = true\n })\n }\n\n close() {\n this.isClosed = true\n this.messageCallback = undefined\n }\n}\n"],"mappings":";AAcA,IAAa,eAAb,MAA2D;CAMzD,YAAY,AAAQA,OAAqB;EAArB;kBALqC,EAAE;kBAGxC;;CAInB,QAAmC,QAAgB,SAAsC;AACvF,OAAK,SAAS,UAAU;;CAG1B,UAAuB,UAAoC;AACzD,OAAK,kBAAkB;;CAGzB,MAAM,OAAO,QAAgB,OAAgB;EAC3C,MAAM,UAAU,KAAK,SAAS;AAC9B,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,sBAAsB,OAAO,YAAY;AAE3D,SAAO,QAAQ,MAAM;;CAGvB,AAAQ,SAAS,IAAwB,QAAiB,OAAgB;AACxE,MAAI,MAAM,CAAC,KAAK,YAAY,KAAK,MAAM,QAAQ,KAAK,MAAM,WAAW;GACnE,MAAM,kBAAkB;IACtB,MAAM;IACN;IACA,QAAQ,QAAQ,SAAY;IAC5B,OAAO,QAAQ,OAAO,MAAM,GAAG;IAChC;AACD,QAAK,MAAM,KAAK,gBAAgB;;;CAIpC,MAAM,OAAO;AACX,OAAK,MAAM,GAAG,YAAY,QAAa;AAErC,OAAI,KAAK,gBACP,MAAK,gBAAgB,IAAI;AAI3B,OAAI,OAAO,IAAI,SAAS,eAAe;IACrC,MAAM,EAAE,IAAI,QAAQ,SAAS;AAC7B,SAAK,OAAO,QAAQ,KAAK,CACtB,MAAM,WAAW,KAAK,SAAS,IAAI,QAAQ,KAAK,CAAC,CACjD,OAAO,UAAU,KAAK,SAAS,IAAI,MAAM,MAAM,CAAC;;IAErD;AAEF,OAAK,MAAM,GAAG,cAAc;AAC1B,QAAK,WAAW;IAChB;AACF,OAAK,MAAM,GAAG,eAAe;AAC3B,QAAK,WAAW;IAChB;AACF,OAAK,MAAM,GAAG,oBAAoB;AAChC,QAAK,WAAW;IAChB;;CAGJ,QAAQ;AACN,OAAK,WAAW;AAChB,OAAK,kBAAkB"}
|
|
1
|
+
{"version":3,"file":"step-handler-rpc-processor.mjs","names":["child: ChildProcess"],"sources":["../../src/step-handler-rpc-processor.ts"],"sourcesContent":["import type { ChildProcess } from 'child_process'\nimport type {\n MessageCallback,\n RpcHandler,\n RpcProcessorInterface,\n} from './process-communication/rpc-processor-interface'\n\nexport type RpcMessage = {\n type: 'rpc_request'\n id: string | undefined\n method: string\n args: unknown\n}\n\nexport class RpcProcessor implements RpcProcessorInterface {\n private handlers: Record<string, RpcHandler<any, any>> = {}\n\n private messageCallback?: MessageCallback<any>\n private isClosed = false\n\n constructor(private child: ChildProcess) {}\n\n handler<TInput, TOutput = unknown>(method: string, handler: RpcHandler<TInput, TOutput>) {\n this.handlers[method] = handler\n }\n\n onMessage<T = unknown>(callback: MessageCallback<T>): void {\n this.messageCallback = callback\n }\n\n async handle(method: string, input: unknown) {\n const handler = this.handlers[method]\n if (!handler) {\n throw new Error(`Handler for method ${method} not found`)\n }\n return handler(input)\n }\n\n private response(id: string | undefined, result: unknown, error: unknown) {\n if (id && !this.isClosed && this.child.send && this.child.connected) {\n const responseMessage = {\n type: 'rpc_response',\n id,\n result: error ? undefined : result,\n error: error ? String(error) : undefined,\n }\n this.child.send(responseMessage)\n }\n }\n\n async init() {\n this.child.on('message', (msg: any) => {\n // Call generic message callback if registered\n if (this.messageCallback) {\n this.messageCallback(msg)\n }\n\n // Handle RPC requests specifically\n if (msg && msg.type === 'rpc_request') {\n const { id, method, args } = msg as RpcMessage\n this.handle(method, args)\n .then((result) => this.response(id, result, null))\n .catch((error) => this.response(id, null, error))\n }\n })\n\n this.child.on('exit', () => {\n this.isClosed = true\n })\n this.child.on('close', () => {\n this.isClosed = true\n })\n this.child.on('disconnect', () => {\n this.isClosed = true\n })\n }\n\n close() {\n this.isClosed = true\n this.messageCallback = undefined\n this.handlers = {}\n }\n}\n"],"mappings":";AAcA,IAAa,eAAb,MAA2D;CAMzD,YAAY,AAAQA,OAAqB;EAArB;kBALqC,EAAE;kBAGxC;;CAInB,QAAmC,QAAgB,SAAsC;AACvF,OAAK,SAAS,UAAU;;CAG1B,UAAuB,UAAoC;AACzD,OAAK,kBAAkB;;CAGzB,MAAM,OAAO,QAAgB,OAAgB;EAC3C,MAAM,UAAU,KAAK,SAAS;AAC9B,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,sBAAsB,OAAO,YAAY;AAE3D,SAAO,QAAQ,MAAM;;CAGvB,AAAQ,SAAS,IAAwB,QAAiB,OAAgB;AACxE,MAAI,MAAM,CAAC,KAAK,YAAY,KAAK,MAAM,QAAQ,KAAK,MAAM,WAAW;GACnE,MAAM,kBAAkB;IACtB,MAAM;IACN;IACA,QAAQ,QAAQ,SAAY;IAC5B,OAAO,QAAQ,OAAO,MAAM,GAAG;IAChC;AACD,QAAK,MAAM,KAAK,gBAAgB;;;CAIpC,MAAM,OAAO;AACX,OAAK,MAAM,GAAG,YAAY,QAAa;AAErC,OAAI,KAAK,gBACP,MAAK,gBAAgB,IAAI;AAI3B,OAAI,OAAO,IAAI,SAAS,eAAe;IACrC,MAAM,EAAE,IAAI,QAAQ,SAAS;AAC7B,SAAK,OAAO,QAAQ,KAAK,CACtB,MAAM,WAAW,KAAK,SAAS,IAAI,QAAQ,KAAK,CAAC,CACjD,OAAO,UAAU,KAAK,SAAS,IAAI,MAAM,MAAM,CAAC;;IAErD;AAEF,OAAK,MAAM,GAAG,cAAc;AAC1B,QAAK,WAAW;IAChB;AACF,OAAK,MAAM,GAAG,eAAe;AAC3B,QAAK,WAAW;IAChB;AACF,OAAK,MAAM,GAAG,oBAAoB;AAChC,QAAK,WAAW;IAChB;;CAGJ,QAAQ;AACN,OAAK,WAAW;AAChB,OAAK,kBAAkB;AACvB,OAAK,WAAW,EAAE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-handler-rpc-stdin-processor.mjs","names":["child: ChildProcess"],"sources":["../../src/step-handler-rpc-stdin-processor.ts"],"sourcesContent":["import type { ChildProcess } from 'child_process'\nimport readline from 'readline'\nimport type {\n MessageCallback,\n RpcHandler,\n RpcProcessorInterface,\n} from './process-communication/rpc-processor-interface'\n\nexport type RpcMessage = {\n type: 'rpc_request'\n id: string | undefined\n method: string\n args: unknown\n}\n\nexport class RpcStdinProcessor implements RpcProcessorInterface {\n private handlers: Record<string, RpcHandler<any, any>> = {}\n\n private messageCallback?: MessageCallback<any>\n private isClosed = false\n private rl?: readline.Interface\n\n constructor(private child: ChildProcess) {}\n\n handler<TInput, TOutput = unknown>(method: string, handler: RpcHandler<TInput, TOutput>) {\n this.handlers[method] = handler\n }\n\n onMessage<T = unknown>(callback: MessageCallback<T>): void {\n this.messageCallback = callback\n }\n\n async handle(method: string, input: unknown) {\n const handler = this.handlers[method]\n if (!handler) {\n throw new Error(`Handler for method ${method} not found`)\n }\n return handler(input)\n }\n\n private response(id: string | undefined, result: unknown, error: unknown) {\n if (id && !this.isClosed && this.child.stdin && !this.child.killed) {\n const responseMessage = {\n type: 'rpc_response',\n id,\n result: error ? undefined : result,\n error: error ? String(error) : undefined,\n }\n const messageStr = JSON.stringify(responseMessage)\n this.child.stdin.write(messageStr + '\\n')\n }\n }\n\n async init() {\n if (this.child.stdout) {\n this.rl = readline.createInterface({\n input: this.child.stdout,\n crlfDelay: Infinity,\n })\n\n this.rl.on('line', (line) => {\n try {\n const msg = JSON.parse(line.trim())\n\n // Call generic message callback if registered\n if (this.messageCallback) {\n this.messageCallback(msg)\n }\n\n // Handle RPC requests specifically\n if (msg && msg.type === 'rpc_request') {\n const { id, method, args } = msg as RpcMessage\n this.handle(method, args)\n .then((result) => this.response(id, result, null))\n .catch((error) => this.response(id, null, error))\n }\n } catch (error) {\n console.error('Failed to parse RPC message:', error, 'Raw line:', line)\n }\n })\n\n this.rl.on('close', () => {\n this.isClosed = true\n })\n }\n\n this.child.on('exit', () => {\n this.isClosed = true\n })\n this.child.on('close', () => {\n this.isClosed = true\n })\n }\n\n close() {\n this.isClosed = true\n this.messageCallback = undefined\n if (this.rl) {\n this.rl.removeAllListeners()\n this.rl.close()\n }\n }\n}\n"],"mappings":";;;AAeA,IAAa,oBAAb,MAAgE;CAO9D,YAAY,AAAQA,OAAqB;EAArB;kBANqC,EAAE;kBAGxC;;CAKnB,QAAmC,QAAgB,SAAsC;AACvF,OAAK,SAAS,UAAU;;CAG1B,UAAuB,UAAoC;AACzD,OAAK,kBAAkB;;CAGzB,MAAM,OAAO,QAAgB,OAAgB;EAC3C,MAAM,UAAU,KAAK,SAAS;AAC9B,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,sBAAsB,OAAO,YAAY;AAE3D,SAAO,QAAQ,MAAM;;CAGvB,AAAQ,SAAS,IAAwB,QAAiB,OAAgB;AACxE,MAAI,MAAM,CAAC,KAAK,YAAY,KAAK,MAAM,SAAS,CAAC,KAAK,MAAM,QAAQ;GAClE,MAAM,kBAAkB;IACtB,MAAM;IACN;IACA,QAAQ,QAAQ,SAAY;IAC5B,OAAO,QAAQ,OAAO,MAAM,GAAG;IAChC;GACD,MAAM,aAAa,KAAK,UAAU,gBAAgB;AAClD,QAAK,MAAM,MAAM,MAAM,aAAa,KAAK;;;CAI7C,MAAM,OAAO;AACX,MAAI,KAAK,MAAM,QAAQ;AACrB,QAAK,KAAK,SAAS,gBAAgB;IACjC,OAAO,KAAK,MAAM;IAClB,WAAW;IACZ,CAAC;AAEF,QAAK,GAAG,GAAG,SAAS,SAAS;AAC3B,QAAI;KACF,MAAM,MAAM,KAAK,MAAM,KAAK,MAAM,CAAC;AAGnC,SAAI,KAAK,gBACP,MAAK,gBAAgB,IAAI;AAI3B,SAAI,OAAO,IAAI,SAAS,eAAe;MACrC,MAAM,EAAE,IAAI,QAAQ,SAAS;AAC7B,WAAK,OAAO,QAAQ,KAAK,CACtB,MAAM,WAAW,KAAK,SAAS,IAAI,QAAQ,KAAK,CAAC,CACjD,OAAO,UAAU,KAAK,SAAS,IAAI,MAAM,MAAM,CAAC;;aAE9C,OAAO;AACd,aAAQ,MAAM,gCAAgC,OAAO,aAAa,KAAK;;KAEzE;AAEF,QAAK,GAAG,GAAG,eAAe;AACxB,SAAK,WAAW;KAChB;;AAGJ,OAAK,MAAM,GAAG,cAAc;AAC1B,QAAK,WAAW;IAChB;AACF,OAAK,MAAM,GAAG,eAAe;AAC3B,QAAK,WAAW;IAChB;;CAGJ,QAAQ;AACN,OAAK,WAAW;AAChB,OAAK,kBAAkB;AACvB,MAAI,KAAK,IAAI;AACX,QAAK,GAAG,oBAAoB;AAC5B,QAAK,GAAG,OAAO"}
|
|
1
|
+
{"version":3,"file":"step-handler-rpc-stdin-processor.mjs","names":["child: ChildProcess"],"sources":["../../src/step-handler-rpc-stdin-processor.ts"],"sourcesContent":["import type { ChildProcess } from 'child_process'\nimport readline from 'readline'\nimport type {\n MessageCallback,\n RpcHandler,\n RpcProcessorInterface,\n} from './process-communication/rpc-processor-interface'\n\nexport type RpcMessage = {\n type: 'rpc_request'\n id: string | undefined\n method: string\n args: unknown\n}\n\nexport class RpcStdinProcessor implements RpcProcessorInterface {\n private handlers: Record<string, RpcHandler<any, any>> = {}\n\n private messageCallback?: MessageCallback<any>\n private isClosed = false\n private rl?: readline.Interface\n\n constructor(private child: ChildProcess) {}\n\n handler<TInput, TOutput = unknown>(method: string, handler: RpcHandler<TInput, TOutput>) {\n this.handlers[method] = handler\n }\n\n onMessage<T = unknown>(callback: MessageCallback<T>): void {\n this.messageCallback = callback\n }\n\n async handle(method: string, input: unknown) {\n const handler = this.handlers[method]\n if (!handler) {\n throw new Error(`Handler for method ${method} not found`)\n }\n return handler(input)\n }\n\n private response(id: string | undefined, result: unknown, error: unknown) {\n if (id && !this.isClosed && this.child.stdin && !this.child.killed) {\n const responseMessage = {\n type: 'rpc_response',\n id,\n result: error ? undefined : result,\n error: error ? String(error) : undefined,\n }\n const messageStr = JSON.stringify(responseMessage)\n this.child.stdin.write(messageStr + '\\n')\n }\n }\n\n async init() {\n if (this.child.stdout) {\n this.rl = readline.createInterface({\n input: this.child.stdout,\n crlfDelay: Infinity,\n })\n\n this.rl.on('line', (line) => {\n try {\n const msg = JSON.parse(line.trim())\n\n // Call generic message callback if registered\n if (this.messageCallback) {\n this.messageCallback(msg)\n }\n\n // Handle RPC requests specifically\n if (msg && msg.type === 'rpc_request') {\n const { id, method, args } = msg as RpcMessage\n this.handle(method, args)\n .then((result) => this.response(id, result, null))\n .catch((error) => this.response(id, null, error))\n }\n } catch (error) {\n console.error('Failed to parse RPC message:', error, 'Raw line:', line)\n }\n })\n\n this.rl.on('close', () => {\n this.isClosed = true\n })\n }\n\n this.child.on('exit', () => {\n this.isClosed = true\n })\n this.child.on('close', () => {\n this.isClosed = true\n })\n }\n\n close() {\n this.isClosed = true\n this.messageCallback = undefined\n this.handlers = {}\n if (this.rl) {\n this.rl.removeAllListeners()\n this.rl.close()\n }\n }\n}\n"],"mappings":";;;AAeA,IAAa,oBAAb,MAAgE;CAO9D,YAAY,AAAQA,OAAqB;EAArB;kBANqC,EAAE;kBAGxC;;CAKnB,QAAmC,QAAgB,SAAsC;AACvF,OAAK,SAAS,UAAU;;CAG1B,UAAuB,UAAoC;AACzD,OAAK,kBAAkB;;CAGzB,MAAM,OAAO,QAAgB,OAAgB;EAC3C,MAAM,UAAU,KAAK,SAAS;AAC9B,MAAI,CAAC,QACH,OAAM,IAAI,MAAM,sBAAsB,OAAO,YAAY;AAE3D,SAAO,QAAQ,MAAM;;CAGvB,AAAQ,SAAS,IAAwB,QAAiB,OAAgB;AACxE,MAAI,MAAM,CAAC,KAAK,YAAY,KAAK,MAAM,SAAS,CAAC,KAAK,MAAM,QAAQ;GAClE,MAAM,kBAAkB;IACtB,MAAM;IACN;IACA,QAAQ,QAAQ,SAAY;IAC5B,OAAO,QAAQ,OAAO,MAAM,GAAG;IAChC;GACD,MAAM,aAAa,KAAK,UAAU,gBAAgB;AAClD,QAAK,MAAM,MAAM,MAAM,aAAa,KAAK;;;CAI7C,MAAM,OAAO;AACX,MAAI,KAAK,MAAM,QAAQ;AACrB,QAAK,KAAK,SAAS,gBAAgB;IACjC,OAAO,KAAK,MAAM;IAClB,WAAW;IACZ,CAAC;AAEF,QAAK,GAAG,GAAG,SAAS,SAAS;AAC3B,QAAI;KACF,MAAM,MAAM,KAAK,MAAM,KAAK,MAAM,CAAC;AAGnC,SAAI,KAAK,gBACP,MAAK,gBAAgB,IAAI;AAI3B,SAAI,OAAO,IAAI,SAAS,eAAe;MACrC,MAAM,EAAE,IAAI,QAAQ,SAAS;AAC7B,WAAK,OAAO,QAAQ,KAAK,CACtB,MAAM,WAAW,KAAK,SAAS,IAAI,QAAQ,KAAK,CAAC,CACjD,OAAO,UAAU,KAAK,SAAS,IAAI,MAAM,MAAM,CAAC;;aAE9C,OAAO;AACd,aAAQ,MAAM,gCAAgC,OAAO,aAAa,KAAK;;KAEzE;AAEF,QAAK,GAAG,GAAG,eAAe;AACxB,SAAK,WAAW;KAChB;;AAGJ,OAAK,MAAM,GAAG,cAAc;AAC1B,QAAK,WAAW;IAChB;AACF,OAAK,MAAM,GAAG,eAAe;AAC3B,QAAK,WAAW;IAChB;;CAGJ,QAAQ;AACN,OAAK,WAAW;AAChB,OAAK,kBAAkB;AACvB,OAAK,WAAW,EAAE;AAClB,MAAI,KAAK,IAAI;AACX,QAAK,GAAG,oBAAoB;AAC5B,QAAK,GAAG,OAAO"}
|