feat(daemon): Reorganize and refactor core into client/daemon/shared modules; add IPC protocol and tests
This commit is contained in:
12
changelog.md
12
changelog.md
@@ -1,5 +1,17 @@
|
|||||||
# Changelog
|
# 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)
|
## 2025-08-28 - 3.0.2 - fix(daemon)
|
||||||
Ensure TSPM runtime dir exists and improve daemon startup/debug output
|
Ensure TSPM runtime dir exists and improve daemon startup/debug output
|
||||||
|
|
||||||
|
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@git.zone/tspm',
|
name: '@git.zone/tspm',
|
||||||
version: '3.0.2',
|
version: '3.1.0',
|
||||||
description: 'a no fuzz process manager'
|
description: 'a no fuzz process manager'
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
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 type { CliArguments } from '../../types.js';
|
||||||
import { registerIpcCommand } from '../../registration/index.js';
|
import { registerIpcCommand } from '../../registration/index.js';
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
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 type { CliArguments } from '../../types.js';
|
||||||
import { registerIpcCommand } from '../../registration/index.js';
|
import { registerIpcCommand } from '../../registration/index.js';
|
||||||
import { pad } from '../../helpers/formatting.js';
|
import { pad } from '../../helpers/formatting.js';
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
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 type { CliArguments } from '../../types.js';
|
||||||
import { registerIpcCommand } from '../../registration/index.js';
|
import { registerIpcCommand } from '../../registration/index.js';
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
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 { IProcessConfig } from '../../../classes.tspm.js';
|
||||||
import type { CliArguments } from '../../types.js';
|
import type { CliArguments } from '../../types.js';
|
||||||
import { parseMemoryString, formatMemory } from '../../helpers/memory.js';
|
import { parseMemoryString, formatMemory } from '../../helpers/memory.js';
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import * as plugins from '../../../plugins.js';
|
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 type { CliArguments } from '../../types.js';
|
||||||
import { registerIpcCommand } from '../../registration/index.js';
|
import { registerIpcCommand } from '../../registration/index.js';
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import * as plugins from '../plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import * as paths from '../paths.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 command registration functions
|
||||||
import { registerDefaultCommand } from './commands/default.js';
|
import { registerDefaultCommand } from './commands/default.js';
|
||||||
|
8
ts/client/index.ts
Normal file
8
ts/client/index.ts
Normal file
@@ -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';
|
@@ -1,11 +1,11 @@
|
|||||||
import * as plugins from './plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import * as paths from './paths.js';
|
import * as paths from '../paths.js';
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
IpcMethodMap,
|
IpcMethodMap,
|
||||||
RequestForMethod,
|
RequestForMethod,
|
||||||
ResponseForMethod,
|
ResponseForMethod,
|
||||||
} from './ipc.types.js';
|
} from '../shared/protocol/ipc.types.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IPC client for communicating with the TSPM daemon
|
* IPC client for communicating with the TSPM daemon
|
@@ -1,5 +1,5 @@
|
|||||||
import * as plugins from './plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import * as paths from './paths.js';
|
import * as paths from '../paths.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages TSPM daemon as a systemd service via smartdaemon
|
* Manages TSPM daemon as a systemd service via smartdaemon
|
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { startDaemon } from './classes.daemon.js';
|
import { startDaemon } from './tspm.daemon.js';
|
||||||
|
|
||||||
// Start the daemon
|
// Start the daemon
|
||||||
startDaemon().catch((error) => {
|
startDaemon().catch((error) => {
|
@@ -1,19 +1,19 @@
|
|||||||
import * as plugins from './plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import * as paths from './paths.js';
|
import * as paths from '../paths.js';
|
||||||
import {
|
import {
|
||||||
ProcessMonitor,
|
ProcessMonitor,
|
||||||
type IMonitorConfig,
|
type IMonitorConfig,
|
||||||
} from './classes.processmonitor.js';
|
} from './processmonitor.js';
|
||||||
import { type IProcessLog } from './classes.processwrapper.js';
|
import { type IProcessLog } from './processwrapper.js';
|
||||||
import { TspmConfig } from './classes.config.js';
|
import { TspmConfig } from './tspm.config.js';
|
||||||
import {
|
import {
|
||||||
Logger,
|
Logger,
|
||||||
ProcessError,
|
ProcessError,
|
||||||
ConfigError,
|
ConfigError,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
handleError,
|
handleError,
|
||||||
} from './utils.errorhandler.js';
|
} from '../shared/common/utils.errorhandler.js';
|
||||||
|
|
||||||
export interface IProcessConfig extends IMonitorConfig {
|
export interface IProcessConfig extends IMonitorConfig {
|
||||||
id: string; // Unique identifier for the process
|
id: string; // Unique identifier for the process
|
||||||
@@ -32,7 +32,7 @@ export interface IProcessInfo {
|
|||||||
restarts: number;
|
restarts: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Tspm extends EventEmitter {
|
export class ProcessManager extends EventEmitter {
|
||||||
public processes: Map<string, ProcessMonitor> = new Map();
|
public processes: Map<string, ProcessMonitor> = new Map();
|
||||||
public processConfigs: Map<string, IProcessConfig> = new Map();
|
public processConfigs: Map<string, IProcessConfig> = new Map();
|
||||||
public processInfo: Map<string, IProcessInfo> = new Map();
|
public processInfo: Map<string, IProcessInfo> = new Map();
|
@@ -1,7 +1,7 @@
|
|||||||
import * as plugins from './plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { ProcessWrapper, type IProcessLog } from './classes.processwrapper.js';
|
import { ProcessWrapper, type IProcessLog } from './processwrapper.js';
|
||||||
import { Logger, ProcessError, handleError } from './utils.errorhandler.js';
|
import { Logger, ProcessError, handleError } from '../shared/common/utils.errorhandler.js';
|
||||||
|
|
||||||
export interface IMonitorConfig {
|
export interface IMonitorConfig {
|
||||||
name?: string; // Optional name to identify the instance
|
name?: string; // Optional name to identify the instance
|
@@ -1,6 +1,6 @@
|
|||||||
import * as plugins from './plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import { EventEmitter } from 'events';
|
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 {
|
export interface IProcessWrapperOptions {
|
||||||
command: string;
|
command: string;
|
@@ -1,4 +1,4 @@
|
|||||||
import * as plugins from './plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
|
|
||||||
export class TspmConfig {
|
export class TspmConfig {
|
||||||
public npmextraInstance = new plugins.npmextra.KeyValueStore({
|
public npmextraInstance = new plugins.npmextra.KeyValueStore({
|
@@ -1,19 +1,19 @@
|
|||||||
import * as plugins from './plugins.js';
|
import * as plugins from '../plugins.js';
|
||||||
import * as paths from './paths.js';
|
import * as paths from '../paths.js';
|
||||||
import { Tspm } from './classes.tspm.js';
|
import { ProcessManager } from './processmanager.js';
|
||||||
import type {
|
import type {
|
||||||
IpcMethodMap,
|
IpcMethodMap,
|
||||||
RequestForMethod,
|
RequestForMethod,
|
||||||
ResponseForMethod,
|
ResponseForMethod,
|
||||||
DaemonStatusResponse,
|
DaemonStatusResponse,
|
||||||
HeartbeatResponse,
|
HeartbeatResponse,
|
||||||
} from './ipc.types.js';
|
} from '../shared/protocol/ipc.types.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Central daemon server that manages all TSPM processes
|
* Central daemon server that manages all TSPM processes
|
||||||
*/
|
*/
|
||||||
export class TspmDaemon {
|
export class TspmDaemon {
|
||||||
private tspmInstance: Tspm;
|
private tspmInstance: ProcessManager;
|
||||||
private ipcServer: plugins.smartipc.IpcServer;
|
private ipcServer: plugins.smartipc.IpcServer;
|
||||||
private startTime: number;
|
private startTime: number;
|
||||||
private isShuttingDown: boolean = false;
|
private isShuttingDown: boolean = false;
|
||||||
@@ -22,7 +22,7 @@ export class TspmDaemon {
|
|||||||
private daemonPidFile: string;
|
private daemonPidFile: string;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.tspmInstance = new Tspm();
|
this.tspmInstance = new ProcessManager();
|
||||||
this.socketPath = plugins.path.join(paths.tspmDir, 'tspm.sock');
|
this.socketPath = plugins.path.join(paths.tspmDir, 'tspm.sock');
|
||||||
this.daemonPidFile = plugins.path.join(paths.tspmDir, 'daemon.pid');
|
this.daemonPidFile = plugins.path.join(paths.tspmDir, 'daemon.pid');
|
||||||
this.startTime = Date.now();
|
this.startTime = Date.now();
|
26
ts/shared/protocol/error.codes.ts
Normal file
26
ts/shared/protocol/error.codes.ts
Normal file
@@ -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',
|
||||||
|
}
|
5
ts/shared/protocol/protocol.version.ts
Normal file
5
ts/shared/protocol/protocol.version.ts
Normal file
@@ -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';
|
Reference in New Issue
Block a user