aicodeman 0.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.
- package/LICENSE +21 -0
- package/README.md +403 -0
- package/dist/ai-checker-base.d.ts +175 -0
- package/dist/ai-checker-base.d.ts.map +1 -0
- package/dist/ai-checker-base.js +424 -0
- package/dist/ai-checker-base.js.map +1 -0
- package/dist/ai-idle-checker.d.ts +53 -0
- package/dist/ai-idle-checker.d.ts.map +1 -0
- package/dist/ai-idle-checker.js +141 -0
- package/dist/ai-idle-checker.js.map +1 -0
- package/dist/ai-plan-checker.d.ts +52 -0
- package/dist/ai-plan-checker.d.ts.map +1 -0
- package/dist/ai-plan-checker.js +103 -0
- package/dist/ai-plan-checker.js.map +1 -0
- package/dist/bash-tool-parser.d.ts +191 -0
- package/dist/bash-tool-parser.d.ts.map +1 -0
- package/dist/bash-tool-parser.js +598 -0
- package/dist/bash-tool-parser.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +460 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/buffer-limits.d.ts +59 -0
- package/dist/config/buffer-limits.d.ts.map +1 -0
- package/dist/config/buffer-limits.js +74 -0
- package/dist/config/buffer-limits.js.map +1 -0
- package/dist/config/map-limits.d.ts +40 -0
- package/dist/config/map-limits.d.ts.map +1 -0
- package/dist/config/map-limits.js +52 -0
- package/dist/config/map-limits.js.map +1 -0
- package/dist/file-stream-manager.d.ts +148 -0
- package/dist/file-stream-manager.d.ts.map +1 -0
- package/dist/file-stream-manager.js +351 -0
- package/dist/file-stream-manager.js.map +1 -0
- package/dist/hooks-config.d.ts +31 -0
- package/dist/hooks-config.d.ts.map +1 -0
- package/dist/hooks-config.js +115 -0
- package/dist/hooks-config.js.map +1 -0
- package/dist/image-watcher.d.ts +86 -0
- package/dist/image-watcher.d.ts.map +1 -0
- package/dist/image-watcher.js +275 -0
- package/dist/image-watcher.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/mux-factory.d.ts +13 -0
- package/dist/mux-factory.d.ts.map +1 -0
- package/dist/mux-factory.js +19 -0
- package/dist/mux-factory.js.map +1 -0
- package/dist/mux-interface.d.ts +145 -0
- package/dist/mux-interface.d.ts.map +1 -0
- package/dist/mux-interface.js +9 -0
- package/dist/mux-interface.js.map +1 -0
- package/dist/plan-orchestrator.d.ts +123 -0
- package/dist/plan-orchestrator.d.ts.map +1 -0
- package/dist/plan-orchestrator.js +500 -0
- package/dist/plan-orchestrator.js.map +1 -0
- package/dist/prompts/index.d.ts +9 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +9 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/planner.d.ts +14 -0
- package/dist/prompts/planner.d.ts.map +1 -0
- package/dist/prompts/planner.js +83 -0
- package/dist/prompts/planner.js.map +1 -0
- package/dist/prompts/research-agent.d.ts +10 -0
- package/dist/prompts/research-agent.d.ts.map +1 -0
- package/dist/prompts/research-agent.js +143 -0
- package/dist/prompts/research-agent.js.map +1 -0
- package/dist/push-store.d.ts +41 -0
- package/dist/push-store.d.ts.map +1 -0
- package/dist/push-store.js +168 -0
- package/dist/push-store.js.map +1 -0
- package/dist/ralph-config.d.ts +67 -0
- package/dist/ralph-config.d.ts.map +1 -0
- package/dist/ralph-config.js +134 -0
- package/dist/ralph-config.js.map +1 -0
- package/dist/ralph-loop.d.ts +124 -0
- package/dist/ralph-loop.d.ts.map +1 -0
- package/dist/ralph-loop.js +418 -0
- package/dist/ralph-loop.js.map +1 -0
- package/dist/ralph-tracker.d.ts +1081 -0
- package/dist/ralph-tracker.d.ts.map +1 -0
- package/dist/ralph-tracker.js +3343 -0
- package/dist/ralph-tracker.js.map +1 -0
- package/dist/respawn-controller.d.ts +1182 -0
- package/dist/respawn-controller.d.ts.map +1 -0
- package/dist/respawn-controller.js +2754 -0
- package/dist/respawn-controller.js.map +1 -0
- package/dist/run-summary.d.ts +123 -0
- package/dist/run-summary.d.ts.map +1 -0
- package/dist/run-summary.js +325 -0
- package/dist/run-summary.js.map +1 -0
- package/dist/session-lifecycle-log.d.ts +36 -0
- package/dist/session-lifecycle-log.d.ts.map +1 -0
- package/dist/session-lifecycle-log.js +101 -0
- package/dist/session-lifecycle-log.js.map +1 -0
- package/dist/session-manager.d.ts +97 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +224 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/session.d.ts +686 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +2025 -0
- package/dist/session.js.map +1 -0
- package/dist/state-store.d.ts +189 -0
- package/dist/state-store.d.ts.map +1 -0
- package/dist/state-store.js +730 -0
- package/dist/state-store.js.map +1 -0
- package/dist/subagent-watcher.d.ts +345 -0
- package/dist/subagent-watcher.d.ts.map +1 -0
- package/dist/subagent-watcher.js +1469 -0
- package/dist/subagent-watcher.js.map +1 -0
- package/dist/task-queue.d.ts +108 -0
- package/dist/task-queue.d.ts.map +1 -0
- package/dist/task-queue.js +235 -0
- package/dist/task-queue.js.map +1 -0
- package/dist/task-tracker.d.ts +306 -0
- package/dist/task-tracker.d.ts.map +1 -0
- package/dist/task-tracker.js +488 -0
- package/dist/task-tracker.js.map +1 -0
- package/dist/task.d.ts +73 -0
- package/dist/task.d.ts.map +1 -0
- package/dist/task.js +177 -0
- package/dist/task.js.map +1 -0
- package/dist/team-watcher.d.ts +53 -0
- package/dist/team-watcher.d.ts.map +1 -0
- package/dist/team-watcher.js +313 -0
- package/dist/team-watcher.js.map +1 -0
- package/dist/templates/case-template.md +461 -0
- package/dist/templates/claude-md.d.ts +26 -0
- package/dist/templates/claude-md.d.ts.map +1 -0
- package/dist/templates/claude-md.js +74 -0
- package/dist/templates/claude-md.js.map +1 -0
- package/dist/tmux-manager.d.ts +181 -0
- package/dist/tmux-manager.d.ts.map +1 -0
- package/dist/tmux-manager.js +1405 -0
- package/dist/tmux-manager.js.map +1 -0
- package/dist/transcript-watcher.d.ts +110 -0
- package/dist/transcript-watcher.d.ts.map +1 -0
- package/dist/transcript-watcher.js +338 -0
- package/dist/transcript-watcher.js.map +1 -0
- package/dist/tunnel-manager.d.ts +54 -0
- package/dist/tunnel-manager.d.ts.map +1 -0
- package/dist/tunnel-manager.js +251 -0
- package/dist/tunnel-manager.js.map +1 -0
- package/dist/types.d.ts +1139 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +215 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/buffer-accumulator.d.ts +111 -0
- package/dist/utils/buffer-accumulator.d.ts.map +1 -0
- package/dist/utils/buffer-accumulator.js +172 -0
- package/dist/utils/buffer-accumulator.js.map +1 -0
- package/dist/utils/claude-cli-resolver.d.ts +26 -0
- package/dist/utils/claude-cli-resolver.d.ts.map +1 -0
- package/dist/utils/claude-cli-resolver.js +78 -0
- package/dist/utils/claude-cli-resolver.js.map +1 -0
- package/dist/utils/cleanup-manager.d.ts +165 -0
- package/dist/utils/cleanup-manager.d.ts.map +1 -0
- package/dist/utils/cleanup-manager.js +274 -0
- package/dist/utils/cleanup-manager.js.map +1 -0
- package/dist/utils/index.d.ts +19 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +19 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/lru-map.d.ts +140 -0
- package/dist/utils/lru-map.d.ts.map +1 -0
- package/dist/utils/lru-map.js +234 -0
- package/dist/utils/lru-map.js.map +1 -0
- package/dist/utils/nice-wrapper.d.ts +13 -0
- package/dist/utils/nice-wrapper.d.ts.map +1 -0
- package/dist/utils/nice-wrapper.js +17 -0
- package/dist/utils/nice-wrapper.js.map +1 -0
- package/dist/utils/opencode-cli-resolver.d.ts +21 -0
- package/dist/utils/opencode-cli-resolver.d.ts.map +1 -0
- package/dist/utils/opencode-cli-resolver.js +67 -0
- package/dist/utils/opencode-cli-resolver.js.map +1 -0
- package/dist/utils/regex-patterns.d.ts +64 -0
- package/dist/utils/regex-patterns.d.ts.map +1 -0
- package/dist/utils/regex-patterns.js +74 -0
- package/dist/utils/regex-patterns.js.map +1 -0
- package/dist/utils/stale-expiration-map.d.ts +159 -0
- package/dist/utils/stale-expiration-map.d.ts.map +1 -0
- package/dist/utils/stale-expiration-map.js +277 -0
- package/dist/utils/stale-expiration-map.js.map +1 -0
- package/dist/utils/string-similarity.d.ts +108 -0
- package/dist/utils/string-similarity.d.ts.map +1 -0
- package/dist/utils/string-similarity.js +189 -0
- package/dist/utils/string-similarity.js.map +1 -0
- package/dist/utils/token-validation.d.ts +39 -0
- package/dist/utils/token-validation.d.ts.map +1 -0
- package/dist/utils/token-validation.js +59 -0
- package/dist/utils/token-validation.js.map +1 -0
- package/dist/utils/type-safety.d.ts +33 -0
- package/dist/utils/type-safety.d.ts.map +1 -0
- package/dist/utils/type-safety.js +35 -0
- package/dist/utils/type-safety.js.map +1 -0
- package/dist/web/public/app.js +491 -0
- package/dist/web/public/app.js.br +0 -0
- package/dist/web/public/app.js.gz +0 -0
- package/dist/web/public/index.html +1675 -0
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/manifest.json +8 -0
- package/dist/web/public/mobile.css +1 -0
- package/dist/web/public/mobile.css.br +0 -0
- package/dist/web/public/mobile.css.gz +0 -0
- package/dist/web/public/ralph-wizard.js +1037 -0
- package/dist/web/public/ralph-wizard.js.br +0 -0
- package/dist/web/public/ralph-wizard.js.gz +0 -0
- package/dist/web/public/styles.css +1 -0
- package/dist/web/public/styles.css.br +0 -0
- package/dist/web/public/styles.css.gz +0 -0
- package/dist/web/public/sw.js +67 -0
- package/dist/web/public/sw.js.br +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/upload.html +155 -0
- package/dist/web/public/upload.html.br +0 -0
- package/dist/web/public/upload.html.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js +1 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.br +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js +1 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.br +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js +2 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.br +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm.css +209 -0
- package/dist/web/public/vendor/xterm.css.br +0 -0
- package/dist/web/public/vendor/xterm.css.gz +0 -0
- package/dist/web/public/vendor/xterm.min.js +9 -0
- package/dist/web/public/vendor/xterm.min.js.br +0 -0
- package/dist/web/public/vendor/xterm.min.js.gz +0 -0
- package/dist/web/schemas.d.ts +479 -0
- package/dist/web/schemas.d.ts.map +1 -0
- package/dist/web/schemas.js +448 -0
- package/dist/web/schemas.js.map +1 -0
- package/dist/web/server.d.ts +207 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +5784 -0
- package/dist/web/server.js.map +1 -0
- package/package.json +110 -0
- package/scripts/postinstall.js +390 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Centralized resource cleanup manager.
|
|
3
|
+
*
|
|
4
|
+
* Tracks timers, intervals, watchers, and other resources that need explicit
|
|
5
|
+
* cleanup. Provides a unified dispose() method that safely cleans up all
|
|
6
|
+
* registered resources, even on partial failures.
|
|
7
|
+
*
|
|
8
|
+
* @module utils/cleanup-manager
|
|
9
|
+
*/
|
|
10
|
+
import type { Disposable, CleanupRegistration, CleanupResourceType } from '../types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Options for setTimeout/setInterval with automatic cleanup.
|
|
13
|
+
*/
|
|
14
|
+
export interface TimerOptions {
|
|
15
|
+
/** Human-readable description for debugging */
|
|
16
|
+
description?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Centralized manager for tracking and disposing resources.
|
|
20
|
+
*
|
|
21
|
+
* Implements the Disposable interface for hierarchical cleanup.
|
|
22
|
+
* All registered resources are cleaned up when dispose() is called.
|
|
23
|
+
*
|
|
24
|
+
* Features:
|
|
25
|
+
* - Tracks timers, intervals, watchers, and custom cleanup functions
|
|
26
|
+
* - isStopped guard to prevent callbacks firing after disposal
|
|
27
|
+
* - Safe disposal that continues even if individual cleanups fail
|
|
28
|
+
* - Debug logging for resource tracking
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* class MyService implements Disposable {
|
|
33
|
+
* private cleanup = new CleanupManager();
|
|
34
|
+
*
|
|
35
|
+
* start() {
|
|
36
|
+
* // Timer automatically cleared on dispose
|
|
37
|
+
* this.cleanup.setTimeout(() => {
|
|
38
|
+
* if (this.cleanup.isStopped) return; // Guard
|
|
39
|
+
* this.doWork();
|
|
40
|
+
* }, 5000, { description: 'work timer' });
|
|
41
|
+
* }
|
|
42
|
+
*
|
|
43
|
+
* dispose() {
|
|
44
|
+
* this.cleanup.dispose();
|
|
45
|
+
* }
|
|
46
|
+
*
|
|
47
|
+
* get isDisposed() { return this.cleanup.isDisposed; }
|
|
48
|
+
* }
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare class CleanupManager implements Disposable {
|
|
52
|
+
private registrations;
|
|
53
|
+
private _isDisposed;
|
|
54
|
+
private readonly debugMode;
|
|
55
|
+
/**
|
|
56
|
+
* Creates a new CleanupManager.
|
|
57
|
+
*
|
|
58
|
+
* @param debug - Enable debug logging for resource tracking
|
|
59
|
+
*/
|
|
60
|
+
constructor(debug?: boolean);
|
|
61
|
+
/**
|
|
62
|
+
* Whether this manager has been disposed.
|
|
63
|
+
* Check this before executing callbacks to prevent zombie operations.
|
|
64
|
+
*/
|
|
65
|
+
get isDisposed(): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Alias for isDisposed - check before executing async callbacks.
|
|
68
|
+
*/
|
|
69
|
+
get isStopped(): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Number of currently registered resources.
|
|
72
|
+
*/
|
|
73
|
+
get resourceCount(): number;
|
|
74
|
+
/**
|
|
75
|
+
* Get counts by resource type for metrics/debugging.
|
|
76
|
+
*/
|
|
77
|
+
get resourceCounts(): Record<CleanupResourceType, number>;
|
|
78
|
+
/**
|
|
79
|
+
* Schedule a timeout that will be automatically cleared on dispose.
|
|
80
|
+
*
|
|
81
|
+
* @param callback - Function to call when timeout fires
|
|
82
|
+
* @param delay - Delay in milliseconds
|
|
83
|
+
* @param options - Optional configuration
|
|
84
|
+
* @returns Timer ID for manual clearing if needed
|
|
85
|
+
*/
|
|
86
|
+
setTimeout(callback: () => void, delay: number, options?: TimerOptions): string;
|
|
87
|
+
/**
|
|
88
|
+
* Schedule an interval that will be automatically cleared on dispose.
|
|
89
|
+
*
|
|
90
|
+
* @param callback - Function to call on each interval
|
|
91
|
+
* @param delay - Interval in milliseconds
|
|
92
|
+
* @param options - Optional configuration
|
|
93
|
+
* @returns Interval ID for manual clearing if needed
|
|
94
|
+
*/
|
|
95
|
+
setInterval(callback: () => void, delay: number, options?: TimerOptions): string;
|
|
96
|
+
/**
|
|
97
|
+
* Register a custom cleanup function.
|
|
98
|
+
*
|
|
99
|
+
* @param type - Type of resource for categorization
|
|
100
|
+
* @param cleanup - Function to call on dispose
|
|
101
|
+
* @param description - Human-readable description
|
|
102
|
+
* @returns Registration ID for manual removal if needed
|
|
103
|
+
*/
|
|
104
|
+
registerCleanup(type: CleanupResourceType, cleanup: () => void, description: string): string;
|
|
105
|
+
/**
|
|
106
|
+
* Register a file system watcher for cleanup.
|
|
107
|
+
*
|
|
108
|
+
* @param watcher - Object with close() method (FSWatcher, chokidar, etc.)
|
|
109
|
+
* @param description - Human-readable description
|
|
110
|
+
* @returns Registration ID
|
|
111
|
+
*/
|
|
112
|
+
registerWatcher(watcher: {
|
|
113
|
+
close: () => void;
|
|
114
|
+
}, description: string): string;
|
|
115
|
+
/**
|
|
116
|
+
* Register an event listener for cleanup.
|
|
117
|
+
*
|
|
118
|
+
* @param emitter - Object with removeListener/off method
|
|
119
|
+
* @param event - Event name
|
|
120
|
+
* @param listener - Listener function
|
|
121
|
+
* @param description - Human-readable description
|
|
122
|
+
* @returns Registration ID
|
|
123
|
+
*/
|
|
124
|
+
registerListener<T extends {
|
|
125
|
+
removeListener?: (event: string, listener: () => void) => void;
|
|
126
|
+
off?: (event: string, listener: () => void) => void;
|
|
127
|
+
}>(emitter: T, event: string, listener: () => void, description: string): string;
|
|
128
|
+
/**
|
|
129
|
+
* Register a stream for cleanup.
|
|
130
|
+
*
|
|
131
|
+
* @param stream - Object with destroy() or close() method
|
|
132
|
+
* @param description - Human-readable description
|
|
133
|
+
* @returns Registration ID
|
|
134
|
+
*/
|
|
135
|
+
registerStream(stream: {
|
|
136
|
+
destroy?: () => void;
|
|
137
|
+
close?: () => void;
|
|
138
|
+
}, description: string): string;
|
|
139
|
+
/**
|
|
140
|
+
* Manually remove a registered resource.
|
|
141
|
+
*
|
|
142
|
+
* @param id - Registration ID returned from register methods
|
|
143
|
+
* @returns True if resource was found and removed
|
|
144
|
+
*/
|
|
145
|
+
unregister(id: string): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Dispose all registered resources.
|
|
148
|
+
* Safe to call multiple times (idempotent).
|
|
149
|
+
* Continues cleanup even if individual resources fail.
|
|
150
|
+
*/
|
|
151
|
+
dispose(): void;
|
|
152
|
+
/**
|
|
153
|
+
* Get all current registrations for debugging.
|
|
154
|
+
*/
|
|
155
|
+
getRegistrations(): CleanupRegistration[];
|
|
156
|
+
/**
|
|
157
|
+
* Internal: Register a cleanup entry.
|
|
158
|
+
*/
|
|
159
|
+
private register;
|
|
160
|
+
/**
|
|
161
|
+
* Internal: Debug logging.
|
|
162
|
+
*/
|
|
163
|
+
private debug;
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=cleanup-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-manager.d.ts","sourceRoot":"","sources":["../../src/utils/cleanup-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAExF;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;IAEpC;;;;OAIG;gBACS,KAAK,UAAQ;IAIzB;;;OAGG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;OAEG;IACH,IAAI,cAAc,IAAI,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAcxD;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM;IAqB/E;;;;;;;OAOG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM;IAmBhF;;;;;;;OAOG;IACH,eAAe,CAAC,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAY5F;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAI5E;;;;;;;;OAQG;IACH,gBAAgB,CACd,CAAC,SAAS;QACR,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;QAC/D,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;KACrD,EACD,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAc/E;;;;;;OAMG;IACH,cAAc,CAAC,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,IAAI,CAAA;KAAE,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM;IAcjG;;;;;OAKG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAc/B;;;;OAIG;IACH,OAAO,IAAI,IAAI;IA0Bf;;OAEG;IACH,gBAAgB,IAAI,mBAAmB,EAAE;IAIzC;;OAEG;IACH,OAAO,CAAC,QAAQ;IAKhB;;OAEG;IACH,OAAO,CAAC,KAAK;CAKd"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Centralized resource cleanup manager.
|
|
3
|
+
*
|
|
4
|
+
* Tracks timers, intervals, watchers, and other resources that need explicit
|
|
5
|
+
* cleanup. Provides a unified dispose() method that safely cleans up all
|
|
6
|
+
* registered resources, even on partial failures.
|
|
7
|
+
*
|
|
8
|
+
* @module utils/cleanup-manager
|
|
9
|
+
*/
|
|
10
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
11
|
+
/**
|
|
12
|
+
* Centralized manager for tracking and disposing resources.
|
|
13
|
+
*
|
|
14
|
+
* Implements the Disposable interface for hierarchical cleanup.
|
|
15
|
+
* All registered resources are cleaned up when dispose() is called.
|
|
16
|
+
*
|
|
17
|
+
* Features:
|
|
18
|
+
* - Tracks timers, intervals, watchers, and custom cleanup functions
|
|
19
|
+
* - isStopped guard to prevent callbacks firing after disposal
|
|
20
|
+
* - Safe disposal that continues even if individual cleanups fail
|
|
21
|
+
* - Debug logging for resource tracking
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* class MyService implements Disposable {
|
|
26
|
+
* private cleanup = new CleanupManager();
|
|
27
|
+
*
|
|
28
|
+
* start() {
|
|
29
|
+
* // Timer automatically cleared on dispose
|
|
30
|
+
* this.cleanup.setTimeout(() => {
|
|
31
|
+
* if (this.cleanup.isStopped) return; // Guard
|
|
32
|
+
* this.doWork();
|
|
33
|
+
* }, 5000, { description: 'work timer' });
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* dispose() {
|
|
37
|
+
* this.cleanup.dispose();
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* get isDisposed() { return this.cleanup.isDisposed; }
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export class CleanupManager {
|
|
45
|
+
registrations = new Map();
|
|
46
|
+
_isDisposed = false;
|
|
47
|
+
debugMode;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a new CleanupManager.
|
|
50
|
+
*
|
|
51
|
+
* @param debug - Enable debug logging for resource tracking
|
|
52
|
+
*/
|
|
53
|
+
constructor(debug = false) {
|
|
54
|
+
this.debugMode = debug;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Whether this manager has been disposed.
|
|
58
|
+
* Check this before executing callbacks to prevent zombie operations.
|
|
59
|
+
*/
|
|
60
|
+
get isDisposed() {
|
|
61
|
+
return this._isDisposed;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Alias for isDisposed - check before executing async callbacks.
|
|
65
|
+
*/
|
|
66
|
+
get isStopped() {
|
|
67
|
+
return this._isDisposed;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Number of currently registered resources.
|
|
71
|
+
*/
|
|
72
|
+
get resourceCount() {
|
|
73
|
+
return this.registrations.size;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get counts by resource type for metrics/debugging.
|
|
77
|
+
*/
|
|
78
|
+
get resourceCounts() {
|
|
79
|
+
const counts = {
|
|
80
|
+
timer: 0,
|
|
81
|
+
interval: 0,
|
|
82
|
+
watcher: 0,
|
|
83
|
+
listener: 0,
|
|
84
|
+
stream: 0,
|
|
85
|
+
};
|
|
86
|
+
for (const reg of this.registrations.values()) {
|
|
87
|
+
counts[reg.type]++;
|
|
88
|
+
}
|
|
89
|
+
return counts;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Schedule a timeout that will be automatically cleared on dispose.
|
|
93
|
+
*
|
|
94
|
+
* @param callback - Function to call when timeout fires
|
|
95
|
+
* @param delay - Delay in milliseconds
|
|
96
|
+
* @param options - Optional configuration
|
|
97
|
+
* @returns Timer ID for manual clearing if needed
|
|
98
|
+
*/
|
|
99
|
+
setTimeout(callback, delay, options) {
|
|
100
|
+
const id = uuidv4();
|
|
101
|
+
const timeoutId = setTimeout(() => {
|
|
102
|
+
// Remove registration when timer fires naturally
|
|
103
|
+
this.registrations.delete(id);
|
|
104
|
+
// Don't execute if already stopped
|
|
105
|
+
if (this._isDisposed)
|
|
106
|
+
return;
|
|
107
|
+
callback();
|
|
108
|
+
}, delay);
|
|
109
|
+
this.register({
|
|
110
|
+
id,
|
|
111
|
+
type: 'timer',
|
|
112
|
+
description: options?.description || `setTimeout(${delay}ms)`,
|
|
113
|
+
cleanup: () => clearTimeout(timeoutId),
|
|
114
|
+
registeredAt: Date.now(),
|
|
115
|
+
});
|
|
116
|
+
return id;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Schedule an interval that will be automatically cleared on dispose.
|
|
120
|
+
*
|
|
121
|
+
* @param callback - Function to call on each interval
|
|
122
|
+
* @param delay - Interval in milliseconds
|
|
123
|
+
* @param options - Optional configuration
|
|
124
|
+
* @returns Interval ID for manual clearing if needed
|
|
125
|
+
*/
|
|
126
|
+
setInterval(callback, delay, options) {
|
|
127
|
+
const id = uuidv4();
|
|
128
|
+
const intervalId = setInterval(() => {
|
|
129
|
+
// Don't execute if stopped
|
|
130
|
+
if (this._isDisposed)
|
|
131
|
+
return;
|
|
132
|
+
callback();
|
|
133
|
+
}, delay);
|
|
134
|
+
this.register({
|
|
135
|
+
id,
|
|
136
|
+
type: 'interval',
|
|
137
|
+
description: options?.description || `setInterval(${delay}ms)`,
|
|
138
|
+
cleanup: () => clearInterval(intervalId),
|
|
139
|
+
registeredAt: Date.now(),
|
|
140
|
+
});
|
|
141
|
+
return id;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Register a custom cleanup function.
|
|
145
|
+
*
|
|
146
|
+
* @param type - Type of resource for categorization
|
|
147
|
+
* @param cleanup - Function to call on dispose
|
|
148
|
+
* @param description - Human-readable description
|
|
149
|
+
* @returns Registration ID for manual removal if needed
|
|
150
|
+
*/
|
|
151
|
+
registerCleanup(type, cleanup, description) {
|
|
152
|
+
const id = uuidv4();
|
|
153
|
+
this.register({
|
|
154
|
+
id,
|
|
155
|
+
type,
|
|
156
|
+
description,
|
|
157
|
+
cleanup,
|
|
158
|
+
registeredAt: Date.now(),
|
|
159
|
+
});
|
|
160
|
+
return id;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Register a file system watcher for cleanup.
|
|
164
|
+
*
|
|
165
|
+
* @param watcher - Object with close() method (FSWatcher, chokidar, etc.)
|
|
166
|
+
* @param description - Human-readable description
|
|
167
|
+
* @returns Registration ID
|
|
168
|
+
*/
|
|
169
|
+
registerWatcher(watcher, description) {
|
|
170
|
+
return this.registerCleanup('watcher', () => watcher.close(), description);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Register an event listener for cleanup.
|
|
174
|
+
*
|
|
175
|
+
* @param emitter - Object with removeListener/off method
|
|
176
|
+
* @param event - Event name
|
|
177
|
+
* @param listener - Listener function
|
|
178
|
+
* @param description - Human-readable description
|
|
179
|
+
* @returns Registration ID
|
|
180
|
+
*/
|
|
181
|
+
registerListener(emitter, event, listener, description) {
|
|
182
|
+
return this.registerCleanup('listener', () => {
|
|
183
|
+
if (emitter.removeListener) {
|
|
184
|
+
emitter.removeListener(event, listener);
|
|
185
|
+
}
|
|
186
|
+
else if (emitter.off) {
|
|
187
|
+
emitter.off(event, listener);
|
|
188
|
+
}
|
|
189
|
+
}, description);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Register a stream for cleanup.
|
|
193
|
+
*
|
|
194
|
+
* @param stream - Object with destroy() or close() method
|
|
195
|
+
* @param description - Human-readable description
|
|
196
|
+
* @returns Registration ID
|
|
197
|
+
*/
|
|
198
|
+
registerStream(stream, description) {
|
|
199
|
+
return this.registerCleanup('stream', () => {
|
|
200
|
+
if (stream.destroy) {
|
|
201
|
+
stream.destroy();
|
|
202
|
+
}
|
|
203
|
+
else if (stream.close) {
|
|
204
|
+
stream.close();
|
|
205
|
+
}
|
|
206
|
+
}, description);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Manually remove a registered resource.
|
|
210
|
+
*
|
|
211
|
+
* @param id - Registration ID returned from register methods
|
|
212
|
+
* @returns True if resource was found and removed
|
|
213
|
+
*/
|
|
214
|
+
unregister(id) {
|
|
215
|
+
const reg = this.registrations.get(id);
|
|
216
|
+
if (!reg)
|
|
217
|
+
return false;
|
|
218
|
+
try {
|
|
219
|
+
reg.cleanup();
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
this.debug(`Error cleaning up ${reg.type} "${reg.description}": ${err}`);
|
|
223
|
+
}
|
|
224
|
+
this.registrations.delete(id);
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Dispose all registered resources.
|
|
229
|
+
* Safe to call multiple times (idempotent).
|
|
230
|
+
* Continues cleanup even if individual resources fail.
|
|
231
|
+
*/
|
|
232
|
+
dispose() {
|
|
233
|
+
if (this._isDisposed)
|
|
234
|
+
return;
|
|
235
|
+
this._isDisposed = true;
|
|
236
|
+
const errors = [];
|
|
237
|
+
for (const reg of this.registrations.values()) {
|
|
238
|
+
try {
|
|
239
|
+
reg.cleanup();
|
|
240
|
+
this.debug(`Cleaned up ${reg.type}: ${reg.description}`);
|
|
241
|
+
}
|
|
242
|
+
catch (err) {
|
|
243
|
+
errors.push({ description: reg.description, error: err });
|
|
244
|
+
this.debug(`Error cleaning up ${reg.type} "${reg.description}": ${err}`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
this.registrations.clear();
|
|
248
|
+
if (errors.length > 0) {
|
|
249
|
+
console.error(`[CleanupManager] ${errors.length} errors during disposal:`, errors.map((e) => e.description).join(', '));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Get all current registrations for debugging.
|
|
254
|
+
*/
|
|
255
|
+
getRegistrations() {
|
|
256
|
+
return Array.from(this.registrations.values());
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Internal: Register a cleanup entry.
|
|
260
|
+
*/
|
|
261
|
+
register(reg) {
|
|
262
|
+
this.registrations.set(reg.id, reg);
|
|
263
|
+
this.debug(`Registered ${reg.type}: ${reg.description}`);
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Internal: Debug logging.
|
|
267
|
+
*/
|
|
268
|
+
debug(message) {
|
|
269
|
+
if (this.debugMode) {
|
|
270
|
+
console.log(`[CleanupManager] ${message}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=cleanup-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup-manager.js","sourceRoot":"","sources":["../../src/utils/cleanup-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAWpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,OAAO,cAAc;IACjB,aAAa,GAAG,IAAI,GAAG,EAA+B,CAAC;IACvD,WAAW,GAAG,KAAK,CAAC;IACX,SAAS,CAAU;IAEpC;;;;OAIG;IACH,YAAY,KAAK,GAAG,KAAK;QACvB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,IAAI,cAAc;QAChB,MAAM,MAAM,GAAwC;YAClD,KAAK,EAAE,CAAC;YACR,QAAQ,EAAE,CAAC;YACX,OAAO,EAAE,CAAC;YACV,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,CAAC;SACV,CAAC;QAEF,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;YAC9C,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,QAAoB,EAAE,KAAa,EAAE,OAAsB;QACpE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;QACpB,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,iDAAiD;YACjD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC9B,mCAAmC;YACnC,IAAI,IAAI,CAAC,WAAW;gBAAE,OAAO;YAC7B,QAAQ,EAAE,CAAC;QACb,CAAC,EAAE,KAAK,CAAC,CAAC;QAEV,IAAI,CAAC,QAAQ,CAAC;YACZ,EAAE;YACF,IAAI,EAAE,OAAO;YACb,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,cAAc,KAAK,KAAK;YAC7D,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC;YACtC,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;SACzB,CAAC,CAAC;QAEH,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,QAAoB,EAAE,KAAa,EAAE,OAAsB;QACrE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;QACpB,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YAClC,2BAA2B;YAC3B,IAAI,IAAI,CAAC,WAAW;gBAAE,OAAO;YAC7B,QAAQ,EAAE,CAAC;QACb,CAAC,EAAE,KAAK,CAAC,CAAC;QAEV,IAAI,CAAC,QAAQ,CAAC;YACZ,EAAE;YACF,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,eAAe,KAAK,KAAK;YAC9D,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,CAAC;YACxC,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;SACzB,CAAC,CAAC;QAEH,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,IAAyB,EAAE,OAAmB,EAAE,WAAmB;QACjF,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC;YACZ,EAAE;YACF,IAAI;YACJ,WAAW;YACX,OAAO;YACP,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;SACzB,CAAC,CAAC;QACH,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;;;;OAMG;IACH,eAAe,CAAC,OAA8B,EAAE,WAAmB;QACjE,OAAO,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,WAAW,CAAC,CAAC;IAC7E,CAAC;IAED;;;;;;;;OAQG;IACH,gBAAgB,CAKd,OAAU,EAAE,KAAa,EAAE,QAAoB,EAAE,WAAmB;QACpE,OAAO,IAAI,CAAC,eAAe,CACzB,UAAU,EACV,GAAG,EAAE;YACH,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;gBAC3B,OAAO,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC1C,CAAC;iBAAM,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC,EACD,WAAW,CACZ,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,cAAc,CAAC,MAAoD,EAAE,WAAmB;QACtF,OAAO,IAAI,CAAC,eAAe,CACzB,QAAQ,EACR,GAAG,EAAE;YACH,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC;iBAAM,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACxB,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,CAAC;QACH,CAAC,EACD,WAAW,CACZ,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,EAAU;QACnB,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG;YAAE,OAAO,KAAK,CAAC;QAEvB,IAAI,CAAC;YACH,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,CAAC,qBAAqB,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,WAAW,MAAM,GAAG,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,OAAO;QACL,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAExB,MAAM,MAAM,GAAmD,EAAE,CAAC;QAElE,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;YAC9C,IAAI,CAAC;gBACH,GAAG,CAAC,OAAO,EAAE,CAAC;gBACd,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;YAC3D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC1D,IAAI,CAAC,KAAK,CAAC,qBAAqB,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,WAAW,MAAM,GAAG,EAAE,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAE3B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CACX,oBAAoB,MAAM,CAAC,MAAM,0BAA0B,EAC3D,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC5C,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACK,QAAQ,CAAC,GAAwB;QACvC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,OAAe;QAC3B,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Utility module exports.
|
|
3
|
+
*
|
|
4
|
+
* This module re-exports all utility classes and functions for easy import.
|
|
5
|
+
*
|
|
6
|
+
* @module utils
|
|
7
|
+
*/
|
|
8
|
+
export { BufferAccumulator } from './buffer-accumulator.js';
|
|
9
|
+
export { LRUMap, type LRUMapOptions } from './lru-map.js';
|
|
10
|
+
export { CleanupManager, type TimerOptions } from './cleanup-manager.js';
|
|
11
|
+
export { StaleExpirationMap, type StaleExpirationMapOptions } from './stale-expiration-map.js';
|
|
12
|
+
export { ANSI_ESCAPE_PATTERN_FULL, ANSI_ESCAPE_PATTERN_SIMPLE, TOKEN_PATTERN, SPINNER_PATTERN, } from './regex-patterns.js';
|
|
13
|
+
export { MAX_SESSION_TOKENS } from './token-validation.js';
|
|
14
|
+
export { stringSimilarity, fuzzyPhraseMatch, todoContentHash } from './string-similarity.js';
|
|
15
|
+
export { assertNever } from './type-safety.js';
|
|
16
|
+
export { wrapWithNice } from './nice-wrapper.js';
|
|
17
|
+
export { findClaudeDir, getAugmentedPath } from './claude-cli-resolver.js';
|
|
18
|
+
export { resolveOpenCodeDir, isOpenCodeAvailable } from './opencode-cli-resolver.js';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC/F,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Utility module exports.
|
|
3
|
+
*
|
|
4
|
+
* This module re-exports all utility classes and functions for easy import.
|
|
5
|
+
*
|
|
6
|
+
* @module utils
|
|
7
|
+
*/
|
|
8
|
+
export { BufferAccumulator } from './buffer-accumulator.js';
|
|
9
|
+
export { LRUMap } from './lru-map.js';
|
|
10
|
+
export { CleanupManager } from './cleanup-manager.js';
|
|
11
|
+
export { StaleExpirationMap } from './stale-expiration-map.js';
|
|
12
|
+
export { ANSI_ESCAPE_PATTERN_FULL, ANSI_ESCAPE_PATTERN_SIMPLE, TOKEN_PATTERN, SPINNER_PATTERN, } from './regex-patterns.js';
|
|
13
|
+
export { MAX_SESSION_TOKENS } from './token-validation.js';
|
|
14
|
+
export { stringSimilarity, fuzzyPhraseMatch, todoContentHash } from './string-similarity.js';
|
|
15
|
+
export { assertNever } from './type-safety.js';
|
|
16
|
+
export { wrapWithNice } from './nice-wrapper.js';
|
|
17
|
+
export { findClaudeDir, getAugmentedPath } from './claude-cli-resolver.js';
|
|
18
|
+
export { resolveOpenCodeDir, isOpenCodeAvailable } from './opencode-cli-resolver.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAsB,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAqB,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAkC,MAAM,2BAA2B,CAAC;AAC/F,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,aAAa,EACb,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview LRU (Least Recently Used) Map implementation.
|
|
3
|
+
*
|
|
4
|
+
* Extends the built-in Map with automatic eviction when a maximum size is
|
|
5
|
+
* exceeded. Uses Map's insertion-order iteration for O(1) LRU eviction.
|
|
6
|
+
*
|
|
7
|
+
* @module utils/lru-map
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Configuration options for LRUMap.
|
|
11
|
+
*/
|
|
12
|
+
export interface LRUMapOptions<K, V> {
|
|
13
|
+
/** Maximum number of entries before eviction */
|
|
14
|
+
maxSize: number;
|
|
15
|
+
/** Optional callback when an entry is evicted */
|
|
16
|
+
onEvict?: (key: K, value: V) => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A Map with automatic LRU (Least Recently Used) eviction.
|
|
20
|
+
*
|
|
21
|
+
* When the map exceeds maxSize, the oldest entries are evicted.
|
|
22
|
+
* Access via get() refreshes an entry's position (moves to most recent).
|
|
23
|
+
*
|
|
24
|
+
* Uses JavaScript Map's insertion-order guarantee for efficient LRU behavior.
|
|
25
|
+
* All operations are O(1) amortized.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const cache = new LRUMap<string, number>({
|
|
30
|
+
* maxSize: 100,
|
|
31
|
+
* onEvict: (key, value) => console.log(`Evicted ${key}`)
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* cache.set('a', 1);
|
|
35
|
+
* cache.set('b', 2);
|
|
36
|
+
* cache.get('a'); // Refreshes 'a', making 'b' the oldest
|
|
37
|
+
* // When full, 'b' would be evicted first
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare class LRUMap<K, V> extends Map<K, V> {
|
|
41
|
+
private readonly maxSize;
|
|
42
|
+
private readonly onEvict?;
|
|
43
|
+
/** Tracks the newest key for O(1) newest() access */
|
|
44
|
+
private _newestKey;
|
|
45
|
+
/**
|
|
46
|
+
* Creates a new LRUMap.
|
|
47
|
+
*
|
|
48
|
+
* @param options - Configuration options
|
|
49
|
+
*/
|
|
50
|
+
constructor(options: LRUMapOptions<K, V>);
|
|
51
|
+
/**
|
|
52
|
+
* Set a key-value pair.
|
|
53
|
+
* If key exists, updates value and refreshes position.
|
|
54
|
+
* If adding new entry would exceed maxSize, evicts oldest entries.
|
|
55
|
+
*
|
|
56
|
+
* @param key - Key to set
|
|
57
|
+
* @param value - Value to associate
|
|
58
|
+
* @returns this (for chaining)
|
|
59
|
+
*/
|
|
60
|
+
set(key: K, value: V): this;
|
|
61
|
+
/**
|
|
62
|
+
* Get a value and refresh its position (mark as most recently used).
|
|
63
|
+
*
|
|
64
|
+
* @param key - Key to look up
|
|
65
|
+
* @returns Value if found, undefined otherwise
|
|
66
|
+
*/
|
|
67
|
+
get(key: K): V | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Check if a key exists WITHOUT refreshing its position.
|
|
70
|
+
* Use this when you want to check existence without affecting LRU order.
|
|
71
|
+
*
|
|
72
|
+
* @param key - Key to check
|
|
73
|
+
* @returns True if key exists
|
|
74
|
+
*/
|
|
75
|
+
has(key: K): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Delete a key-value pair.
|
|
78
|
+
* Updates _newestKey if the deleted key was the newest.
|
|
79
|
+
*
|
|
80
|
+
* @param key - Key to delete
|
|
81
|
+
* @returns True if the key existed and was deleted
|
|
82
|
+
*/
|
|
83
|
+
delete(key: K): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Clear all entries.
|
|
86
|
+
* Resets _newestKey to undefined.
|
|
87
|
+
*/
|
|
88
|
+
clear(): void;
|
|
89
|
+
/**
|
|
90
|
+
* Peek at a value WITHOUT refreshing its position.
|
|
91
|
+
* Use this when you want to read without affecting LRU order.
|
|
92
|
+
*
|
|
93
|
+
* @param key - Key to peek
|
|
94
|
+
* @returns Value if found, undefined otherwise
|
|
95
|
+
*/
|
|
96
|
+
peek(key: K): V | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Get the oldest entry (next to be evicted) without removing it.
|
|
99
|
+
*
|
|
100
|
+
* @returns [key, value] of oldest entry, or undefined if empty
|
|
101
|
+
*/
|
|
102
|
+
oldest(): [K, V] | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Get the newest entry (most recently accessed).
|
|
105
|
+
* O(1) operation using tracked newest key.
|
|
106
|
+
*
|
|
107
|
+
* @returns [key, value] of newest entry, or undefined if empty
|
|
108
|
+
*/
|
|
109
|
+
newest(): [K, V] | undefined;
|
|
110
|
+
/**
|
|
111
|
+
* Evict entries older than a specific timestamp.
|
|
112
|
+
* Assumes values have a timestamp property or are numbers representing time.
|
|
113
|
+
*
|
|
114
|
+
* @param maxAge - Maximum age in milliseconds
|
|
115
|
+
* @param getTimestamp - Function to extract timestamp from value
|
|
116
|
+
* @returns Number of entries evicted
|
|
117
|
+
*/
|
|
118
|
+
expireOlderThan(maxAge: number, getTimestamp: (value: V) => number): number;
|
|
119
|
+
/**
|
|
120
|
+
* Get all keys in order from oldest to newest.
|
|
121
|
+
*
|
|
122
|
+
* @returns Array of keys
|
|
123
|
+
*/
|
|
124
|
+
keysInOrder(): K[];
|
|
125
|
+
/**
|
|
126
|
+
* Get all values in order from oldest to newest.
|
|
127
|
+
*
|
|
128
|
+
* @returns Array of values
|
|
129
|
+
*/
|
|
130
|
+
valuesInOrder(): V[];
|
|
131
|
+
/**
|
|
132
|
+
* Get the maximum size limit.
|
|
133
|
+
*/
|
|
134
|
+
get maxEntries(): number;
|
|
135
|
+
/**
|
|
136
|
+
* Get the number of free slots before eviction would occur.
|
|
137
|
+
*/
|
|
138
|
+
get freeSlots(): number;
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=lru-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lru-map.d.ts","sourceRoot":"","sources":["../../src/utils/lru-map.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa,CAAC,CAAC,EAAE,CAAC;IACjC,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;CACtC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,MAAM,CAAC,CAAC,EAAE,CAAC,CAAE,SAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA6B;IACtD,qDAAqD;IACrD,OAAO,CAAC,UAAU,CAA4B;IAE9C;;;;OAIG;gBACS,OAAO,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC;IAMxC;;;;;;;;OAQG;IACM,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAwBpC;;;;;OAKG;IACM,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAcnC;;;;;;OAMG;IACM,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAI7B;;;;;;OAMG;IACM,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAchC;;;OAGG;IACM,KAAK,IAAI,IAAI;IAKtB;;;;;;OAMG;IACH,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAI3B;;;;OAIG;IACH,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS;IAM5B;;;;;OAKG;IACH,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS;IAS5B;;;;;;;OAOG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM;IAkC3E;;;;OAIG;IACH,WAAW,IAAI,CAAC,EAAE;IAIlB;;;;OAIG;IACH,aAAa,IAAI,CAAC,EAAE;IAIpB;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;CACF"}
|