eslint-plugin-runtime-cleanup 1.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +117 -0
  4. package/dist/_internal/ast-node.d.ts +19 -0
  5. package/dist/_internal/ast-node.d.ts.map +1 -0
  6. package/dist/_internal/ast-node.js +42 -0
  7. package/dist/_internal/ast-node.js.map +1 -0
  8. package/dist/_internal/bounded-cache.d.ts +37 -0
  9. package/dist/_internal/bounded-cache.d.ts.map +1 -0
  10. package/dist/_internal/bounded-cache.js +63 -0
  11. package/dist/_internal/bounded-cache.js.map +1 -0
  12. package/dist/_internal/cycle-safe-linked-search.d.ts +48 -0
  13. package/dist/_internal/cycle-safe-linked-search.d.ts.map +1 -0
  14. package/dist/_internal/cycle-safe-linked-search.js +70 -0
  15. package/dist/_internal/cycle-safe-linked-search.js.map +1 -0
  16. package/dist/_internal/expression-boolean-memoizer.d.ts +17 -0
  17. package/dist/_internal/expression-boolean-memoizer.d.ts.map +1 -0
  18. package/dist/_internal/expression-boolean-memoizer.js +22 -0
  19. package/dist/_internal/expression-boolean-memoizer.js.map +1 -0
  20. package/dist/_internal/filter-callback.d.ts +52 -0
  21. package/dist/_internal/filter-callback.d.ts.map +1 -0
  22. package/dist/_internal/filter-callback.js +108 -0
  23. package/dist/_internal/filter-callback.js.map +1 -0
  24. package/dist/_internal/floating-resource.d.ts +29 -0
  25. package/dist/_internal/floating-resource.d.ts.map +1 -0
  26. package/dist/_internal/floating-resource.js +114 -0
  27. package/dist/_internal/floating-resource.js.map +1 -0
  28. package/dist/_internal/member-call.d.ts +53 -0
  29. package/dist/_internal/member-call.d.ts.map +1 -0
  30. package/dist/_internal/member-call.js +61 -0
  31. package/dist/_internal/member-call.js.map +1 -0
  32. package/dist/_internal/normalize-expression-text.d.ts +21 -0
  33. package/dist/_internal/normalize-expression-text.d.ts.map +1 -0
  34. package/dist/_internal/normalize-expression-text.js +186 -0
  35. package/dist/_internal/normalize-expression-text.js.map +1 -0
  36. package/dist/_internal/nullish-comparison.d.ts +44 -0
  37. package/dist/_internal/nullish-comparison.d.ts.map +1 -0
  38. package/dist/_internal/nullish-comparison.js +162 -0
  39. package/dist/_internal/nullish-comparison.js.map +1 -0
  40. package/dist/_internal/plugin-settings.d.ts +30 -0
  41. package/dist/_internal/plugin-settings.d.ts.map +1 -0
  42. package/dist/_internal/plugin-settings.js +90 -0
  43. package/dist/_internal/plugin-settings.js.map +1 -0
  44. package/dist/_internal/report-adapter.d.ts +24 -0
  45. package/dist/_internal/report-adapter.d.ts.map +1 -0
  46. package/dist/_internal/report-adapter.js +35 -0
  47. package/dist/_internal/report-adapter.js.map +1 -0
  48. package/dist/_internal/rule-catalog.d.ts +47 -0
  49. package/dist/_internal/rule-catalog.d.ts.map +1 -0
  50. package/dist/_internal/rule-catalog.js +97 -0
  51. package/dist/_internal/rule-catalog.js.map +1 -0
  52. package/dist/_internal/rule-docs-metadata.d.ts +35 -0
  53. package/dist/_internal/rule-docs-metadata.d.ts.map +1 -0
  54. package/dist/_internal/rule-docs-metadata.js +172 -0
  55. package/dist/_internal/rule-docs-metadata.js.map +1 -0
  56. package/dist/_internal/rule-docs-url.d.ts +15 -0
  57. package/dist/_internal/rule-docs-url.d.ts.map +1 -0
  58. package/dist/_internal/rule-docs-url.js +15 -0
  59. package/dist/_internal/rule-docs-url.js.map +1 -0
  60. package/dist/_internal/rules-registry.d.ts +11 -0
  61. package/dist/_internal/rules-registry.d.ts.map +1 -0
  62. package/dist/_internal/rules-registry.js +53 -0
  63. package/dist/_internal/rules-registry.js.map +1 -0
  64. package/dist/_internal/runtime-cleanup-config-references.d.ts +38 -0
  65. package/dist/_internal/runtime-cleanup-config-references.d.ts.map +1 -0
  66. package/dist/_internal/runtime-cleanup-config-references.js +78 -0
  67. package/dist/_internal/runtime-cleanup-config-references.js.map +1 -0
  68. package/dist/_internal/safe-type-operation.d.ts +89 -0
  69. package/dist/_internal/safe-type-operation.d.ts.map +1 -0
  70. package/dist/_internal/safe-type-operation.js +147 -0
  71. package/dist/_internal/safe-type-operation.js.map +1 -0
  72. package/dist/_internal/scope-variable.d.ts +17 -0
  73. package/dist/_internal/scope-variable.d.ts.map +1 -0
  74. package/dist/_internal/scope-variable.js +30 -0
  75. package/dist/_internal/scope-variable.js.map +1 -0
  76. package/dist/_internal/type-checker.d.ts +11 -0
  77. package/dist/_internal/type-checker.d.ts.map +1 -0
  78. package/dist/_internal/type-checker.js +25 -0
  79. package/dist/_internal/type-checker.js.map +1 -0
  80. package/dist/_internal/type-predicate-autofix-safety.d.ts +16 -0
  81. package/dist/_internal/type-predicate-autofix-safety.d.ts.map +1 -0
  82. package/dist/_internal/type-predicate-autofix-safety.js +54 -0
  83. package/dist/_internal/type-predicate-autofix-safety.js.map +1 -0
  84. package/dist/_internal/type-reference-node.d.ts +23 -0
  85. package/dist/_internal/type-reference-node.d.ts.map +1 -0
  86. package/dist/_internal/type-reference-node.js +41 -0
  87. package/dist/_internal/type-reference-node.js.map +1 -0
  88. package/dist/_internal/typed-rule.d.ts +91 -0
  89. package/dist/_internal/typed-rule.d.ts.map +1 -0
  90. package/dist/_internal/typed-rule.js +121 -0
  91. package/dist/_internal/typed-rule.js.map +1 -0
  92. package/dist/_internal/value-rewrite-autofix-safety.d.ts +29 -0
  93. package/dist/_internal/value-rewrite-autofix-safety.d.ts.map +1 -0
  94. package/dist/_internal/value-rewrite-autofix-safety.js +108 -0
  95. package/dist/_internal/value-rewrite-autofix-safety.js.map +1 -0
  96. package/dist/plugin.cjs +3693 -0
  97. package/dist/plugin.cjs.map +7 -0
  98. package/dist/plugin.d.cts +75 -0
  99. package/dist/plugin.d.ts +75 -0
  100. package/dist/plugin.d.ts.map +1 -0
  101. package/dist/plugin.js +223 -0
  102. package/dist/plugin.js.map +1 -0
  103. package/dist/rules/no-floating-abort-controllers.d.ts +9 -0
  104. package/dist/rules/no-floating-abort-controllers.d.ts.map +1 -0
  105. package/dist/rules/no-floating-abort-controllers.js +144 -0
  106. package/dist/rules/no-floating-abort-controllers.js.map +1 -0
  107. package/dist/rules/no-floating-audio-contexts.d.ts +9 -0
  108. package/dist/rules/no-floating-audio-contexts.d.ts.map +1 -0
  109. package/dist/rules/no-floating-audio-contexts.js +95 -0
  110. package/dist/rules/no-floating-audio-contexts.js.map +1 -0
  111. package/dist/rules/no-floating-broadcast-channels.d.ts +9 -0
  112. package/dist/rules/no-floating-broadcast-channels.d.ts.map +1 -0
  113. package/dist/rules/no-floating-broadcast-channels.js +151 -0
  114. package/dist/rules/no-floating-broadcast-channels.js.map +1 -0
  115. package/dist/rules/no-floating-child-processes.d.ts +9 -0
  116. package/dist/rules/no-floating-child-processes.d.ts.map +1 -0
  117. package/dist/rules/no-floating-child-processes.js +259 -0
  118. package/dist/rules/no-floating-child-processes.js.map +1 -0
  119. package/dist/rules/no-floating-disposable-stacks.d.ts +9 -0
  120. package/dist/rules/no-floating-disposable-stacks.d.ts.map +1 -0
  121. package/dist/rules/no-floating-disposable-stacks.js +177 -0
  122. package/dist/rules/no-floating-disposable-stacks.js.map +1 -0
  123. package/dist/rules/no-floating-file-watchers.d.ts +9 -0
  124. package/dist/rules/no-floating-file-watchers.d.ts.map +1 -0
  125. package/dist/rules/no-floating-file-watchers.js +241 -0
  126. package/dist/rules/no-floating-file-watchers.js.map +1 -0
  127. package/dist/rules/no-floating-geolocation-watches.d.ts +9 -0
  128. package/dist/rules/no-floating-geolocation-watches.d.ts.map +1 -0
  129. package/dist/rules/no-floating-geolocation-watches.js +156 -0
  130. package/dist/rules/no-floating-geolocation-watches.js.map +1 -0
  131. package/dist/rules/no-floating-infinite-animations.d.ts +9 -0
  132. package/dist/rules/no-floating-infinite-animations.d.ts.map +1 -0
  133. package/dist/rules/no-floating-infinite-animations.js +131 -0
  134. package/dist/rules/no-floating-infinite-animations.js.map +1 -0
  135. package/dist/rules/no-floating-media-streams.d.ts +9 -0
  136. package/dist/rules/no-floating-media-streams.d.ts.map +1 -0
  137. package/dist/rules/no-floating-media-streams.js +175 -0
  138. package/dist/rules/no-floating-media-streams.js.map +1 -0
  139. package/dist/rules/no-floating-message-channels.d.ts +9 -0
  140. package/dist/rules/no-floating-message-channels.d.ts.map +1 -0
  141. package/dist/rules/no-floating-message-channels.js +150 -0
  142. package/dist/rules/no-floating-message-channels.js.map +1 -0
  143. package/dist/rules/no-floating-network-connections.d.ts +9 -0
  144. package/dist/rules/no-floating-network-connections.d.ts.map +1 -0
  145. package/dist/rules/no-floating-network-connections.js +170 -0
  146. package/dist/rules/no-floating-network-connections.js.map +1 -0
  147. package/dist/rules/no-floating-object-urls.d.ts +9 -0
  148. package/dist/rules/no-floating-object-urls.d.ts.map +1 -0
  149. package/dist/rules/no-floating-object-urls.js +83 -0
  150. package/dist/rules/no-floating-object-urls.js.map +1 -0
  151. package/dist/rules/no-floating-observers.d.ts +9 -0
  152. package/dist/rules/no-floating-observers.d.ts.map +1 -0
  153. package/dist/rules/no-floating-observers.js +160 -0
  154. package/dist/rules/no-floating-observers.js.map +1 -0
  155. package/dist/rules/no-floating-servers.d.ts +9 -0
  156. package/dist/rules/no-floating-servers.d.ts.map +1 -0
  157. package/dist/rules/no-floating-servers.js +282 -0
  158. package/dist/rules/no-floating-servers.js.map +1 -0
  159. package/dist/rules/no-floating-streams.d.ts +9 -0
  160. package/dist/rules/no-floating-streams.d.ts.map +1 -0
  161. package/dist/rules/no-floating-streams.js +222 -0
  162. package/dist/rules/no-floating-streams.js.map +1 -0
  163. package/dist/rules/no-floating-timers.d.ts +9 -0
  164. package/dist/rules/no-floating-timers.d.ts.map +1 -0
  165. package/dist/rules/no-floating-timers.js +145 -0
  166. package/dist/rules/no-floating-timers.js.map +1 -0
  167. package/dist/rules/no-floating-wake-locks.d.ts +9 -0
  168. package/dist/rules/no-floating-wake-locks.d.ts.map +1 -0
  169. package/dist/rules/no-floating-wake-locks.js +159 -0
  170. package/dist/rules/no-floating-wake-locks.js.map +1 -0
  171. package/dist/rules/no-floating-web-stream-locks.d.ts +9 -0
  172. package/dist/rules/no-floating-web-stream-locks.d.ts.map +1 -0
  173. package/dist/rules/no-floating-web-stream-locks.js +87 -0
  174. package/dist/rules/no-floating-web-stream-locks.js.map +1 -0
  175. package/dist/rules/no-floating-workers.d.ts +9 -0
  176. package/dist/rules/no-floating-workers.d.ts.map +1 -0
  177. package/dist/rules/no-floating-workers.js +185 -0
  178. package/dist/rules/no-floating-workers.js.map +1 -0
  179. package/dist/rules/no-unmanaged-event-listeners.d.ts +9 -0
  180. package/dist/rules/no-unmanaged-event-listeners.d.ts.map +1 -0
  181. package/dist/rules/no-unmanaged-event-listeners.js +210 -0
  182. package/dist/rules/no-unmanaged-event-listeners.js.map +1 -0
  183. package/docs/rules/getting-started.md +29 -0
  184. package/docs/rules/guides/adoption-checklist.md +31 -0
  185. package/docs/rules/guides/preset-selection-strategy.md +24 -0
  186. package/docs/rules/guides/rollout-and-fix-safety.md +42 -0
  187. package/docs/rules/guides/snapshot-testing.md +20 -0
  188. package/docs/rules/guides/type-aware-linting-readiness.md +20 -0
  189. package/docs/rules/no-floating-abort-controllers.md +126 -0
  190. package/docs/rules/no-floating-audio-contexts.md +104 -0
  191. package/docs/rules/no-floating-broadcast-channels.md +105 -0
  192. package/docs/rules/no-floating-child-processes.md +123 -0
  193. package/docs/rules/no-floating-disposable-stacks.md +118 -0
  194. package/docs/rules/no-floating-file-watchers.md +111 -0
  195. package/docs/rules/no-floating-geolocation-watches.md +95 -0
  196. package/docs/rules/no-floating-infinite-animations.md +110 -0
  197. package/docs/rules/no-floating-media-streams.md +113 -0
  198. package/docs/rules/no-floating-message-channels.md +114 -0
  199. package/docs/rules/no-floating-network-connections.md +116 -0
  200. package/docs/rules/no-floating-object-urls.md +102 -0
  201. package/docs/rules/no-floating-observers.md +108 -0
  202. package/docs/rules/no-floating-servers.md +127 -0
  203. package/docs/rules/no-floating-streams.md +120 -0
  204. package/docs/rules/no-floating-timers.md +120 -0
  205. package/docs/rules/no-floating-wake-locks.md +109 -0
  206. package/docs/rules/no-floating-web-stream-locks.md +105 -0
  207. package/docs/rules/no-floating-workers.md +123 -0
  208. package/docs/rules/no-unmanaged-event-listeners.md +143 -0
  209. package/docs/rules/overview.md +44 -0
  210. package/docs/rules/presets/all.md +35 -0
  211. package/docs/rules/presets/experimental.md +44 -0
  212. package/docs/rules/presets/index.md +54 -0
  213. package/docs/rules/presets/minimal.md +17 -0
  214. package/docs/rules/presets/recommended-type-checked.md +43 -0
  215. package/docs/rules/presets/recommended.md +34 -0
  216. package/docs/rules/presets/strict.md +36 -0
  217. package/package.json +323 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # Changelog
