{"_id":"@acegalaxy/node-utils","name":"@acegalaxy/node-utils","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@acegalaxy/node-utils","version":"0.1.0","description":"Small generic Node.js helpers: file-lock (mkdir-based mutex with stale-PID detection), process-group (kill-tree via pgid), string normalize. Zero deps.","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./file-lock":{"types":"./dist/file-lock.d.ts","default":"./dist/file-lock.js"},"./normalize":{"types":"./dist/normalize.d.ts","default":"./dist/normalize.js"},"./process-group":{"types":"./dist/process-group.d.ts","default":"./dist/process-group.js"},"./*":{"types":"./dist/*.d.ts","default":"./dist/*.js"},"./package.json":"./package.json"},"scripts":{"build":"tsc","prepublishOnly":"npm run build","clean":"rm -rf dist","test":"node --test test/*.test.js","pretest":"npm run build"},"keywords":["file-lock","mutex","process-group","kill-tree","normalize","node-utils"],"author":{"name":"ACE Galaxy","email":"hello@acegalaxy.co"},"license":"MIT","private":false,"engines":{"node":">=18"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/acegalaxy-co/ace_commons-node-utils-nodejs.git"},"bugs":{"url":"https://github.com/acegalaxy-co/ace_commons-node-utils-nodejs/issues"},"homepage":"https://github.com/acegalaxy-co/ace_commons-node-utils-nodejs#readme","devDependencies":{"typescript":"^5.7.0","@types/node":"^20.0.0"},"gitHead":"292dcdb143e18c203c9a8875c781b952c9a0cf85","_id":"@acegalaxy/node-utils@0.1.0","_nodeVersion":"25.9.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-UHvfT5XNkfaHfdE+iRkON+Z/CvoqndwkcXmVdYtVpSCqH1x7Wi2nlOBc4dUFSYTorxnqhfyHHoGFwyg3lV5vDQ==","shasum":"55a0acfa349d976d62c892fd246fa5a2d9e643fc","tarball":"https://registry.npmjs.org/@acegalaxy/node-utils/-/node-utils-0.1.0.tgz","fileCount":22,"unpackedSize":19517,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCG0hkqszxctgWVARiq7ZvBpVUibZrUo++roDjseO6w3gIgZOX2O87oh4u7PjW6RNKuI56X74vnFaelKFascyPtycY="}]},"_npmUser":{"name":"kanelr","email":"lanhnk@acegalaxy.co"},"directories":{},"maintainers":[{"name":"kanelr","email":"lanhnk@acegalaxy.co"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/node-utils_0.1.0_1778162515467_0.5696325187326534"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-07T14:01:55.346Z","0.1.0":"2026-05-07T14:01:55.625Z","modified":"2026-05-07T14:01:55.915Z"},"maintainers":[{"name":"kanelr","email":"lanhnk@acegalaxy.co"}],"description":"Small generic Node.js helpers: file-lock (mkdir-based mutex with stale-PID detection), process-group (kill-tree via pgid), string normalize. Zero deps.","homepage":"https://github.com/acegalaxy-co/ace_commons-node-utils-nodejs#readme","keywords":["file-lock","mutex","process-group","kill-tree","normalize","node-utils"],"repository":{"type":"git","url":"git+https://github.com/acegalaxy-co/ace_commons-node-utils-nodejs.git"},"author":{"name":"ACE Galaxy","email":"hello@acegalaxy.co"},"bugs":{"url":"https://github.com/acegalaxy-co/ace_commons-node-utils-nodejs/issues"},"license":"MIT","readme":"# @acegalaxy/node-utils\n\n[![npm version](https://img.shields.io/npm/v/@acegalaxy/node-utils.svg)](https://www.npmjs.com/package/@acegalaxy/node-utils)\n[![license](https://img.shields.io/npm/l/@acegalaxy/node-utils.svg)](LICENSE)\n[![node](https://img.shields.io/node/v/@acegalaxy/node-utils.svg)](https://nodejs.org)\n\nSmall generic Node.js helpers. Zero runtime deps. TypeScript with `.d.ts` shipped.\n\n## Install\n\n```bash\nnpm install @acegalaxy/node-utils\n```\n\n## What's inside\n\n| Subpath | Purpose |\n|---|---|\n| `@acegalaxy/node-utils/file-lock` | mkdir-based mutex with stale-PID detection (cron-safe) |\n| `@acegalaxy/node-utils/process-group` | kill child + grandchildren via process group; spawn-detached helper |\n| `@acegalaxy/node-utils/normalize` | string normalize helpers (lower + trim, plus normalizing key lookups) |\n\n## Quick start\n\n### file-lock\n\nCron-safe mutex backed by `mkdir` + PID liveness check. Auto-cleans stale locks if the owning PID is gone.\n\n```js\nconst { acquireLock, releaseLock } = require(\"@acegalaxy/node-utils/file-lock\");\n\nconst lockPath = \"/tmp/myjob.lock\";\nif (!acquireLock(lockPath)) {\n  console.log(\"another instance running — exit\");\n  process.exit(0);\n}\ntry {\n  await doWork();\n} finally {\n  releaseLock(lockPath);\n}\n```\n\n### process-group\n\n`child_process.spawn(..., { detached: true })` puts the child in its own process group. With shell:true, the immediate child is `/bin/sh` and the real CLI is a grandchild that would survive `child.kill()`. `killTree(pid)` signals the whole group.\n\n```js\nconst { spawn } = require(\"child_process\");\nconst { killTree, SPAWN_OPTS_DETACHED } = require(\"@acegalaxy/node-utils/process-group\");\n\nconst child = spawn(\"npm\", [\"run\", \"long-task\"], { shell: true, ...SPAWN_OPTS_DETACHED });\nsetTimeout(() => killTree(child.pid, \"SIGTERM\"), 30_000);\n```\n\n### normalize\n\n```js\nconst { normalize } = require(\"@acegalaxy/node-utils/normalize\");\n\nnormalize(\"  Hello World  \"); // \"hello world\"\n```\n\n## License\n\nMIT © ACE Galaxy\n","readmeFilename":"README.md","_rev":"1-9501bda0d64001968b32e6f8c30010ec"}