6 Commits

Author SHA1 Message Date
74bfcb273a 1.3.1
Some checks failed
Default (tags) / security (push) Successful in 36s
Default (tags) / test (push) Successful in 53s
Default (tags) / release (push) Failing after 47s
Default (tags) / metadata (push) Successful in 56s
2025-03-01 19:47:46 +00:00
cefbce1ba0 fix(test): Update test script to fix type references and remove private method call 2025-03-01 19:47:46 +00:00
51bb3a8967 1.3.0
Some checks failed
Default (tags) / security (push) Successful in 37s
Default (tags) / test (push) Successful in 51s
Default (tags) / release (push) Failing after 47s
Default (tags) / metadata (push) Successful in 1m0s
2025-03-01 19:19:28 +00:00
c4a082031e feat(cli): Add CLI support with command parsing and version display 2025-03-01 19:19:28 +00:00
761f9ca1b6 1.2.0
Some checks failed
Default (tags) / security (push) Successful in 36s
Default (tags) / test (push) Successful in 52s
Default (tags) / release (push) Failing after 46s
Default (tags) / metadata (push) Successful in 59s
2025-03-01 18:02:40 +00:00
ad2c180cfe feat(core): Introduce ProcessMonitor with memory management and spawning features 2025-03-01 18:02:40 +00:00
10 changed files with 204 additions and 35 deletions

View File

@ -1,5 +1,27 @@
# Changelog # Changelog
## 2025-03-01 - 1.3.1 - fix(test)
Update test script to fix type references and remove private method call
- Corrected type references in test script for IMonitorConfig.
- Fixed test script to use console.log instead of private method monitor.log.
## 2025-03-01 - 1.3.0 - feat(cli)
Add CLI support with command parsing and version display
- Added a basic CLI interface using smartcli.
- Implemented command parsing with a 'restart' command.
- Integrated project version display in the CLI.
## 2025-03-01 - 1.2.0 - feat(core)
Introduce ProcessMonitor with memory management and spawning features
- Added ProcessMonitor class with functionality to manage process execution and memory usage.
- Implemented process spawning with ability to handle command arguments and directories.
- Added periodic memory monitoring and automatic restarts when memory thresholds are exceeded.
- ProcessMonitor now logs its actions with optional configuration name for better identification.
- Updated test file to include example usage of ProcessMonitor.
## 2025-03-01 - 1.1.1 - fix(package) ## 2025-03-01 - 1.1.1 - fix(package)
Update dependencies and pnpm configuration Update dependencies and pnpm configuration

View File

