{"_id":"@bernierllc/nevar-loop-detector","_rev":"5-3ced874f711208ccce12e546c4b4b8ae","name":"@bernierllc/nevar-loop-detector","dist-tags":{"latest":"0.4.0"},"versions":{"0.0.1":{"name":"@bernierllc/nevar-loop-detector","version":"0.0.1","keywords":["oidc","trusted-publishing","setup"],"_id":"@bernierllc/nevar-loop-detector@0.0.1","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"219977773188563c9bba2c3cf1b834238fd2a9fd","tarball":"https://registry.npmjs.org/@bernierllc/nevar-loop-detector/-/nevar-loop-detector-0.0.1.tgz","fileCount":2,"integrity":"sha512-vMpvEefbaB78f21Qcn3LTwyKpQFdtH5gg++xQrMiSE/9KyLovYCcLL5XoG9p+lwy1JUghrusNC9RCfw4IFdM0w==","signatures":[{"sig":"MEQCIAdjPo8LOnMdsOkU/E/c9MxoQNADpL71JX4ctVo2p8ObAiBxSGWYVA1dR2DS6C5inFuy5Zn46yidCuSR8FrInCYSbQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2087},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"_npmVersion":"11.11.0","description":"OIDC trusted publishing setup package for @bernierllc/nevar-loop-detector","directories":{},"_nodeVersion":"25.8.1","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/nevar-loop-detector_0.0.1_1774655777147_0.44132653844910164","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@bernierllc/nevar-loop-detector","version":"0.1.0","keywords":["nevar","rules-engine","loop-detection","cycle-detection","static-analysis"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/nevar-loop-detector@0.1.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"3a3605597b3b3e3bae4db2888baad89f13fd39ad","tarball":"https://registry.npmjs.org/@bernierllc/nevar-loop-detector/-/nevar-loop-detector-0.1.0.tgz","fileCount":10,"integrity":"sha512-I4hfiWUTAb+9aPKL9Hlti7do4eBGIiMnudSdrdq9oPrtOKS15rAMurBQl+a1JLlKv3pfYZX0ULv0e/FS1xGB6w==","signatures":[{"sig":"MEQCIFYmt/81jE9oFH639SjH7EWoR4kcGHPn/JJbee7Q3tjXAiBMZvsknw+XLy9u0PKxqMuI2cdMqh8VkAM9z2Nw6tp31A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14129},"main":"dist/index.js","_from":"file:bernierllc-nevar-loop-detector-0.1.0.tgz","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"scripts":{"lint":"eslint src __tests__ --ext .ts","test":"jest","build":"tsc","clean":"rimraf dist","prebuild":"npm run clean","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:97499078-3391-46c1-87e8-c1bfcae5a393"}},"_resolved":"/home/runner/work/tools/tools/packages/core/nevar-loop-detector/bernierllc-nevar-loop-detector-0.1.0.tgz","_integrity":"sha512-I4hfiWUTAb+9aPKL9Hlti7do4eBGIiMnudSdrdq9oPrtOKS15rAMurBQl+a1JLlKv3pfYZX0ULv0e/FS1xGB6w==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/nevar-loop-detector"},"_npmVersion":"11.12.1","description":"Static loop analysis and runtime cycle detection for the Nevar rules engine","directories":{},"_nodeVersion":"20.20.1","dependencies":{"@bernierllc/nevar-types":"0.1.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","rimraf":"^5.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/nevar-loop-detector_0.1.0_1774898147578_0.04554479110220466","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bernierllc/nevar-loop-detector","version":"0.2.0","keywords":["nevar","rules-engine","loop-detection","cycle-detection","static-analysis"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/nevar-loop-detector@0.2.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"02ab1896634ea0a50484afa843fb9501565904cc","tarball":"https://registry.npmjs.org/@bernierllc/nevar-loop-detector/-/nevar-loop-detector-0.2.0.tgz","fileCount":10,"integrity":"sha512-b8gV1jiXlMHN4pyE9kMkw6PWCdyL4J2h+Qr+Dj7zcUVqZ5A3fljb2WtihdF7a54PiOd1drk5v//OAlhpdM4v8A==","signatures":[{"sig":"MEQCICvpujaJULTm5NyBI23kcyIdd4ri0bT/6dcB2a6vdnUoAiBUmlFpSjRWb6uFJzpVK+vX4varJPoXy8y25KSgd+/GbA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14129},"main":"dist/index.js","_from":"file:bernierllc-nevar-loop-detector-0.2.0.tgz","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"scripts":{"lint":"eslint src __tests__ --ext .ts","test":"jest","build":"tsc","clean":"rimraf dist","prebuild":"npm run clean","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:97499078-3391-46c1-87e8-c1bfcae5a393"}},"_resolved":"/home/runner/work/tools/tools/packages/core/nevar-loop-detector/bernierllc-nevar-loop-detector-0.2.0.tgz","_integrity":"sha512-b8gV1jiXlMHN4pyE9kMkw6PWCdyL4J2h+Qr+Dj7zcUVqZ5A3fljb2WtihdF7a54PiOd1drk5v//OAlhpdM4v8A==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/nevar-loop-detector"},"_npmVersion":"11.14.1","description":"Static loop analysis and runtime cycle detection for the Nevar rules engine","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@bernierllc/nevar-types":"0.2.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","rimraf":"^5.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/nevar-loop-detector_0.2.0_1779133545999_0.5794905220287296","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@bernierllc/nevar-loop-detector","version":"0.3.0","keywords":["nevar","rules-engine","loop-detection","cycle-detection","static-analysis"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","_id":"@bernierllc/nevar-loop-detector@0.3.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernierllc/tools#readme","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"dist":{"shasum":"ce53bb7ffd2af4cd957d47238d771ab6fba1748e","tarball":"https://registry.npmjs.org/@bernierllc/nevar-loop-detector/-/nevar-loop-detector-0.3.0.tgz","fileCount":10,"integrity":"sha512-/s8D8pnIaR2ocVrHpi1DZtEMK6XSOsL9YJHkzUVaU4OEAM7nezemTV5Rw6h/zoniKDbhNqeOIUq109ZQia8O9A==","signatures":[{"sig":"MEQCHwxg2ZIeD775qbTOlsba2jRNDhIYKFMJ6qXB2m+28CoCIQDfbCOdveqZL8jbcIz712zoYUaNyPLnr7DpTmsdkLTOZA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14129},"main":"dist/index.js","_from":"file:bernierllc-nevar-loop-detector-0.3.0.tgz","types":"dist/index.d.ts","engines":{"node":">=16.0.0"},"scripts":{"lint":"eslint src __tests__ --ext .ts","test":"jest","build":"tsc","clean":"rimraf dist","prebuild":"npm run clean","test:run":"jest","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:97499078-3391-46c1-87e8-c1bfcae5a393"}},"_resolved":"/home/runner/work/tools/tools/packages/core/nevar-loop-detector/bernierllc-nevar-loop-detector-0.3.0.tgz","_integrity":"sha512-/s8D8pnIaR2ocVrHpi1DZtEMK6XSOsL9YJHkzUVaU4OEAM7nezemTV5Rw6h/zoniKDbhNqeOIUq109ZQia8O9A==","repository":{"url":"git+https://github.com/bernierllc/tools.git","type":"git","directory":"packages/core/nevar-loop-detector"},"_npmVersion":"11.14.1","description":"Static loop analysis and runtime cycle detection for the Nevar rules engine","directories":{},"_nodeVersion":"20.20.2","dependencies":{"@bernierllc/nevar-types":"0.3.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","eslint":"^8.0.0","rimraf":"^5.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/parser":"^6.0.0","@typescript-eslint/eslint-plugin":"^6.0.0"},"_npmOperationalInternal":{"tmp":"tmp/nevar-loop-detector_0.3.0_1779241273260_0.9949418192832804","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@bernierllc/nevar-loop-detector","version":"0.4.0","description":"Static loop analysis and runtime cycle detection for the Nevar rules engine","main":"dist/index.js","types":"dist/index.d.ts","keywords":["nevar","rules-engine","loop-detection","cycle-detection","static-analysis"],"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"engines":{"node":">=16.0.0"},"repository":{"type":"git","url":"git+https://github.com/bernierllc/tools.git","directory":"packages/core/nevar-loop-detector"},"dependencies":{"@bernierllc/nevar-types":"0.4.0"},"devDependencies":{"@types/jest":"^29.5.0","@types/node":"^20.0.0","@typescript-eslint/eslint-plugin":"^6.0.0","@typescript-eslint/parser":"^6.0.0","eslint":"^8.0.0","jest":"^29.5.0","rimraf":"^5.0.0","ts-jest":"^29.1.0","typescript":"^5.0.0"},"scripts":{"build":"tsc","prebuild":"npm run clean","clean":"rimraf dist","test":"jest","test:run":"jest","test:coverage":"jest --coverage","lint":"eslint src __tests__ --ext .ts"},"_id":"@bernierllc/nevar-loop-detector@0.4.0","bugs":{"url":"https://github.com/bernierllc/tools/issues"},"homepage":"https://github.com/bernierllc/tools#readme","_integrity":"sha512-GHO42rxt+k8GvxRPUh7JP79VLiAdXjw0Z0hJZmy0cobLzXOzXGXMHhcSvoICO9MljYlXKbTxhWtUjFz+w37xqQ==","_resolved":"/home/runner/work/tools/tools/packages/core/nevar-loop-detector/bernierllc-nevar-loop-detector-0.4.0.tgz","_from":"file:bernierllc-nevar-loop-detector-0.4.0.tgz","_nodeVersion":"20.20.2","_npmVersion":"11.14.1","dist":{"integrity":"sha512-GHO42rxt+k8GvxRPUh7JP79VLiAdXjw0Z0hJZmy0cobLzXOzXGXMHhcSvoICO9MljYlXKbTxhWtUjFz+w37xqQ==","shasum":"e0c138d76119bfd9a3fab2135cd8ad228f0453f8","tarball":"https://registry.npmjs.org/@bernierllc/nevar-loop-detector/-/nevar-loop-detector-0.4.0.tgz","fileCount":10,"unpackedSize":14129,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHxL6p7tk7g+EvZR/LG5GIBnxNPh+Lsz0NZv/VwO2Qa2AiBhH9/zhMw31B6wPraI+dbKAExoY1IyPGTbA/CbXD5EYw=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:97499078-3391-46c1-87e8-c1bfcae5a393"}},"directories":{},"maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/nevar-loop-detector_0.4.0_1779250024117_0.9410821092456623"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-27T23:56:17.065Z","modified":"2026-05-20T04:07:04.469Z","0.0.1":"2026-03-27T23:56:17.271Z","0.1.0":"2026-03-30T19:15:47.756Z","0.2.0":"2026-05-18T19:45:46.141Z","0.3.0":"2026-05-20T01:41:13.404Z","0.4.0":"2026-05-20T04:07:04.309Z"},"bugs":{"url":"https://github.com/bernierllc/tools/issues"},"author":{"name":"Bernier LLC"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/bernierllc/tools#readme","keywords":["nevar","rules-engine","loop-detection","cycle-detection","static-analysis"],"repository":{"type":"git","url":"git+https://github.com/bernierllc/tools.git","directory":"packages/core/nevar-loop-detector"},"description":"Static loop analysis and runtime cycle detection for the Nevar rules engine","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"readme":"# @bernierllc/nevar-loop-detector\n\nStatic and runtime loop detection for the Nevar rules engine. Analyzes rule sets for potential evaluation cycles at registration time and tracks runtime emit chains.\n\n## Installation\n\n```bash\nnpm install @bernierllc/nevar-loop-detector\n```\n\n## Usage\n\n```typescript\nimport { LoopDetector, ChainTracker } from '@bernierllc/nevar-loop-detector';\nimport type { Rule } from '@bernierllc/nevar-types';\n\n// Static analysis: detect cycles in rule definitions\nconst detector = new LoopDetector();\nconst analysis = detector.analyze(rules);\n\nif (analysis.hasLoops) {\n  for (const loop of analysis.loops) {\n    console.log('Cycle:', loop.chain.join(' -> '));\n    console.log('All rules opted in:', loop.allOptedIn);\n    console.log('Rule IDs:', loop.ruleIds);\n  }\n}\n\n// Runtime tracking: detect cycles during emit chain execution\nconst tracker = new ChainTracker();\n\nconst isCycle = tracker.enter('order.created', 'ctx-123');\nif (isCycle) {\n  // This trigger+context pair was already seen in this chain\n}\n\nconsole.log(tracker.getDepth()); // current chain depth\ntracker.reset(); // clear for next chain\n```\n\n## API\n\n### `LoopDetector`\n\nStatic loop analysis for rule sets. Builds a graph of trigger-to-deferred-trigger relationships and detects cycles using depth-first search.\n\n- `analyze(rules: Rule[])` - Returns a `LoopAnalysis` with `hasLoops: boolean` and `loops: DetectedLoop[]`. Each `DetectedLoop` contains the `chain` of trigger keys forming the cycle, `ruleIds` involved, and whether `allOptedIn` to looping.\n\n### `ChainTracker`\n\nRuntime cycle detection for emit chains. Tracks `(triggerKey, contextId)` pairs within a single emit chain.\n\n- `enter(triggerKey, contextId)` - Records entry into a trigger evaluation. Returns `true` if a cycle is detected (pair already seen), `false` on first occurrence\n- `getDepth()` - Returns the current chain depth\n- `reset()` - Clears all recorded entries and resets depth\n\n### `LoopDetectorError`\n\nError class for loop detection failures. Extends `Error` with `code` and `context` properties.\n\n## Integration Documentation\n\n### Logger Integration\nThis package does not integrate with `@bernierllc/logger`. As a core package, logger integration is optional and not included by default. Consumers should handle logging at the service layer.\n\n### NeverHub Integration\nThis package does not integrate with `@bernierllc/neverhub-adapter`. As a core package, NeverHub integration is not applicable. NeverHub registration should be handled by service-layer packages that compose this package.\n\n## License\n\nCopyright (c) 2025 Bernier LLC. All rights reserved.\n","readmeFilename":"README.md"}