{"id":20731683,"url":"https://github.com/tapjs/processinfo","last_synced_at":"2025-04-23T22:06:17.361Z","repository":{"id":63383202,"uuid":"467666483","full_name":"tapjs/processinfo","owner":"tapjs","description":null,"archived":false,"fork":false,"pushed_at":"2024-06-05T21:11:00.000Z","size":1756,"stargazers_count":6,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-09T22:01:59.336Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://tapjs.github.io/processinfo/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tapjs.png","metadata":{"files":{"readme":"README.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["isaacs","tapjs"]}},"created_at":"2022-03-08T20:31:35.000Z","updated_at":"2025-01-19T11:30:08.000Z","dependencies_parsed_at":"2024-03-23T19:27:56.433Z","dependency_job_id":"7f1af8b5-b6f5-4b6c-83a4-08a0ae626f9a","html_url":"https://github.com/tapjs/processinfo","commit_stats":{"total_commits":158,"total_committers":3,"mean_commits":"52.666666666666664","dds":"0.012658227848101222","last_synced_commit":"c0b71db155f35da0e2f2a17bbefce4ddc287a827"},"previous_names":[],"tags_count":53,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tapjs%2Fprocessinfo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tapjs%2Fprocessinfo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tapjs%2Fprocessinfo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tapjs%2Fprocessinfo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tapjs","download_url":"https://codeload.github.com/tapjs/processinfo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249933985,"owners_count":21347768,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-17T05:16:24.301Z","updated_at":"2025-04-23T22:06:16.443Z","avatar_url":"https://github.com/tapjs.png","language":"JavaScript","funding_links":["https://github.com/sponsors/isaacs","https://github.com/sponsors/tapjs"],"categories":[],"sub_categories":[],"readme":"# @tapjs/processinfo\n\nA Node.js loader to track processes and which JavaScript files they load.\n\nAfter the process has run, all wrapped process info is dumped to\n`.tap/processinfo`.\n\nThe exported object can also be used to spawn processes, clear the\nprocessinfo data, or load the processinfo data.\n\n## USAGE\n\nRun the top level process with a `--loader` or `--require` argument to\ntrack all Node.js child processes.\n\n```sh\n# wrap both CommonJS and ESM, node versions less than 20.6\nnode --loader=@tapjs/processinfo/loader file.js\n\n# for node versions 20.6 and higher:\nnode --import=@tapjs/processinfo/import\n```\n\nTo spawn a wrapped process from JavaScript, you can run:\n\n```js\nimport {\n  spawn,\n  exec,\n  execFile,\n  execSync,\n  execFileSync,\n  fork,\n} from '@tapjs/processinfo'\n// any of these will work\nconst childProcess = spawn(cmd, args, options)\nconst childProcess = exec(cmd, options, callback)\nconst childProcess = execFile(cmd, options, callback)\nconst childProcess = spawnSync(cmd, args, options)\nconst childProcess = execSync(cmd, options)\nconst childProcess = execFileSync(cmd, options)\nconst childProcess = fork(cmd, options)\n```\n\nThe `cmd` and `args` parameters are identical to the methods from the\nNode.js `child_process` module. The `options` parameter is also identical,\nbut may also include an `externalID` field, which if set to a string, will\nbe used as the processinfo `externalID`.\n\nIf you just use the normal `spawn`/`exec` methods from the Node.js\n`child_process` module, then the relevant environment variables will still\nbe tracked, unless explicitly set to `''` or some other value.\n\n### Important\n\nIn order to properly track `lineLengths` (required for coverage\nreporting on source mapped files), `@tapjs/processinfo` must be\nthe **last** loader specified on the command line, so that it can\nget access to the transpiled source that Node.js actually\nexecutes.\n\n### Interacting with Process Info\n\nTo load the process info data, use the exported `ProcessInfo` class.\n\n```js\nimport { ProcessInfo } from '@tapjs/processinfo'\n\n// returns\n// {\n//   roots: Set([ProcessInfo.Node, ...]) for each root process group\n//   files: Map({ filename =\u003e Set([ProcessInfo.Node, ...]) }),\n//   externalIDs: Map({ externalID =\u003e ProcessInfo.Node }),\n//   uuids: Map({ uuid =\u003e ProcessInfo.Node }),\n// }\n// A ProcessInfo.Node looks like:\n// {\n//   date: iso date string,\n//   argv,\n//   execArgv,\n//   cwd,\n//   pid,\n//   ppid,\n//   uuid,\n//   externalID,\n//   parent: \u003cProcessInfo.Node or null for root node\u003e,\n//   root: \u003cProcessInfo.Node\u003e,\n//   children: [ProcessInfo.Node, ...],\n//   descendants: [ProcessInfo.Node, ...],\n//   files: [ filename, ... ],\n//   code: unix exit code,\n//   signal: terminating signal or null,\n//   runtime: high resolution run time in ms,\n// }\nconst processInfoDB = await ProcessInfo.load()\n// say we wanted to find all the files loaded by the process 'foo'\nconst proc = processInfoDB.externalIDs.get('foo')\nconsole.error(`Files loaded by process named 'foo':`, proc.files)\n\n// now let's find all any other named processes that loaded them\nfor (const f of proc.files) {\n  for (const otherProc of processInfoDB.files.get(f)) {\n    // walk up the tree looking for a named process\n    for (let parent = otherProc; parent; parent = parent.parent) {\n      if (parent.externalID \u0026\u0026 parent !== proc) {\n        console.error(`Also loaded by process ${parent.externalID}`)\n      }\n    }\n  }\n}\n```\n\nNote: unless there has been a previous wrapped process run, nothing will be\npresent in the data. That is, `data.root` will be null, and all the maps\nwill be empty.\n\n## Controlling Coverage\n\nTo disable coverage entirely, set\n`_TAPJS_PROCESSINFO_COVERAGE_=0` in the environment.\n\nTo exclude certain file paths from coverage with a pattern, set\nthe `_TAPJS_PROCESSINFO_COV_EXCLUDE_` to a regular expression\nstring. Note that processinfo will _never_ provide coverage for a\nfile that's excluded from process file tracking.\n\nTo exclude specific individual file paths from coverage, set the\n`_TAPJS_PROCESSINFO_COV_EXCLUDE_FILES_` to a `\\n` delimited\nset of file paths.\n\nTo include only a specific set of files for coverage (as with\nnode-tap's `coverage-map` option), set\n`_TAPJS_PROCESSINFO_COV_FILES_` to a `\\n` delimited list of the\nfiles to include. These will have their coverage reported even if\nthey would be excluded by the `_TAPJS_PROCESSINFO_COV_EXCLUDE_`\nregexp or `_TAPJS_PROCESSINFO_COV_EXCLUDE_FILES_` list.\n\nNote that coverage _instrumentation_ is by necessity enabled for\nall files, but it's only written to disk if the file (or any of\nits sources, if it has a sourcemap) is included.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftapjs%2Fprocessinfo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftapjs%2Fprocessinfo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftapjs%2Fprocessinfo/lists"}