@ -1,6 +1,6 @@
{ {
"name": "@git.zone/tspm", "name": "@git.zone/tspm",
"version": "1.1.1", "version": "1.3.1",
"private": false, "private": false,
"description": "a no fuzz process manager", "description": "a no fuzz process manager",
"main": "dist_ts/index.js", "main": "dist_ts/index.js",
@ -11,7 +11,11 @@
"scripts": { "scripts": {
"test": "(tstest test/ --web)", "test": "(tstest test/ --web)",
"build": "(tsbuild --web --allowimplicitany)", "build": "(tsbuild --web --allowimplicitany)",
"buildDocs": "(tsdoc)" "buildDocs": "(tsdoc)",
"start": "(tsrun ./cli.ts -v)"
},
"bin": {
"tspm": "./cli.js"
}, },
"devDependencies": { "devDependencies": {
"@git.zone/tsbuild": "^2.1.25", "@git.zone/tsbuild": "^2.1.25",
@ -22,7 +26,11 @@
"@types/node": "^22.13.8" "@types/node": "^22.13.8"
}, },
"dependencies": { "dependencies": {
"@push.rocks/smartpath": "^5.0.18" "@push.rocks/projectinfo": "^5.0.2",
"@push.rocks/smartcli": "^4.0.11",
"@push.rocks/smartpath": "^5.0.18",
"pidusage": "^4.0.0",
"ps-tree": "^1.2.0"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

93
pnpm-lock.yaml generated
View File

@ -8,9 +8,21 @@ importers:
.: .:
dependencies: dependencies:
'@push.rocks/projectinfo':
specifier: ^5.0.2
version: 5.0.2
'@push.rocks/smartcli':
specifier: ^4.0.11
version: 4.0.11
'@push.rocks/smartpath': '@push.rocks/smartpath':
specifier: ^5.0.18 specifier: ^5.0.18
version: 5.0.18 version: 5.0.18
pidusage:
specifier: ^4.0.0
version: 4.0.0
ps-tree:
specifier: ^1.2.0
version: 1.2.0
devDependencies: devDependencies:
'@git.zone/tsbuild': '@git.zone/tsbuild':
specifier: ^2.1.25 specifier: ^2.1.25
@ -701,6 +713,9 @@ packages:
'@push.rocks/mongodump@1.0.8': '@push.rocks/mongodump@1.0.8':
resolution: {integrity: sha512-oDufyjNBg8I50OaJvbHhc0RnRpJQ544dr9her0G6sA8JmI3hD2/amTdcPLVIX1kzYf5GsTUKeWuRaZgdNqz3ew==} resolution: {integrity: sha512-oDufyjNBg8I50OaJvbHhc0RnRpJQ544dr9her0G6sA8JmI3hD2/amTdcPLVIX1kzYf5GsTUKeWuRaZgdNqz3ew==}
'@push.rocks/projectinfo@5.0.2':
resolution: {integrity: sha512-zzieCal6jwR++o+fDl8gMpWkNV2cGEsbT96vCNZu/H9kr0iqRmapOiA4DFadkhOnhlDqvRr6TPaXESu2YUbI8Q==}
'@push.rocks/qenv@6.1.0': '@push.rocks/qenv@6.1.0':
resolution: {integrity: sha512-1FUFMlSVwFSFg8LbqfkzJ2LLP4lMGApUtgOpsvrde6+AxBmB4gjoNgCUH7z3xXfDAtYqcrtSELXBNE0xVL1MqQ==} resolution: {integrity: sha512-1FUFMlSVwFSFg8LbqfkzJ2LLP4lMGApUtgOpsvrde6+AxBmB4gjoNgCUH7z3xXfDAtYqcrtSELXBNE0xVL1MqQ==}
@ -2071,6 +2086,9 @@ packages:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
duplexer@0.1.2:
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
duplexify@3.7.1: duplexify@3.7.1:
resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==}
@ -2206,6 +2224,9 @@ packages:
resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=} resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}
event-stream@3.3.4:
resolution: {integrity: sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=}
eventemitter3@4.0.7: eventemitter3@4.0.7:
resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
@ -2349,6 +2370,9 @@ packages:
from2@2.3.0: from2@2.3.0:
resolution: {integrity: sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=} resolution: {integrity: sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=}
from@0.1.7:
resolution: {integrity: sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=}
fs-constants@1.0.0: fs-constants@1.0.0:
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
@ -2930,6 +2954,9 @@ packages:
make-error@1.3.6: make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
map-stream@0.1.0:
resolution: {integrity: sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=}
markdown-table@3.0.4: markdown-table@3.0.4:
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
@ -3431,6 +3458,9 @@ packages:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'} engines: {node: '>=8'}
pause-stream@0.0.11:
resolution: {integrity: sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=}
pdf-lib@1.17.1: pdf-lib@1.17.1:
resolution: {integrity: sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==} resolution: {integrity: sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==}
@ -3458,6 +3488,10 @@ packages:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'} engines: {node: '>=8.6'}
pidusage@4.0.0:
resolution: {integrity: sha512-89hVJc5gq157puLYZaO3CH0qfGyDfbDG1KFCE4lCSwK0l1EuEbNa4pIJJXL93ltU5SsYia/DHJUgMY2qE4XRQg==}
engines: {node: '>=18'}
ping@0.4.4: ping@0.4.4:
resolution: {integrity: sha512-56ZMC0j7SCsMMLdOoUg12VZCfj/+ZO+yfOSjaNCRrmZZr6GLbN2X/Ui56T15dI8NhiHckaw5X2pvyfAomanwqQ==} resolution: {integrity: sha512-56ZMC0j7SCsMMLdOoUg12VZCfj/+ZO+yfOSjaNCRrmZZr6GLbN2X/Ui56T15dI8NhiHckaw5X2pvyfAomanwqQ==}
engines: {node: '>=4.0.0'} engines: {node: '>=4.0.0'}
@ -3506,6 +3540,11 @@ packages:
proxy-from-env@1.1.0: proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
ps-tree@1.2.0:
resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==}
engines: {node: '>= 0.10'}
hasBin: true
public-ip@6.0.2: public-ip@6.0.2:
resolution: {integrity: sha512-+6bkjnf0yQ4+tZV0zJv1017DiIF7y6R4yg17Mrhhkc25L7dtQtXWHgSCrz9BbLL4OeTFbPK4EALXqJUrwCIWXw==} resolution: {integrity: sha512-+6bkjnf0yQ4+tZV0zJv1017DiIF7y6R4yg17Mrhhkc25L7dtQtXWHgSCrz9BbLL4OeTFbPK4EALXqJUrwCIWXw==}
engines: {node: '>=14.16'} engines: {node: '>=14.16'}
@ -3796,6 +3835,9 @@ packages:
resolution: {integrity: sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==} resolution: {integrity: sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==}
engines: {node: '>=8'} engines: {node: '>=8'}
split@0.3.3:
resolution: {integrity: sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=}
sprintf-js@1.0.3: sprintf-js@1.0.3:
resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=} resolution: {integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=}
@ -3817,6 +3859,9 @@ packages:
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
stream-combiner@0.0.4:
resolution: {integrity: sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=}
stream-shift@1.0.3: stream-shift@1.0.3:
resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==}
@ -3923,6 +3968,9 @@ packages:
through2@4.0.2: through2@4.0.2:
resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==}
through@2.3.8:
resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=}
tiny-worker@2.3.0: tiny-worker@2.3.0:
resolution: {integrity: sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==} resolution: {integrity: sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==}
@ -5370,6 +5418,13 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- aws-crt - aws-crt
'@push.rocks/projectinfo@5.0.2':
dependencies:
'@push.rocks/smartfile': 10.0.41
'@push.rocks/smartpath': 5.0.18
'@push.rocks/smartpromise': 4.2.3
'@push.rocks/smartstring': 4.0.15
'@push.rocks/qenv@6.1.0': '@push.rocks/qenv@6.1.0':
dependencies: dependencies:
'@api.global/typedrequest': 3.1.10 '@api.global/typedrequest': 3.1.10
@ -7345,6 +7400,8 @@ snapshots:
es-errors: 1.3.0 es-errors: 1.3.0
gopd: 1.2.0 gopd: 1.2.0
duplexer@0.1.2: {}
duplexify@3.7.1: duplexify@3.7.1:
dependencies: dependencies:
end-of-stream: 1.4.4 end-of-stream: 1.4.4
@ -7516,6 +7573,16 @@ snapshots:
etag@1.8.1: {} etag@1.8.1: {}
event-stream@3.3.4:
dependencies:
duplexer: 0.1.2
from: 0.1.7
map-stream: 0.1.0
pause-stream: 0.0.11
split: 0.3.3
stream-combiner: 0.0.4
through: 2.3.8
eventemitter3@4.0.7: {} eventemitter3@4.0.7: {}
execa@5.1.1: execa@5.1.1:
@ -7712,6 +7779,8 @@ snapshots:
inherits: 2.0.4 inherits: 2.0.4
readable-stream: 2.3.8 readable-stream: 2.3.8
from@0.1.7: {}
fs-constants@1.0.0: {} fs-constants@1.0.0: {}
fs-extra@10.1.0: fs-extra@10.1.0:
@ -8377,6 +8446,8 @@ snapshots:
make-error@1.3.6: {} make-error@1.3.6: {}
map-stream@0.1.0: {}
markdown-table@3.0.4: {} markdown-table@3.0.4: {}
matcher@3.0.0: matcher@3.0.0:
@ -9020,6 +9091,10 @@ snapshots:
path-type@4.0.0: {} path-type@4.0.0: {}
pause-stream@0.0.11:
dependencies:
through: 2.3.8
pdf-lib@1.17.1: pdf-lib@1.17.1:
dependencies: dependencies:
'@pdf-lib/standard-fonts': 1.0.0 '@pdf-lib/standard-fonts': 1.0.0
@ -9043,6 +9118,10 @@ snapshots:
picomatch@2.3.1: {} picomatch@2.3.1: {}
pidusage@4.0.0:
dependencies:
safe-buffer: 5.2.1
ping@0.4.4: {} ping@0.4.4: {}
pkg-dir@4.2.0: pkg-dir@4.2.0:
@ -9095,6 +9174,10 @@ snapshots:
proxy-from-env@1.1.0: {} proxy-from-env@1.1.0: {}
ps-tree@1.2.0:
dependencies:
event-stream: 3.3.4
public-ip@6.0.2: public-ip@6.0.2:
dependencies: dependencies:
aggregate-error: 4.0.1 aggregate-error: 4.0.1
@ -9504,6 +9587,10 @@ snapshots:
signal-exit: 3.0.7 signal-exit: 3.0.7
which: 2.0.2 which: 2.0.2
split@0.3.3:
dependencies:
through: 2.3.8
sprintf-js@1.0.3: {} sprintf-js@1.0.3: {}
sprintf-js@1.1.3: {} sprintf-js@1.1.3: {}
@ -9518,6 +9605,10 @@ snapshots:
statuses@2.0.1: {} statuses@2.0.1: {}
stream-combiner@0.0.4:
dependencies:
duplexer: 0.1.2
stream-shift@1.0.3: {} stream-shift@1.0.3: {}
streamsearch@0.1.2: {} streamsearch@0.1.2: {}
@ -9652,6 +9743,8 @@ snapshots:
dependencies: dependencies:
readable-stream: 3.6.2 readable-stream: 3.6.2
through@2.3.8: {}
tiny-worker@2.3.0: tiny-worker@2.3.0:
dependencies: dependencies:
esm: 3.2.25 esm: 3.2.25

