@motiadev/core 0.15.5-beta.174-093524 → 0.15.6-beta.174

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.
@@ -22,6 +22,7 @@ declare class Logger {
22
22
  warn(message: string, args?: unknown): void;
23
23
  log(args: any): void;
24
24
  addListener(listener: LogListener): void;
25
+ removeListener(listener: LogListener): void;
25
26
  }
26
27
  //#endregion
27
28
  export { Logger };
@@ -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"}
@@ -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
 
@@ -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;;;AAIjC,MAAa,eAAe,IAAI,QAAQ"}
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"}
@@ -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.processor) this.processor.close();
55
- this.processor = void 0;
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 this.child = undefined\n }\n\n close(): void {\n if (this.processor) {\n this.processor.close()\n }\n this.processor = undefined\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;AAE5B,OAAK,QAAQ;;CAGf,QAAc;AACZ,MAAI,KAAK,UACP,MAAK,UAAU,OAAO;AAExB,OAAK,YAAY;;CAGnB,IAAI,UAAoC;AACtC,SAAO,KAAK;;CAGd,IAAI,WAA0C;AAC5C,SAAO,KAAK"}
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"}
@@ -87,6 +87,7 @@ const createSocketServer = ({ server, onJoin, onJoinGroup, authenticate, authori
87
87
  socket.on("close", () => {
88
88
  subscriptions.get(socket)?.forEach(([room, subscriptionId]) => {
89
89
  rooms[room]?.delete(subscriptionId);
90
+ if (rooms[room]?.size === 0) delete rooms[room];
90
91
  });
91
92
  subscriptions.delete(socket);
92
93
  authContexts.delete(socket);
@@ -1 +1 @@
1
- {"version":3,"file":"socket-server.mjs","names":["authRequest: StreamAuthRequest","rooms: Record<string, Map<string, WebSocket>>","subscriptions: Map<WebSocket, Set<[string, string]>>","authContexts: Map<WebSocket, unknown>","message: Message","resultMessage: EventMessage<typeof item>","resultMessage: EventMessage<typeof items>"],"sources":["../../src/socket-server.ts"],"sourcesContent":["import type { Server } from 'http'\nimport { type 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, Set<[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 Set())\n\n socket.on('message', async (payload: Buffer) => {\n const message: Message = JSON.parse(payload.toString())\n\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)?.add([room, message.data.subscriptionId])\n } else if (message.type === 'leave') {\n const room = getRoom(message.data)\n\n if (rooms[room]) {\n rooms[room].delete(message.data.subscriptionId)\n }\n }\n })\n\n socket.on('close', () => {\n subscriptions.get(socket)?.forEach(([room, subscriptionId]) => {\n rooms[room]?.delete(subscriptionId)\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 if (rooms[groupRoom]) {\n rooms[groupRoom].forEach((socket) => {\n socket.send(eventMessage)\n })\n }\n\n if (id) {\n const itemRoom = getRoom({ groupId, streamName, id })\n\n if (rooms[itemRoom]) {\n rooms[itemRoom].forEach((socket) => {\n socket.send(eventMessage)\n })\n }\n }\n }\n\n return { pushEvent, socketServer }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"socket-server.mjs","names":["authRequest: StreamAuthRequest","rooms: Record<string, Map<string, WebSocket>>","subscriptions: Map<WebSocket, Set<[string, string]>>","authContexts: Map<WebSocket, unknown>","message: Message","resultMessage: EventMessage<typeof item>","resultMessage: EventMessage<typeof items>"],"sources":["../../src/socket-server.ts"],"sourcesContent":["import type { Server } from 'http'\nimport { type 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, Set<[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 Set())\n\n socket.on('message', async (payload: Buffer) => {\n const message: Message = JSON.parse(payload.toString())\n\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)?.add([room, message.data.subscriptionId])\n } else if (message.type === 'leave') {\n const room = getRoom(message.data)\n\n if (rooms[room]) {\n rooms[room].delete(message.data.subscriptionId)\n }\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 if (rooms[groupRoom]) {\n rooms[groupRoom].forEach((socket) => {\n socket.send(eventMessage)\n })\n }\n\n if (id) {\n const itemRoom = getRoom({ groupId, streamName, id })\n\n if (rooms[itemRoom]) {\n rooms[itemRoom].forEach((socket) => {\n socket.send(eventMessage)\n })\n }\n }\n }\n\n return { pushEvent, socketServer }\n}\n"],"mappings":"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"}
@@ -48,6 +48,7 @@ var RpcProcessor = class {
48
48
  close() {
49
49
  this.isClosed = true;
50
50
  this.messageCallback = void 0;
51
+ this.handlers = {};
51
52
  }
52
53
  };
53
54
 
@@ -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"}
@@ -62,6 +62,7 @@ var RpcStdinProcessor = class {
62
62
  close() {
63
63
  this.isClosed = true;
64
64
  this.messageCallback = void 0;
65
+ this.handlers = {};
65
66
  if (this.rl) {
66
67
  this.rl.removeAllListeners();
67
68
  this.rl.close();
@@ -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"}
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "import": "./dist/index.mjs"
12
12
  }
13
13
  },
14
- "version": "0.15.5-beta.174-093524",
14
+ "version": "0.15.6-beta.174",
15
15
  "dependencies": {
16
16
  "@amplitude/analytics-node": "^1.5.26",
17
17
  "@standard-schema/spec": "^1.0.0",