From ece16b75e210d7b74674a5322376853c065ffa60 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Thu, 28 Aug 2025 18:17:41 +0000 Subject: [PATCH] feat(daemon): Reorganize and refactor core into client/daemon/shared modules; add IPC protocol and tests --- changelog.md | 12 +++++++++ .../testassets/simple-script2.ts | 0 .../testassets/simple-test.ts | 0 ts/00_commitinfo_data.ts | 2 +- ts/cli/commands/process/delete.ts | 2 +- ts/cli/commands/process/list.ts | 2 +- ts/cli/commands/process/restart.ts | 2 +- ts/cli/commands/process/start.ts | 2 +- ts/cli/commands/process/stop.ts | 2 +- ts/cli/index.ts | 2 +- ts/client/index.ts | 8 ++++++ .../tspm.ipcclient.ts} | 6 ++--- .../tspm.servicemanager.ts} | 4 +-- ts/{daemon.ts => daemon/index.ts} | 2 +- .../processmanager.ts} | 14 +++++----- .../processmonitor.ts} | 6 ++--- .../processwrapper.ts} | 4 +-- .../tspm.config.ts} | 2 +- .../tspm.daemon.ts} | 12 ++++----- ts/{ => shared/common}/utils.errorhandler.ts | 0 ts/shared/protocol/error.codes.ts | 26 +++++++++++++++++++ ts/{ => shared/protocol}/ipc.types.ts | 0 ts/shared/protocol/protocol.version.ts | 5 ++++ 23 files changed, 83 insertions(+), 32 deletions(-) rename test-script.ts => test/testassets/simple-script2.ts (100%) rename simple-test.ts => test/testassets/simple-test.ts (100%) create mode 100644 ts/client/index.ts rename ts/{classes.ipcclient.ts => client/tspm.ipcclient.ts} (98%) rename ts/{classes.servicemanager.ts => client/tspm.servicemanager.ts} (97%) rename ts/{daemon.ts => daemon/index.ts} (74%) rename ts/{classes.tspm.ts => daemon/processmanager.ts} (97%) rename ts/{classes.processmonitor.ts => daemon/processmonitor.ts} (97%) rename ts/{classes.processwrapper.ts => daemon/processwrapper.ts} (98%) rename ts/{classes.config.ts => daemon/tspm.config.ts} (92%) rename ts/{classes.daemon.ts => daemon/tspm.daemon.ts} (97%) rename ts/{ => shared/common}/utils.errorhandler.ts (100%) create mode 100644 ts/shared/protocol/error.codes.ts rename ts/{ => shared/protocol}/ipc.types.ts (100%) create mode 100644 ts/shared/protocol/protocol.version.ts diff --git a/changelog.md b/changelog.md index f7577ae..a35c806 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,17 @@ # Changelog +## 2025-08-28 - 3.1.0 - feat(daemon) +Reorganize and refactor core into client/daemon/shared modules; add IPC protocol and tests + +- Reorganized core code: split daemon and client logic into ts/daemon and ts/client directories +- Moved process management into ProcessManager, ProcessMonitor and ProcessWrapper under ts/daemon +- Added a dedicated IPC client and service manager under ts/client (tspm.ipcclient, tspm.servicemanager) +- Introduced shared protocol and error handling: ts/shared/protocol/ipc.types.ts, protocol.version.ts and ts/shared/common/utils.errorhandler.ts +- Updated CLI to import Logger from shared/common utils and updated related helpers +- Added daemon entrypoint at ts/daemon/index.ts and reorganized daemon startup/shutdown/heartbeat handling +- Added test assets (test/testassets/simple-test.ts, simple-script2.ts) and expanded test files under test/ +- Removed legacy top-level class files (classes.*) in favor of the new structured layout + ## 2025-08-28 - 3.0.2 - fix(daemon) Ensure TSPM runtime dir exists and improve daemon startup/debug output diff --git a/test-script.ts b/test/testassets/simple-script2.ts similarity index 100% rename from test-script.ts rename to test/testassets/simple-script2.ts diff --git a/simple-test.ts b/test/testassets/simple-test.ts similarity index 100% rename from simple-test.ts rename to test/testassets/simple-test.ts diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index b6faf89..1b53454 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@git.zone/tspm', - version: '3.0.2', + version: '3.1.0', description: 'a no fuzz process manager' } diff --git a/ts/cli/commands/process/delete.ts b/ts/cli/commands/process/delete.ts index c671bc3..65dc4c0 100644 --- a/ts/cli/commands/process/delete.ts +++ b/ts/cli/commands/process/delete.ts @@ -1,5 +1,5 @@ import * as plugins from '../../../plugins.js'; -import { tspmIpcClient } from '../../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; import type { CliArguments } from '../../types.js'; import { registerIpcCommand } from '../../registration/index.js'; diff --git a/ts/cli/commands/process/list.ts b/ts/cli/commands/process/list.ts index 98eff0c..da95671 100644 --- a/ts/cli/commands/process/list.ts +++ b/ts/cli/commands/process/list.ts @@ -1,5 +1,5 @@ import * as plugins from '../../../plugins.js'; -import { tspmIpcClient } from '../../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; import type { CliArguments } from '../../types.js'; import { registerIpcCommand } from '../../registration/index.js'; import { pad } from '../../helpers/formatting.js'; diff --git a/ts/cli/commands/process/restart.ts b/ts/cli/commands/process/restart.ts index d0312d6..8719071 100644 --- a/ts/cli/commands/process/restart.ts +++ b/ts/cli/commands/process/restart.ts @@ -1,5 +1,5 @@ import * as plugins from '../../../plugins.js'; -import { tspmIpcClient } from '../../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; import type { CliArguments } from '../../types.js'; import { registerIpcCommand } from '../../registration/index.js'; diff --git a/ts/cli/commands/process/start.ts b/ts/cli/commands/process/start.ts index dcc9045..bf36bd6 100644 --- a/ts/cli/commands/process/start.ts +++ b/ts/cli/commands/process/start.ts @@ -1,5 +1,5 @@ import * as plugins from '../../../plugins.js'; -import { tspmIpcClient } from '../../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; import type { IProcessConfig } from '../../../classes.tspm.js'; import type { CliArguments } from '../../types.js'; import { parseMemoryString, formatMemory } from '../../helpers/memory.js'; diff --git a/ts/cli/commands/process/stop.ts b/ts/cli/commands/process/stop.ts index e7a1963..0ec0ef4 100644 --- a/ts/cli/commands/process/stop.ts +++ b/ts/cli/commands/process/stop.ts @@ -1,5 +1,5 @@ import * as plugins from '../../../plugins.js'; -import { tspmIpcClient } from '../../../classes.ipcclient.js'; +import { tspmIpcClient } from '../../../client/tspm.ipcclient.js'; import type { CliArguments } from '../../types.js'; import { registerIpcCommand } from '../../registration/index.js'; diff --git a/ts/cli/index.ts b/ts/cli/index.ts index 56ec21b..888299b 100644 --- a/ts/cli/index.ts +++ b/ts/cli/index.ts @@ -1,6 +1,6 @@ import * as plugins from '../plugins.js'; import * as paths from '../paths.js'; -import { Logger, LogLevel } from '../utils.errorhandler.js'; +import { Logger, LogLevel } from '../shared/common/utils.errorhandler.js'; // Import command registration functions import { registerDefaultCommand } from './commands/default.js'; diff --git a/ts/client/index.ts b/ts/client/index.ts new file mode 100644 index 0000000..163b4fd --- /dev/null +++ b/ts/client/index.ts @@ -0,0 +1,8 @@ +/** + * Client-side exports for TSPM + * These are the only components that client applications should use + * They only communicate with the daemon via IPC, never directly manage processes + */ + +export * from './tspm.ipcclient.js'; +export * from './tspm.servicemanager.js'; \ No newline at end of file diff --git a/ts/classes.ipcclient.ts b/ts/client/tspm.ipcclient.ts similarity index 98% rename from ts/classes.ipcclient.ts rename to ts/client/tspm.ipcclient.ts index dad7220..7ada68f 100644 --- a/ts/classes.ipcclient.ts +++ b/ts/client/tspm.ipcclient.ts @@ -1,11 +1,11 @@ -import * as plugins from './plugins.js'; -import * as paths from './paths.js'; +import * as plugins from '../plugins.js'; +import * as paths from '../paths.js'; import type { IpcMethodMap, RequestForMethod, ResponseForMethod, -} from './ipc.types.js'; +} from '../shared/protocol/ipc.types.js'; /** * IPC client for communicating with the TSPM daemon diff --git a/ts/classes.servicemanager.ts b/ts/client/tspm.servicemanager.ts similarity index 97% rename from ts/classes.servicemanager.ts rename to ts/client/tspm.servicemanager.ts index 990f173..d3306ce 100644 --- a/ts/classes.servicemanager.ts +++ b/ts/client/tspm.servicemanager.ts @@ -1,5 +1,5 @@ -import * as plugins from './plugins.js'; -import * as paths from './paths.js'; +import * as plugins from '../plugins.js'; +import * as paths from '../paths.js'; /** * Manages TSPM daemon as a systemd service via smartdaemon diff --git a/ts/daemon.ts b/ts/daemon/index.ts similarity index 74% rename from ts/daemon.ts rename to ts/daemon/index.ts index d62d845..632fe6d 100644 --- a/ts/daemon.ts +++ b/ts/daemon/index.ts @@ -1,6 +1,6 @@ #!/usr/bin/env node -import { startDaemon } from './classes.daemon.js'; +import { startDaemon } from './tspm.daemon.js'; // Start the daemon startDaemon().catch((error) => { diff --git a/ts/classes.tspm.ts b/ts/daemon/processmanager.ts similarity index 97% rename from ts/classes.tspm.ts rename to ts/daemon/processmanager.ts index ad95ef8..cd36c7d 100644 --- a/ts/classes.tspm.ts +++ b/ts/daemon/processmanager.ts @@ -1,19 +1,19 @@ -import * as plugins from './plugins.js'; +import * as plugins from '../plugins.js'; import { EventEmitter } from 'events'; -import * as paths from './paths.js'; +import * as paths from '../paths.js'; import { ProcessMonitor, type IMonitorConfig, -} from './classes.processmonitor.js'; -import { type IProcessLog } from './classes.processwrapper.js'; -import { TspmConfig } from './classes.config.js'; +} from './processmonitor.js'; +import { type IProcessLog } from './processwrapper.js'; +import { TspmConfig } from './tspm.config.js'; import { Logger, ProcessError, ConfigError, ValidationError, handleError, -} from './utils.errorhandler.js'; +} from '../shared/common/utils.errorhandler.js'; export interface IProcessConfig extends IMonitorConfig { id: string; // Unique identifier for the process @@ -32,7 +32,7 @@ export interface IProcessInfo { restarts: number; } -export class Tspm extends EventEmitter { +export class ProcessManager extends EventEmitter { public processes: Map = new Map(); public processConfigs: Map = new Map(); public processInfo: Map = new Map(); diff --git a/ts/classes.processmonitor.ts b/ts/daemon/processmonitor.ts similarity index 97% rename from ts/classes.processmonitor.ts rename to ts/daemon/processmonitor.ts index 17c696c..afee984 100644 --- a/ts/classes.processmonitor.ts +++ b/ts/daemon/processmonitor.ts @@ -1,7 +1,7 @@ -import * as plugins from './plugins.js'; +import * as plugins from '../plugins.js'; import { EventEmitter } from 'events'; -import { ProcessWrapper, type IProcessLog } from './classes.processwrapper.js'; -import { Logger, ProcessError, handleError } from './utils.errorhandler.js'; +import { ProcessWrapper, type IProcessLog } from './processwrapper.js'; +import { Logger, ProcessError, handleError } from '../shared/common/utils.errorhandler.js'; export interface IMonitorConfig { name?: string; // Optional name to identify the instance diff --git a/ts/classes.processwrapper.ts b/ts/daemon/processwrapper.ts similarity index 98% rename from ts/classes.processwrapper.ts rename to ts/daemon/processwrapper.ts index 4261f97..f2b86ad 100644 --- a/ts/classes.processwrapper.ts +++ b/ts/daemon/processwrapper.ts @@ -1,6 +1,6 @@ -import * as plugins from './plugins.js'; +import * as plugins from '../plugins.js'; import { EventEmitter } from 'events'; -import { Logger, ProcessError, handleError } from './utils.errorhandler.js'; +import { Logger, ProcessError, handleError } from '../shared/common/utils.errorhandler.js'; export interface IProcessWrapperOptions { command: string; diff --git a/ts/classes.config.ts b/ts/daemon/tspm.config.ts similarity index 92% rename from ts/classes.config.ts rename to ts/daemon/tspm.config.ts index 109aba4..f3ddde2 100644 --- a/ts/classes.config.ts +++ b/ts/daemon/tspm.config.ts @@ -1,4 +1,4 @@ -import * as plugins from './plugins.js'; +import * as plugins from '../plugins.js'; export class TspmConfig { public npmextraInstance = new plugins.npmextra.KeyValueStore({ diff --git a/ts/classes.daemon.ts b/ts/daemon/tspm.daemon.ts similarity index 97% rename from ts/classes.daemon.ts rename to ts/daemon/tspm.daemon.ts index 3402fcd..676f661 100644 --- a/ts/classes.daemon.ts +++ b/ts/daemon/tspm.daemon.ts @@ -1,19 +1,19 @@ -import * as plugins from './plugins.js'; -import * as paths from './paths.js'; -import { Tspm } from './classes.tspm.js'; +import * as plugins from '../plugins.js'; +import * as paths from '../paths.js'; +import { ProcessManager } from './processmanager.js'; import type { IpcMethodMap, RequestForMethod, ResponseForMethod, DaemonStatusResponse, HeartbeatResponse, -} from './ipc.types.js'; +} from '../shared/protocol/ipc.types.js'; /** * Central daemon server that manages all TSPM processes */ export class TspmDaemon { - private tspmInstance: Tspm; + private tspmInstance: ProcessManager; private ipcServer: plugins.smartipc.IpcServer; private startTime: number; private isShuttingDown: boolean = false; @@ -22,7 +22,7 @@ export class TspmDaemon { private daemonPidFile: string; constructor() { - this.tspmInstance = new Tspm(); + this.tspmInstance = new ProcessManager(); this.socketPath = plugins.path.join(paths.tspmDir, 'tspm.sock'); this.daemonPidFile = plugins.path.join(paths.tspmDir, 'daemon.pid'); this.startTime = Date.now(); diff --git a/ts/utils.errorhandler.ts b/ts/shared/common/utils.errorhandler.ts similarity index 100% rename from ts/utils.errorhandler.ts rename to ts/shared/common/utils.errorhandler.ts diff --git a/ts/shared/protocol/error.codes.ts b/ts/shared/protocol/error.codes.ts new file mode 100644 index 0000000..a269370 --- /dev/null +++ b/ts/shared/protocol/error.codes.ts @@ -0,0 +1,26 @@ +/** + * Standardized error codes for IPC communication + * These are used instead of string messages for better error handling + */ +export enum ErrorCode { + // General errors + UNKNOWN_ERROR = 'UNKNOWN_ERROR', + INVALID_REQUEST = 'INVALID_REQUEST', + + // Process errors + PROCESS_NOT_FOUND = 'PROCESS_NOT_FOUND', + PROCESS_ALREADY_EXISTS = 'PROCESS_ALREADY_EXISTS', + PROCESS_START_FAILED = 'PROCESS_START_FAILED', + PROCESS_STOP_FAILED = 'PROCESS_STOP_FAILED', + + // Daemon errors + DAEMON_NOT_RUNNING = 'DAEMON_NOT_RUNNING', + DAEMON_ALREADY_RUNNING = 'DAEMON_ALREADY_RUNNING', + + // Memory errors + MEMORY_LIMIT_EXCEEDED = 'MEMORY_LIMIT_EXCEEDED', + + // Config errors + CONFIG_INVALID = 'CONFIG_INVALID', + CONFIG_SAVE_FAILED = 'CONFIG_SAVE_FAILED', +} \ No newline at end of file diff --git a/ts/ipc.types.ts b/ts/shared/protocol/ipc.types.ts similarity index 100% rename from ts/ipc.types.ts rename to ts/shared/protocol/ipc.types.ts diff --git a/ts/shared/protocol/protocol.version.ts b/ts/shared/protocol/protocol.version.ts new file mode 100644 index 0000000..b5cec57 --- /dev/null +++ b/ts/shared/protocol/protocol.version.ts @@ -0,0 +1,5 @@ +/** + * Protocol version for client-daemon communication + * This allows for version compatibility checks between client and daemon + */ +export const PROTOCOL_VERSION = '1.0.0'; \ No newline at end of file