View File

@ -6,3 +6,22 @@ tap.test('first test', async () => {
}); });
tap.start(); tap.start();
// Example usage:
const config: tspm.IMonitorConfig = {
name: 'Project XYZ Monitor', // Identifier for the instance
projectDir: '/path/to/your/project', // Set the project directory here
command: 'npm run xyz', // Full command string (no need for args)
memoryLimitBytes: 500 * 1024 * 1024, // 500 MB memory limit
monitorIntervalMs: 5000, // Check memory usage every 5 seconds
};
const monitor = new tspm.ProcessMonitor(config);
monitor.start();
// Ensure that on process exit (e.g. Ctrl+C) we clean up the child process and prevent respawns.
process.on('SIGINT', () => {
console.log('Received SIGINT, stopping monitor...');
monitor.stop();
process.exit();
});

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@git.zone/tspm', name: '@git.zone/tspm',
version: '1.1.1', version: '1.3.1',
description: 'a no fuzz process manager' description: 'a no fuzz process manager'
} }

View File

@ -1,8 +1,6 @@
import { spawn, ChildProcess } from 'child_process'; import * as plugins from './plugins.js';
import psTree from 'ps-tree';
import pidusage from 'pidusage';
interface IMonitorConfig { export interface IMonitorConfig {
name?: string; // Optional name to identify the instance name?: string; // Optional name to identify the instance
projectDir: string; // Directory where the command will run projectDir: string; // Directory where the command will run
command: string; // Full command to run (e.g., "npm run xyz") command: string; // Full command to run (e.g., "npm run xyz")
@ -11,8 +9,8 @@ interface IMonitorConfig {
monitorIntervalMs?: number; // Interval (in ms) at which memory is checked (default: 5000) monitorIntervalMs?: number; // Interval (in ms) at which memory is checked (default: 5000)
} }
class ProcessMonitor { export class ProcessMonitor {
private child: ChildProcess | null = null; private child: plugins.childProcess.ChildProcess | null = null;
private config: IMonitorConfig; private config: IMonitorConfig;
private intervalId: NodeJS.Timeout | null = null; private intervalId: NodeJS.Timeout | null = null;
private stopped: boolean = true; // Initially stopped until start() is called private stopped: boolean = true; // Initially stopped until start() is called
@ -46,7 +44,7 @@ class ProcessMonitor {
', ' ', '
)}] in directory: ${this.config.projectDir}` )}] in directory: ${this.config.projectDir}`
); );
this.child = spawn(this.config.command, this.config.args, { this.child = plugins.childProcess.spawn(this.config.command, this.config.args, {
cwd: this.config.projectDir, cwd: this.config.projectDir,
detached: true, detached: true,
stdio: 'inherit', stdio: 'inherit',
@ -56,7 +54,7 @@ class ProcessMonitor {
`Spawning command "${this.config.command}" in directory: ${this.config.projectDir}` `Spawning command "${this.config.command}" in directory: ${this.config.projectDir}`
); );
// Use shell mode to allow a full command string. // Use shell mode to allow a full command string.
this.child = spawn(this.config.command, { this.child = plugins.childProcess.spawn(this.config.command, {
cwd: this.config.projectDir, cwd: this.config.projectDir,
detached: true, detached: true,
stdio: 'inherit', stdio: 'inherit',
@ -107,11 +105,11 @@ class ProcessMonitor {
*/ */
private getProcessGroupMemory(pid: number): Promise<number> { private getProcessGroupMemory(pid: number): Promise<number> {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
psTree(pid, (err, children) => { plugins.psTree(pid, (err, children) => {
if (err) return reject(err); if (err) return reject(err);
// Include the main process and its children. // Include the main process and its children.
const pids: number[] = [pid, ...children.map(child => Number(child.PID))]; const pids: number[] = [pid, ...children.map(child => Number(child.PID))];
pidusage(pids, (err, stats) => { plugins.pidusage(pids, (err, stats) => {
if (err) return reject(err); if (err) return reject(err);
let totalMemory = 0; let totalMemory = 0;
for (const key in stats) { for (const key in stats) {
@ -157,22 +155,3 @@ class ProcessMonitor {
console.log(prefix + message); console.log(prefix + message);
} }
} }
// Example usage:
const config: IMonitorConfig = {
name: 'Project XYZ Monitor', // Identifier for the instance
projectDir: '/path/to/your/project', // Set the project directory here
command: 'npm run xyz', // Full command string (no need for args)
memoryLimitBytes: 500 * 1024 * 1024, // 500 MB memory limit
monitorIntervalMs: 5000, // Check memory usage every 5 seconds
};
const monitor = new ProcessMonitor(config);
monitor.start();
// Ensure that on process exit (e.g. Ctrl+C) we clean up the child process and prevent respawns.
process.on('SIGINT', () => {
monitor.log('Received SIGINT, stopping monitor...');
monitor.stop();
process.exit();
});

21
ts/cli.ts Normal file
View File

@ -0,0 +1,21 @@
import * as plugins from './plugins.js';
import * as paths from './paths.js';
export const run = async () => {
const tspmProjectinfo = new plugins.projectinfo.ProjectInfo(paths.packageDir);
const smartcliInstance = new plugins.smartcli.Smartcli();
smartcliInstance.addVersion(tspmProjectinfo.npm.version);
smartcliInstance.standardCommand().subscribe({
next: (argvArg) => {
console.log(`Please specify a command.`)
},
});
smartcliInstance.addCommand('restart').subscribe({
})
smartcliInstance.startParse();
}

View File

@ -1,3 +1,11 @@
import * as plugins from './plugins.js'; export * from './classes.tspm.js';
export * from './classes.processmonitor.js';
export let demoExport = 'Hi there! :) This is an exported string'; import * as cli from './cli.js';
/**
* called to run as cli
*/
export const runCli = async () => {
await cli.run();
}

4
ts/paths.ts Normal file
View File

@ -0,0 +1,4 @@
import * as plugins from './plugins.js';
export const packageDir = plugins.path.join(plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url), '..');
export const cwd = process.cwd();

View File

@ -1,13 +1,28 @@
// native scope // native scope
import * as childProcess from 'child_process';
import * as path from 'node:path'; import * as path from 'node:path';
export { export {
childProcess,
path, path,
} }
// @push.rocks scope // @push.rocks scope
import * as projectinfo from '@push.rocks/projectinfo';
import * as smartpath from '@push.rocks/smartpath'; import * as smartpath from '@push.rocks/smartpath';
import * as smartcli from '@push.rocks/smartcli';
export { export {
projectinfo,
smartpath, smartpath,
smartcli,
}
// third-party scope
import psTree from 'ps-tree';
import pidusage from 'pidusage';
export {
psTree,
pidusage,
} }