2
+
3
+ All notable changes to `eslint-plugin-runtime-cleanup` will be documented in this file.
4
+
5
+ This repository was scaffolded from a mature ESLint plugin template and is now
6
+ owned by the runtime-cleanup plugin identity. Historical template release notes
7
+ were intentionally removed because they described unrelated rule behavior.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nick2bad4u
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # eslint-plugin-runtime-cleanup
2
+
3
+ [![npm license.](https://flat.badgen.net/npm/license/eslint-plugin-runtime-cleanup?color=purple)](https://github.com/Nick2bad4u/eslint-plugin-runtime-cleanup/blob/main/LICENSE) [![npm total downloads.](https://flat.badgen.net/npm/dt/eslint-plugin-runtime-cleanup?color=pink)](https://www.npmjs.com/package/eslint-plugin-runtime-cleanup) [![latest GitHub release.](https://flat.badgen.net/github/release/Nick2bad4u/eslint-plugin-runtime-cleanup?color=cyan)](https://github.com/Nick2bad4u/eslint-plugin-runtime-cleanup/releases) [![GitHub stars.](https://flat.badgen.net/github/stars/Nick2bad4u/eslint-plugin-runtime-cleanup?color=yellow)](https://github.com/Nick2bad4u/eslint-plugin-runtime-cleanup/stargazers) [![GitHub forks.](https://flat.badgen.net/github/forks/Nick2bad4u/eslint-plugin-runtime-cleanup?color=green)](https://github.com/Nick2bad4u/eslint-plugin-runtime-cleanup/forks) [![GitHub open issues.](https://flat.badgen.net/github/open-issues/Nick2bad4u/eslint-plugin-runtime-cleanup?color=red)](https://github.com/Nick2bad4u/eslint-plugin-runtime-cleanup/issues) [![codecov.](https://codecov.io/gh/Nick2bad4u/eslint-plugin-runtime-cleanup/branch/main/graph/badge.svg)](https://codecov.io/gh/Nick2bad4u/eslint-plugin-runtime-cleanup)
4
+
5
+ ESLint plugin scaffold for rules that require explicit cleanup of runtime
6
+ resources such as timers, event listeners, observers, abort controllers,
7
+ workers, streams, child processes, and disposable handles.
8
+
9
+ This repository has been converted from the shared modern ESLint plugin
10
+ template. It intentionally does not publish speculative rules yet. The runtime,
11
+ preset surfaces, documentation structure, tests, and release gates are in place
12
+ so concrete cleanup rules can be added without carrying over template-specific
13
+ rule behavior.
14
+
15
+ ## Install
16
+
17
+ ```sh
18
+ npm install --save-dev eslint-plugin-runtime-cleanup typescript
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ ```js
24
+ import runtimeCleanup from "eslint-plugin-runtime-cleanup";
25
+
26
+ export default [runtimeCleanup.configs.recommended];
27
+ ```
28
+
29
+ The initial presets contain no rules. They exist so consumers can adopt the
30
+ package shape early and so future rules can land behind stable config keys.
31
+
32
+ ## Presets
33
+
34
+ | Preset | Purpose |
35
+ | ----------------------------------------------------- | ------------------------------------------------------------------ |
36
+ | `runtime-cleanup.configs.minimal` | Reserved for low-noise cleanup checks. |
37
+ | `runtime-cleanup.configs.recommended` | Reserved for broadly safe cleanup checks. |
38
+ | `runtime-cleanup.configs["recommended-type-checked"]` | Reserved for cleanup checks that need TypeScript type information. |
39
+ | `runtime-cleanup.configs.strict` | Reserved for stricter cleanup enforcement. |
40
+ | `runtime-cleanup.configs.all` | Reserved for all stable cleanup rules. |
41
+ | `runtime-cleanup.configs.experimental` | Reserved for rules still proving out behavior or fix safety. |
42
+
43
+ ## Rules
44
+
45
+ Runtime-cleanup rules are listed below. Each rule documents the exact resource-lifetime pattern it enforces.
46
+
47
+ - `Fix` legend:
48
+ - `fix` = autofixable
49
+ - `suggest` = suggestions available
50
+ - `-` = report only
51
+ - `Preset key` legend:
52
+ - [M](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/minimal) - [`runtime-cleanup.configs.minimal`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/minimal)
53
+ - [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) - [`runtime-cleanup.configs.recommended`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended)
54
+ - [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) - [`runtime-cleanup.configs["recommended-type-checked"]`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked)
55
+ - [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) - [`runtime-cleanup.configs.strict`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict)
56
+ - [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) - [`runtime-cleanup.configs.all`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all)
57
+ - [E](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/experimental) - [`runtime-cleanup.configs.experimental`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/experimental)
58
+
59
+ | Rule | Fix | Preset key |
60
+ | --- | :-: | :-- |
61
+ | [`no-floating-abort-controllers`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-abort-controllers) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
62
+ | [`no-floating-audio-contexts`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-audio-contexts) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
63
+ | [`no-floating-broadcast-channels`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-broadcast-channels) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
64
+ | [`no-floating-child-processes`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-child-processes) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
65
+ | [`no-floating-disposable-stacks`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-disposable-stacks) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
66
+ | [`no-floating-file-watchers`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-file-watchers) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
67
+ | [`no-floating-geolocation-watches`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-geolocation-watches) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
68
+ | [`no-floating-infinite-animations`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-infinite-animations) | - | [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
69
+ | [`no-floating-media-streams`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-media-streams) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
70
+ | [`no-floating-message-channels`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-message-channels) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
71
+ | [`no-floating-network-connections`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-network-connections) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
72
+ | [`no-floating-object-urls`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-object-urls) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
73
+ | [`no-floating-observers`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-observers) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
74
+ | [`no-floating-servers`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-servers) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
75
+ | [`no-floating-streams`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-streams) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
76
+ | [`no-floating-timers`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-timers) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
77
+ | [`no-floating-wake-locks`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-wake-locks) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
78
+ | [`no-floating-web-stream-locks`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-web-stream-locks) | - | [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
79
+ | [`no-floating-workers`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-floating-workers) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
80
+ | [`no-unmanaged-event-listeners`](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/no-unmanaged-event-listeners) | - | [R](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended) [T](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/recommended-type-checked) [S](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/strict) [A](https://nick2bad4u.github.io/eslint-plugin-runtime-cleanup/docs/rules/presets/all) |
81
+
82
+ ## Rule Roadmap
83
+
84
+ The plugin is intended to cover resource lifetime hazards where missed cleanup
85
+ causes leaks, duplicate work, stuck processes, or stale callbacks. Concrete
86
+ rules should be added only when the AST strategy, false-positive boundaries,
87
+ and fix/suggestion behavior are explicit.
88
+
89
+ Likely future rule families:
90
+
91
+ - timers created by `setTimeout`, `setInterval`, and related scheduling APIs
92
+ - event listeners that need matching `removeEventListener` calls or signal
93
+ cleanup
94
+ - observers such as `MutationObserver`, `ResizeObserver`, and
95
+ `IntersectionObserver`
96
+ - `AbortController` and `AbortSignal` lifecycle management
97
+ - workers, streams, child processes, and disposable handles
98
+
99
+ ## Development
100
+
101
+ ```sh
102
+ npm run build
103
+ npm run typecheck
104
+ npm run test
105
+ npm run lint:nocache
106
+ ```
107
+
108
+ The release gate is:
109
+
110
+ ```sh
111
+ npm run release:verify
112
+ ```
113
+
114
+ ## Documentation
115
+
116
+ The Docusaurus documentation site lives under `docs/docusaurus` and consumes
117
+ the hand-authored rule and preset docs under `docs/rules`.
@@ -0,0 +1,19 @@
1
+ import type { TSESTree } from "@typescript-eslint/utils";
2
+ /**
3
+ * Gets a node's parent reference when available.
4
+ *
5
+ * @param node - AST node whose parent should be read.
6
+ *
7
+ * @returns Parent node when present on parser output; otherwise `undefined`.
8
+ */
9
+ export declare const getParentNode: (node: Readonly<TSESTree.Node>) => Readonly<TSESTree.Node> | undefined;
10
+ /**
11
+ * Walks the parent chain to locate the enclosing `Program` node.
12
+ *
13
+ * @param node - Starting AST node.
14
+ *
15
+ * @returns Nearest enclosing `Program` node; otherwise `null` when no program
16
+ * boundary can be reached (including cycle-guard termination).
17
+ */
18
+ export declare const getProgramNode: (node: Readonly<TSESTree.Node>) => null | Readonly<TSESTree.Program>;
19
+ //# sourceMappingURL=ast-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast-node.d.ts","sourceRoot":"","sources":["../../src/_internal/ast-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAwBzD;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GACtB,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,KAC9B,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,SACgC,CAAC;AAE9D;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GACvB,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,KAC9B,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAqBlC,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * AST parent-chain traversal helpers used by multiple rule utilities.
4
+ */
5
+ import { AST_NODE_TYPES } from "@typescript-eslint/utils";
6
+ import { resolveFirstValueInLinkedStructure } from "./cycle-safe-linked-search.js";
7
+ /**
8
+ * Determine whether a node exposes an optional `parent` property.
9
+ */
10
+ const hasOptionalParentProperty = (node) => "parent" in node;
11
+ /**
12
+ * Gets a node's parent reference when available.
13
+ *
14
+ * @param node - AST node whose parent should be read.
15
+ *
16
+ * @returns Parent node when present on parser output; otherwise `undefined`.
17
+ */
18
+ export const getParentNode = (node) => hasOptionalParentProperty(node) ? node.parent : undefined;
19
+ /**
20
+ * Walks the parent chain to locate the enclosing `Program` node.
21
+ *
22
+ * @param node - Starting AST node.
23
+ *
24
+ * @returns Nearest enclosing `Program` node; otherwise `null` when no program
25
+ * boundary can be reached (including cycle-guard termination).
26
+ */
27
+ export const getProgramNode = (node) => {
28
+ const lookupResult = resolveFirstValueInLinkedStructure({
29
+ getNextNode: (currentNode) => getParentNode(currentNode) ?? null,
30
+ resolveValue: (currentNode) => currentNode.type === AST_NODE_TYPES.Program
31
+ ? {
32
+ found: true,
33
+ value: currentNode,
34
+ }
35
+ : {
36
+ found: false,
37
+ },
38
+ startNode: node,
39
+ });
40
+ return lookupResult.found ? lookupResult.value : null;
41
+ };
42
+ //# sourceMappingURL=ast-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ast-node.js","sourceRoot":"","sources":["../../src/_internal/ast-node.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,kCAAkC,EAAE,MAAM,+BAA+B,CAAC;AASnF;;GAEG;AACH,MAAM,yBAAyB,GAAG,CAC9B,IAA6B,EACC,EAAE,CAAC,QAAQ,IAAI,IAAI,CAAC;AAEtD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CACzB,IAA6B,EACM,EAAE,CACrC,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC1B,IAA6B,EACI,EAAE;IACnC,MAAM,YAAY,GAAG,kCAAkC,CAGrD;QACE,WAAW,EAAE,CACT,WAAoC,EACN,EAAE,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,IAAI;QACvE,YAAY,EAAE,CAAC,WAAoC,EAAE,EAAE,CACnD,WAAW,CAAC,IAAI,KAAK,cAAc,CAAC,OAAO;YACvC,CAAC,CAAC;gBACI,KAAK,EAAE,IAAI;gBACX,KAAK,EAAE,WAAW;aACrB;YACH,CAAC,CAAC;gBACI,KAAK,EAAE,KAAK;aACf;QACX,SAAS,EAAE,IAAI;KAClB,CAAC,CAAC;IAEH,OAAO,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1D,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Result shape returned by bounded-cache lookups.
3
+ */
4
+ export type BoundedCacheLookupResult<Value> = Readonly<{
5
+ found: false;
6
+ }> | Readonly<{
7
+ found: true;
8
+ value: Value;
9
+ }>;
10
+ /**
11
+ * Read a cache entry and mark it as most-recently-used.
12
+ *
13
+ * @param cache - Mutable cache map.
14
+ * @param key - Entry key.
15
+ *
16
+ * @returns Lookup result describing whether an entry was found. When found,
17
+ * includes the cached value (which can itself be `undefined`/`null`).
18
+ */
19
+ export declare const getBoundedCacheValue: <Key, Value>(cache: Map<Key, Value>, key: Key) => BoundedCacheLookupResult<Value>;
20
+ /**
21
+ * Insert or update a cache entry and evict least-recently-used entries beyond
22
+ * the configured max size.
23
+ *
24
+ * @param options - Bounded-cache insertion options.
25
+ *
26
+ * - `cache`: Mutable cache map.
27
+ * - `key`: Entry key.
28
+ * - `maxEntries`: Maximum number of cache entries to retain.
29
+ * - `value`: Entry value.
30
+ */
31
+ export declare const setBoundedCacheValue: <Key, Value>({ cache, key, maxEntries, value, }: Readonly<{
32
+ cache: Map<Key, Value>;
33
+ key: Key;
34
+ maxEntries: number;
35
+ value: Value;
36
+ }>) => void;
37
+ //# sourceMappingURL=bounded-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bounded-cache.d.ts","sourceRoot":"","sources":["../../src/_internal/bounded-cache.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,MAAM,MAAM,wBAAwB,CAAC,KAAK,IACpC,QAAQ,CAAC;IACL,KAAK,EAAE,KAAK,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACL,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC;CAChB,CAAC,CAAC;AAET;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,GAAI,GAAG,EAAE,KAAK,EAC3C,OAAO,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EACtB,KAAK,GAAG,KACT,wBAAwB,CAAC,KAAK,CAgBhC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,GAAI,GAAG,EAAE,KAAK,EAAE,oCAK9C,QAAQ,CAAC;IACR,KAAK,EAAE,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACvB,GAAG,EAAE,GAAG,CAAC;IACT,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;CAChB,CAAC,KAAG,IAoBJ,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Shared bounded-cache helpers with lightweight LRU semantics for hot-path
3
+ * parser/type-analysis caches.
4
+ *
5
+ * @packageDocumentation
6
+ */
7
+ const isSameValueZero = (left, right) => left === right ||
8
+ (typeof left === "number" &&
9
+ typeof right === "number" &&
10
+ Number.isNaN(left) &&
11
+ Number.isNaN(right));
12
+ /**
13
+ * Read a cache entry and mark it as most-recently-used.
14
+ *
15
+ * @param cache - Mutable cache map.
16
+ * @param key - Entry key.
17
+ *
18
+ * @returns Lookup result describing whether an entry was found. When found,
19
+ * includes the cached value (which can itself be `undefined`/`null`).
20
+ */
21
+ export const getBoundedCacheValue = (cache, key) => {
22
+ for (const [entryKey, value] of cache) {
23
+ if (isSameValueZero(entryKey, key)) {
24
+ cache.delete(key);
25
+ cache.set(key, value);
26
+ return {
27
+ found: true,
28
+ value,
29
+ };
30
+ }
31
+ }
32
+ return {
33
+ found: false,
34
+ };
35
+ };
36
+ /**
37
+ * Insert or update a cache entry and evict least-recently-used entries beyond
38
+ * the configured max size.
39
+ *
40
+ * @param options - Bounded-cache insertion options.
41
+ *
42
+ * - `cache`: Mutable cache map.
43
+ * - `key`: Entry key.
44
+ * - `maxEntries`: Maximum number of cache entries to retain.
45
+ * - `value`: Entry value.
46
+ */
47
+ export const setBoundedCacheValue = ({ cache, key, maxEntries, value, }) => {
48
+ if (!Number.isSafeInteger(maxEntries) || maxEntries < 1) {
49
+ return;
50
+ }
51
+ if (cache.has(key)) {
52
+ cache.delete(key);
53
+ }
54
+ cache.set(key, value);
55
+ while (cache.size > maxEntries) {
56
+ const oldestEntry = cache.keys().next();
57
+ if (oldestEntry.done === true) {
58
+ return;
59
+ }
60
+ cache.delete(oldestEntry.value);
61
+ }
62
+ };
63
+ //# sourceMappingURL=bounded-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bounded-cache.js","sourceRoot":"","sources":["../../src/_internal/bounded-cache.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,eAAe,GAAG,CAAQ,IAAW,EAAE,KAAY,EAAW,EAAE,CAClE,IAAI,KAAK,KAAK;IACd,CAAC,OAAO,IAAI,KAAK,QAAQ;QACrB,OAAO,KAAK,KAAK,QAAQ;QACzB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;QAClB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAc7B;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAChC,KAAsB,EACtB,GAAQ,EACuB,EAAE;IACjC,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;QACpC,IAAI,eAAe,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;YACjC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAEtB,OAAO;gBACH,KAAK,EAAE,IAAI;gBACX,KAAK;aACR,CAAC;QACN,CAAC;IACL,CAAC;IAED,OAAO;QACH,KAAK,EAAE,KAAK;KACf,CAAC;AACN,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAa,EAC7C,KAAK,EACL,GAAG,EACH,UAAU,EACV,KAAK,GAMP,EAAQ,EAAE;IACR,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACtD,OAAO;IACX,CAAC;IAED,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACjB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEtB,OAAO,KAAK,CAAC,IAAI,GAAG,UAAU,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QAExC,IAAI,WAAW,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAC5B,OAAO;QACX,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Shared Floyd-cycle-guarded linked-structure traversal utilities.
4
+ */
5
+ /**
6
+ * Result shape returned by linked-structure searches.
7
+ */
8
+ export type LinkedStructureLookupResult<Value> = Readonly<{
9
+ found: false;
10
+ }> | Readonly<{
11
+ found: true;
12
+ value: Value;
13
+ }>;
14
+ /**
15
+ * Resolve the first matching value while traversing a linked structure.
16
+ *
17
+ * @param options - Linked-structure traversal options.
18
+ *
19
+ * - `startNode`: Initial node to inspect.
20
+ * - `getNextNode`: Function that returns the next node in the chain.
21
+ * - `resolveValue`: Function that returns a lookup result for the current node.
22
+ *
23
+ * @returns Lookup result for the first resolved value; otherwise a non-matching
24
+ * lookup result when traversal reaches the chain end or detects a
25
+ * parent-cycle.
26
+ */
27
+ export declare const resolveFirstValueInLinkedStructure: <Node, Value>({ getNextNode, resolveValue, startNode, }: Readonly<{
28
+ getNextNode: (node: Node) => Node | null;
29
+ resolveValue: (node: Node) => LinkedStructureLookupResult<Value>;
30
+ startNode: Node | null;
31
+ }>) => LinkedStructureLookupResult<Value>;
32
+ /**
33
+ * Check whether any node in a linked structure satisfies a predicate.
34
+ *
35
+ * @param options - Linked-structure traversal options.
36
+ *
37
+ * - `startNode`: Initial node to inspect.
38
+ * - `getNextNode`: Function that returns the next node in the chain.
39
+ * - `isMatch`: Predicate used to test each visited node.
40
+ *
41
+ * @returns `true` when any visited node matches; otherwise `false`.
42
+ */
43
+ export declare const isAnyLinkedStructureNodeMatching: <Node>({ getNextNode, isMatch, startNode, }: Readonly<{
44
+ getNextNode: (node: Node) => Node | null;
45
+ isMatch: (node: Node) => boolean;
46
+ startNode: Node | null;
47
+ }>) => boolean;
48
+ //# sourceMappingURL=cycle-safe-linked-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cycle-safe-linked-search.d.ts","sourceRoot":"","sources":["../../src/_internal/cycle-safe-linked-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,MAAM,2BAA2B,CAAC,KAAK,IACvC,QAAQ,CAAC;IACL,KAAK,EAAE,KAAK,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACL,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,KAAK,CAAC;CAChB,CAAC,CAAC;AAOT;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kCAAkC,GAAI,IAAI,EAAE,KAAK,EAAE,2CAI7D,QAAQ,CAAC;IACR,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;IACzC,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,2BAA2B,CAAC,KAAK,CAAC,CAAC;IACjE,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;CAC1B,CAAC,KAAG,2BAA2B,CAAC,KAAK,CA+BrC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gCAAgC,GAAI,IAAI,EAAE,sCAIpD,QAAQ,CAAC;IACR,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC;IACzC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IACjC,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;CAC1B,CAAC,KAAG,OAaO,CAAC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Shared Floyd-cycle-guarded linked-structure traversal utilities.
4
+ */
5
+ /**
6
+ * Fast-pointer hop count per iteration for Floyd cycle detection.
7
+ */
8
+ const FLOYD_FAST_POINTER_ADVANCE_STEPS = 2;
9
+ /**
10
+ * Resolve the first matching value while traversing a linked structure.
11
+ *
12
+ * @param options - Linked-structure traversal options.
13
+ *
14
+ * - `startNode`: Initial node to inspect.
15
+ * - `getNextNode`: Function that returns the next node in the chain.
16
+ * - `resolveValue`: Function that returns a lookup result for the current node.
17
+ *
18
+ * @returns Lookup result for the first resolved value; otherwise a non-matching
19
+ * lookup result when traversal reaches the chain end or detects a
20
+ * parent-cycle.
21
+ */
22
+ export const resolveFirstValueInLinkedStructure = ({ getNextNode, resolveValue, startNode, }) => {
23
+ let slowNode = startNode;
24
+ let fastNode = startNode;
25
+ while (slowNode !== null) {
26
+ const resolvedValue = resolveValue(slowNode);
27
+ if (resolvedValue.found) {
28
+ return resolvedValue;
29
+ }
30
+ slowNode = getNextNode(slowNode);
31
+ for (let step = 0; step < FLOYD_FAST_POINTER_ADVANCE_STEPS; step += 1) {
32
+ if (fastNode === null) {
33
+ break;
34
+ }
35
+ fastNode = getNextNode(fastNode);
36
+ }
37
+ if (slowNode !== null && fastNode !== null && slowNode === fastNode) {
38
+ return {
39
+ found: false,
40
+ };
41
+ }
42
+ }
43
+ return {
44
+ found: false,
45
+ };
46
+ };
47
+ /**
48
+ * Check whether any node in a linked structure satisfies a predicate.
49
+ *
50
+ * @param options - Linked-structure traversal options.
51
+ *
52
+ * - `startNode`: Initial node to inspect.
53
+ * - `getNextNode`: Function that returns the next node in the chain.
54
+ * - `isMatch`: Predicate used to test each visited node.
55
+ *
56
+ * @returns `true` when any visited node matches; otherwise `false`.
57
+ */
58
+ export const isAnyLinkedStructureNodeMatching = ({ getNextNode, isMatch, startNode, }) => resolveFirstValueInLinkedStructure({
59
+ getNextNode,
60
+ resolveValue: (node) => isMatch(node)
61
+ ? {
62
+ found: true,
63
+ value: true,
64
+ }
65
+ : {
66
+ found: false,
67
+ },
68
+ startNode,
69
+ }).found;
70
+ //# sourceMappingURL=cycle-safe-linked-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cycle-safe-linked-search.js","sourceRoot":"","sources":["../../src/_internal/cycle-safe-linked-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH;;GAEG;AACH,MAAM,gCAAgC,GAAG,CAAU,CAAC;AAEpD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAc,EAC5D,WAAW,EACX,YAAY,EACZ,SAAS,GAKX,EAAsC,EAAE;IACtC,IAAI,QAAQ,GAAG,SAAS,CAAC;IACzB,IAAI,QAAQ,GAAG,SAAS,CAAC;IAEzB,OAAO,QAAQ,KAAK,IAAI,EAAE,CAAC;QACvB,MAAM,aAAa,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE7C,IAAI,aAAa,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,aAAa,CAAC;QACzB,CAAC;QAED,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QAEjC,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,gCAAgC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;YACpE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACpB,MAAM;YACV,CAAC;YAED,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC;QAED,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClE,OAAO;gBACH,KAAK,EAAE,KAAK;aACf,CAAC;QACN,CAAC;IACL,CAAC;IAED,OAAO;QACH,KAAK,EAAE,KAAK;KACf,CAAC;AACN,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAAO,EACnD,WAAW,EACX,OAAO,EACP,SAAS,GAKX,EAAW,EAAE,CACX,kCAAkC,CAAC;IAC/B,WAAW;IACX,YAAY,EAAE,CAAC,IAAI,EAAwC,EAAE,CACzD,OAAO,CAAC,IAAI,CAAC;QACT,CAAC,CAAC;YACI,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,IAAI;SACd;QACH,CAAC,CAAC;YACI,KAAK,EAAE,KAAK;SACf;IACX,SAAS;CACZ,CAAC,CAAC,KAAK,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Shared helper for memoizing boolean expression predicates by ESTree node
4
+ * identity.
5
+ */
6
+ import type { TSESTree } from "@typescript-eslint/utils";
7
+ /**
8
+ * Memoize a boolean expression predicate using a `WeakMap` keyed by expression
9
+ * node identity.
10
+ *
11
+ * @param evaluate - Predicate to memoize.
12
+ *
13
+ * @returns Memoized predicate that reuses previous results for the same node
14
+ * object.
15
+ */
16
+ export declare const memoizeExpressionBooleanPredicate: (evaluate: (expression: Readonly<TSESTree.Expression>) => boolean) => ((expression: Readonly<TSESTree.Expression>) => boolean);
17
+ //# sourceMappingURL=expression-boolean-memoizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression-boolean-memoizer.d.ts","sourceRoot":"","sources":["../../src/_internal/expression-boolean-memoizer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD;;;;;;;;GAQG;AACH,eAAO,MAAM,iCAAiC,GAC1C,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,OAAO,KACjE,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,OAAO,CAgBzD,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Memoize a boolean expression predicate using a `WeakMap` keyed by expression
3
+ * node identity.
4
+ *
5
+ * @param evaluate - Predicate to memoize.
6
+ *
7
+ * @returns Memoized predicate that reuses previous results for the same node
8
+ * object.
9
+ */
10
+ export const memoizeExpressionBooleanPredicate = (evaluate) => {
11
+ const cache = new WeakMap();
12
+ return (expression) => {
13
+ const cachedResult = cache.get(expression);
14
+ if (cachedResult !== undefined) {
15
+ return cachedResult;
16
+ }
17
+ const result = evaluate(expression);
18
+ cache.set(expression, result);
19
+ return result;
20
+ };
21
+ };
22
+ //# sourceMappingURL=expression-boolean-memoizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression-boolean-memoizer.js","sourceRoot":"","sources":["../../src/_internal/expression-boolean-memoizer.ts"],"names":[],"mappings":"AAOA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,CAC7C,QAAgE,EACR,EAAE;IAC1D,MAAM,KAAK,GAAG,IAAI,OAAO,EAA0C,CAAC;IAEpE,OAAO,CAAC,UAAU,EAAE,EAAE;QAClB,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAE3C,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,YAAY,CAAC;QACxB,CAAC;QAED,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QAEpC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAE9B,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;AACN,CAAC,CAAC"}
@@ -0,0 +1,52 @@
1
+ import type { TSESTree } from "@typescript-eslint/utils";
2
+ /**
3
+ * Narrows call expressions to direct `.filter(...)` calls.
4
+ */
5
+ export declare const isFilterCallExpression: (expression: Readonly<TSESTree.CallExpression>) => expression is TSESTree.CallExpression & {
6
+ callee: TSESTree.MemberExpression & {
7
+ computed: false;
8
+ optional: false;
9
+ property: TSESTree.Identifier;
10
+ };
11
+ optional: false;
12
+ };
13
+ /**
14
+ * Extract the first callback argument from a direct `.filter(...)` call.
15
+ *
16
+ * @param expression - Candidate call expression to inspect.
17
+ *
18
+ * @returns Callback expression when the call is a supported `.filter(...)`
19
+ * invocation and the first argument is an arrow/function expression;
20
+ * otherwise `null`.
21
+ */
22
+ export declare const getFilterCallbackFunctionArgument: (expression: Readonly<TSESTree.CallExpression>) => null | Readonly<TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression>;
23
+ /**
24
+ * Structured match for `.filter(...)` calls with a single identifier parameter
25
+ * arrow callback that uses an expression body.
26
+ */
27
+ export type SingleParameterExpressionArrowFilterCallbackMatch = Readonly<{
28
+ callback: TSESTree.ArrowFunctionExpression & {
29
+ body: TSESTree.Expression;
30
+ params: [TSESTree.Identifier];
31
+ };
32
+ parameter: TSESTree.Identifier;
33
+ }>;
34
+ /**
35
+ * Extract a strict callback shape from direct `.filter(...)` calls.
36
+ *
37
+ * @param expression - Candidate call expression to inspect.
38
+ *
39
+ * @returns Structured callback match when supported; otherwise `null`.
40
+ */
41
+ export declare const getSingleParameterExpressionArrowFilterCallback: (expression: Readonly<TSESTree.CallExpression>) => null | SingleParameterExpressionArrowFilterCallbackMatch;
42
+ /**
43
+ * Checks whether a node appears inside a callback passed as the first argument
44
+ * to a direct `.filter(...)` call.
45
+ *
46
+ * @param node - Node to inspect.
47
+ *
48
+ * @returns `true` when the node is inside a `.filter(...)` callback; otherwise
49
+ * `false`.
50
+ */
51
+ export declare const isWithinFilterCallback: (node: Readonly<TSESTree.Node>) => boolean;
52
+ //# sourceMappingURL=filter-callback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-callback.d.ts","sourceRoot":"","sources":["../../src/_internal/filter-callback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAsBzD;;GAEG;AACH,eAAO,MAAM,sBAAsB,GAC/B,YAAY,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,KAC9C,UAAU,IAAI,QAAQ,CAAC,cAAc,GAAG;IACvC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,GAAG;QAChC,QAAQ,EAAE,KAAK,CAAC;QAChB,QAAQ,EAAE,KAAK,CAAC;QAChB,QAAQ,EAAE,QAAQ,CAAC,UAAU,CAAC;KACjC,CAAC;IACF,QAAQ,EAAE,KAAK,CAAC;CAOsC,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,iCAAiC,GAC1C,YAAY,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,KAC9C,IAAI,GAAG,QAAQ,CACd,QAAQ,CAAC,uBAAuB,GAAG,QAAQ,CAAC,kBAAkB,CAgBjE,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iDAAiD,GAAG,QAAQ,CAAC;IACrE,QAAQ,EAAE,QAAQ,CAAC,uBAAuB,GAAG;QACzC,IAAI,EAAE,QAAQ,CAAC,UAAU,CAAC;QAC1B,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;KACjC,CAAC;IACF,SAAS,EAAE,QAAQ,CAAC,UAAU,CAAC;CAClC,CAAC,CAAC;AAqBH;;;;;;GAMG;AACH,eAAO,MAAM,+CAA+C,GACxD,YAAY,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,KAC9C,IAAI,GAAG,iDAgBT,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,GAC/B,MAAM,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,KAC9B,OAgCF,CAAC"}