@shuji-bonji/rxjs-mcp 0.1.0
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.ja.md +284 -0
- package/README.md +295 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +94 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/analyze-operators.d.ts +3 -0
- package/dist/tools/analyze-operators.d.ts.map +1 -0
- package/dist/tools/analyze-operators.js +396 -0
- package/dist/tools/analyze-operators.js.map +1 -0
- package/dist/tools/execute-stream-worker.d.ts +2 -0
- package/dist/tools/execute-stream-worker.d.ts.map +1 -0
- package/dist/tools/execute-stream-worker.js +246 -0
- package/dist/tools/execute-stream-worker.js.map +1 -0
- package/dist/tools/execute-stream.d.ts +3 -0
- package/dist/tools/execute-stream.d.ts.map +1 -0
- package/dist/tools/execute-stream.js +219 -0
- package/dist/tools/execute-stream.js.map +1 -0
- package/dist/tools/marble-diagram.d.ts +3 -0
- package/dist/tools/marble-diagram.d.ts.map +1 -0
- package/dist/tools/marble-diagram.js +207 -0
- package/dist/tools/marble-diagram.js.map +1 -0
- package/dist/tools/memory-leak.d.ts +3 -0
- package/dist/tools/memory-leak.d.ts.map +1 -0
- package/dist/tools/memory-leak.js +285 -0
- package/dist/tools/memory-leak.js.map +1 -0
- package/dist/tools/suggest-pattern.d.ts +3 -0
- package/dist/tools/suggest-pattern.d.ts.map +1 -0
- package/dist/tools/suggest-pattern.js +571 -0
- package/dist/tools/suggest-pattern.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// Input schema
|
|
3
|
+
const inputSchema = z.object({
|
|
4
|
+
events: z.array(z.object({
|
|
5
|
+
time: z.number().describe('Time in milliseconds when the event occurs'),
|
|
6
|
+
value: z.any().describe('Value emitted at this time'),
|
|
7
|
+
type: z.enum(['next', 'error', 'complete']).optional().default('next'),
|
|
8
|
+
})).describe('Array of events to visualize'),
|
|
9
|
+
duration: z.number().optional().describe('Total duration to show in the diagram'),
|
|
10
|
+
scale: z.number().optional().default(50).describe('Time scale factor (ms per character)'),
|
|
11
|
+
showValues: z.boolean().optional().default(true).describe('Whether to show values below the timeline'),
|
|
12
|
+
});
|
|
13
|
+
// Generate ASCII marble diagram
|
|
14
|
+
function generateMarbleDiagram(events, duration, scale = 50, showValues = true) {
|
|
15
|
+
// Sort events by time
|
|
16
|
+
const sortedEvents = [...events].sort((a, b) => a.time - b.time);
|
|
17
|
+
// Determine diagram duration
|
|
18
|
+
const maxTime = sortedEvents.length > 0
|
|
19
|
+
? Math.max(...sortedEvents.map(e => e.time))
|
|
20
|
+
: 0;
|
|
21
|
+
const diagramDuration = duration || maxTime + scale * 2;
|
|
22
|
+
// Calculate diagram width
|
|
23
|
+
const width = Math.floor(diagramDuration / scale);
|
|
24
|
+
// Build the timeline
|
|
25
|
+
let timeline = '-'.repeat(width);
|
|
26
|
+
const valueMap = {};
|
|
27
|
+
// Place events on timeline
|
|
28
|
+
sortedEvents.forEach(event => {
|
|
29
|
+
const position = Math.floor(event.time / scale);
|
|
30
|
+
if (position < width) {
|
|
31
|
+
let marker;
|
|
32
|
+
switch (event.type) {
|
|
33
|
+
case 'error':
|
|
34
|
+
marker = '#';
|
|
35
|
+
break;
|
|
36
|
+
case 'complete':
|
|
37
|
+
marker = '|';
|
|
38
|
+
break;
|
|
39
|
+
default:
|
|
40
|
+
// Use letters or numbers for values
|
|
41
|
+
if (typeof event.value === 'string' && event.value.length === 1) {
|
|
42
|
+
marker = event.value;
|
|
43
|
+
}
|
|
44
|
+
else if (typeof event.value === 'number' && event.value >= 0 && event.value <= 9) {
|
|
45
|
+
marker = event.value.toString();
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// Use letters a-z for complex values
|
|
49
|
+
const charCode = 97 + (Object.keys(valueMap).length % 26);
|
|
50
|
+
marker = String.fromCharCode(charCode);
|
|
51
|
+
valueMap[position] = JSON.stringify(event.value);
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
// Replace character at position
|
|
56
|
+
timeline = timeline.substring(0, position) + marker + timeline.substring(position + 1);
|
|
57
|
+
if (event.type === 'next' && !valueMap[position]) {
|
|
58
|
+
valueMap[position] = JSON.stringify(event.value);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
// Build the complete diagram
|
|
63
|
+
const parts = [];
|
|
64
|
+
// Add timeline
|
|
65
|
+
parts.push(timeline);
|
|
66
|
+
// Add value references if needed
|
|
67
|
+
if (showValues && Object.keys(valueMap).length > 0) {
|
|
68
|
+
parts.push('');
|
|
69
|
+
parts.push('Values:');
|
|
70
|
+
Object.entries(valueMap).forEach(([pos, value]) => {
|
|
71
|
+
const position = parseInt(pos);
|
|
72
|
+
const marker = timeline[position];
|
|
73
|
+
if (marker && marker !== '-' && marker !== '|' && marker !== '#') {
|
|
74
|
+
parts.push(` ${marker} = ${value}`);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// Generate explanation
|
|
79
|
+
const explanation = generateExplanation(sortedEvents, scale);
|
|
80
|
+
return {
|
|
81
|
+
diagram: parts.join('\n'),
|
|
82
|
+
explanation,
|
|
83
|
+
timeline: sortedEvents.map(e => ({ time: e.time, value: e.value })),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// Generate human-readable explanation
|
|
87
|
+
function generateExplanation(events, scale) {
|
|
88
|
+
const parts = [];
|
|
89
|
+
if (events.length === 0) {
|
|
90
|
+
return 'Empty stream with no emissions';
|
|
91
|
+
}
|
|
92
|
+
parts.push(`Stream with ${events.length} event(s):`);
|
|
93
|
+
events.forEach((event, index) => {
|
|
94
|
+
const timeStr = `${event.time}ms`;
|
|
95
|
+
switch (event.type) {
|
|
96
|
+
case 'error':
|
|
97
|
+
parts.push(`- Error at ${timeStr}: ${event.value}`);
|
|
98
|
+
break;
|
|
99
|
+
case 'complete':
|
|
100
|
+
parts.push(`- Completed at ${timeStr}`);
|
|
101
|
+
break;
|
|
102
|
+
default:
|
|
103
|
+
parts.push(`- Emitted ${JSON.stringify(event.value)} at ${timeStr}`);
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
// Analyze patterns
|
|
108
|
+
if (events.length > 2) {
|
|
109
|
+
const intervals = [];
|
|
110
|
+
for (let i = 1; i < events.length; i++) {
|
|
111
|
+
if (events[i].type === 'next' && events[i - 1].type === 'next') {
|
|
112
|
+
intervals.push(events[i].time - events[i - 1].time);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (intervals.length > 0) {
|
|
116
|
+
const avgInterval = intervals.reduce((a, b) => a + b, 0) / intervals.length;
|
|
117
|
+
const isRegular = intervals.every(i => Math.abs(i - avgInterval) < scale / 2);
|
|
118
|
+
if (isRegular) {
|
|
119
|
+
parts.push(`\nPattern: Regular interval of ~${Math.round(avgInterval)}ms`);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
parts.push(`\nPattern: Irregular intervals (avg: ${Math.round(avgInterval)}ms)`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return parts.join('\n');
|
|
127
|
+
}
|
|
128
|
+
// Parse RxJS marble syntax
|
|
129
|
+
function parseMarbleSyntax(marble, values) {
|
|
130
|
+
const events = [];
|
|
131
|
+
const frameSize = 10; // Each frame is 10ms
|
|
132
|
+
for (let i = 0; i < marble.length; i++) {
|
|
133
|
+
const char = marble[i];
|
|
134
|
+
const time = i * frameSize;
|
|
135
|
+
switch (char) {
|
|
136
|
+
case '-':
|
|
137
|
+
// Frame boundary, no event
|
|
138
|
+
break;
|
|
139
|
+
case '|':
|
|
140
|
+
events.push({ time, value: undefined, type: 'complete' });
|
|
141
|
+
break;
|
|
142
|
+
case '#':
|
|
143
|
+
events.push({ time, value: 'Error', type: 'error' });
|
|
144
|
+
break;
|
|
145
|
+
case '(':
|
|
146
|
+
case ')':
|
|
147
|
+
// Grouping, ignore for now
|
|
148
|
+
break;
|
|
149
|
+
default:
|
|
150
|
+
// Value emission
|
|
151
|
+
const value = values?.[char] ?? char;
|
|
152
|
+
events.push({ time, value, type: 'next' });
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return events;
|
|
157
|
+
}
|
|
158
|
+
// Tool implementation
|
|
159
|
+
export const generateMarbleTool = {
|
|
160
|
+
definition: {
|
|
161
|
+
name: 'generate_marble',
|
|
162
|
+
description: 'Generate ASCII marble diagrams to visualize RxJS stream emissions over time',
|
|
163
|
+
inputSchema: inputSchema,
|
|
164
|
+
annotations: {
|
|
165
|
+
readOnlyHint: true,
|
|
166
|
+
idempotentHint: true,
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
handler: async (args) => {
|
|
170
|
+
const input = inputSchema.parse(args);
|
|
171
|
+
try {
|
|
172
|
+
const result = generateMarbleDiagram(input.events, input.duration, input.scale, input.showValues);
|
|
173
|
+
const output = [
|
|
174
|
+
'## Marble Diagram',
|
|
175
|
+
'',
|
|
176
|
+
'```',
|
|
177
|
+
result.diagram,
|
|
178
|
+
'```',
|
|
179
|
+
'',
|
|
180
|
+
'### Explanation',
|
|
181
|
+
result.explanation,
|
|
182
|
+
'',
|
|
183
|
+
'### Legend',
|
|
184
|
+
'- `-` : Time frame (each represents ~' + input.scale + 'ms)',
|
|
185
|
+
'- `|` : Stream completion',
|
|
186
|
+
'- `#` : Error',
|
|
187
|
+
'- Letters/Numbers: Emitted values',
|
|
188
|
+
].join('\n');
|
|
189
|
+
return {
|
|
190
|
+
content: [{
|
|
191
|
+
type: 'text',
|
|
192
|
+
text: output,
|
|
193
|
+
}],
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
198
|
+
return {
|
|
199
|
+
content: [{
|
|
200
|
+
type: 'text',
|
|
201
|
+
text: `## Error generating marble diagram\n\n${errorMessage}`,
|
|
202
|
+
}],
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
//# sourceMappingURL=marble-diagram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marble-diagram.js","sourceRoot":"","sources":["../../src/tools/marble-diagram.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-leak.d.ts","sourceRoot":"","sources":["../../src/tools/memory-leak.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAkC,MAAM,aAAa,CAAC;AA+OjF,eAAO,MAAM,oBAAoB,EAAE,kBAwElC,CAAC"}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// Input schema
|
|
3
|
+
const inputSchema = z.object({
|
|
4
|
+
code: z.string().describe('RxJS code to analyze for potential memory leaks'),
|
|
5
|
+
componentLifecycle: z.enum(['angular', 'react', 'vue', 'none']).optional().default('none').describe('Component lifecycle context'),
|
|
6
|
+
});
|
|
7
|
+
// Analyze code for memory leaks
|
|
8
|
+
function analyzeMemoryLeaks(code, lifecycle) {
|
|
9
|
+
const result = {
|
|
10
|
+
hasLeak: false,
|
|
11
|
+
leakSources: [],
|
|
12
|
+
recommendations: [],
|
|
13
|
+
};
|
|
14
|
+
// Check for unsubscribed subscriptions
|
|
15
|
+
const subscribeRegex = /\.subscribe\s*\(/g;
|
|
16
|
+
const unsubscribeRegex = /\.unsubscribe\s*\(\)/g;
|
|
17
|
+
const subscribeMatches = code.match(subscribeRegex) || [];
|
|
18
|
+
const unsubscribeMatches = code.match(unsubscribeRegex) || [];
|
|
19
|
+
if (subscribeMatches.length > unsubscribeMatches.length) {
|
|
20
|
+
result.hasLeak = true;
|
|
21
|
+
result.leakSources.push({
|
|
22
|
+
type: 'subscription',
|
|
23
|
+
description: `Found ${subscribeMatches.length} subscribe() calls but only ${unsubscribeMatches.length} unsubscribe() calls`,
|
|
24
|
+
severity: 'high',
|
|
25
|
+
suggestion: 'Store subscriptions and unsubscribe in cleanup (ngOnDestroy, useEffect cleanup, etc.)',
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// Check for missing takeUntil
|
|
29
|
+
const hasTakeUntil = /takeUntil\s*\(/.test(code);
|
|
30
|
+
const hasTakeWhile = /takeWhile\s*\(/.test(code);
|
|
31
|
+
const hasTake = /take\s*\(/.test(code);
|
|
32
|
+
const hasFirst = /first\s*\(/.test(code);
|
|
33
|
+
if (subscribeMatches.length > 0 && !hasTakeUntil && !hasTakeWhile && !hasTake && !hasFirst) {
|
|
34
|
+
result.hasLeak = true;
|
|
35
|
+
result.leakSources.push({
|
|
36
|
+
type: 'subscription',
|
|
37
|
+
description: 'Subscriptions without completion operators (takeUntil, take, first)',
|
|
38
|
+
severity: 'medium',
|
|
39
|
+
suggestion: 'Use takeUntil with a destroy$ subject for automatic cleanup',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// Check for interval/timer without limits
|
|
43
|
+
const hasInterval = /interval\s*\(/.test(code);
|
|
44
|
+
const hasTimer = /timer\s*\([^,)]+,[^)]+\)/.test(code); // Timer with period
|
|
45
|
+
if ((hasInterval || hasTimer) && !hasTake && !hasTakeUntil && !hasTakeWhile) {
|
|
46
|
+
result.hasLeak = true;
|
|
47
|
+
result.leakSources.push({
|
|
48
|
+
type: 'operator',
|
|
49
|
+
description: 'Infinite interval/timer without limiting operators',
|
|
50
|
+
severity: 'high',
|
|
51
|
+
suggestion: 'Add take() or takeUntil() to limit emissions',
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
// Check for subjects not being completed
|
|
55
|
+
const subjectRegex = /new\s+(Subject|BehaviorSubject|ReplaySubject|AsyncSubject)/g;
|
|
56
|
+
const subjectMatches = code.match(subjectRegex) || [];
|
|
57
|
+
const completeRegex = /\.complete\s*\(\)/g;
|
|
58
|
+
const completeMatches = code.match(completeRegex) || [];
|
|
59
|
+
if (subjectMatches.length > completeMatches.length) {
|
|
60
|
+
result.hasLeak = true;
|
|
61
|
+
result.leakSources.push({
|
|
62
|
+
type: 'subject',
|
|
63
|
+
description: `${subjectMatches.length} Subject(s) created but only ${completeMatches.length} complete() calls`,
|
|
64
|
+
severity: 'medium',
|
|
65
|
+
suggestion: 'Call complete() on Subjects in cleanup to release resources',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
// Check for shareReplay without refCount
|
|
69
|
+
const hasShareReplay = /shareReplay\s*\(/.test(code);
|
|
70
|
+
const hasRefCount = /refCount\s*:?\s*true/.test(code);
|
|
71
|
+
if (hasShareReplay && !hasRefCount) {
|
|
72
|
+
result.leakSources.push({
|
|
73
|
+
type: 'operator',
|
|
74
|
+
description: 'shareReplay() without refCount may keep subscriptions alive',
|
|
75
|
+
severity: 'low',
|
|
76
|
+
suggestion: 'Consider using shareReplay({ bufferSize: 1, refCount: true })',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// Check for event listeners without removal
|
|
80
|
+
const fromEventRegex = /fromEvent\s*\(/g;
|
|
81
|
+
const fromEventMatches = code.match(fromEventRegex) || [];
|
|
82
|
+
if (fromEventMatches.length > 0 && !hasTakeUntil) {
|
|
83
|
+
result.hasLeak = true;
|
|
84
|
+
result.leakSources.push({
|
|
85
|
+
type: 'operator',
|
|
86
|
+
description: 'fromEvent() creates DOM event listeners that may not be removed',
|
|
87
|
+
severity: 'high',
|
|
88
|
+
suggestion: 'Use takeUntil() to remove event listeners on cleanup',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Framework-specific checks
|
|
92
|
+
if (lifecycle === 'angular') {
|
|
93
|
+
// Check for async pipe usage (good practice)
|
|
94
|
+
const hasAsyncPipe = /\|\s*async/.test(code);
|
|
95
|
+
if (!hasAsyncPipe && subscribeMatches.length > 0) {
|
|
96
|
+
result.recommendations.push('Consider using Angular\'s async pipe to auto-manage subscriptions');
|
|
97
|
+
}
|
|
98
|
+
// Check for ngOnDestroy
|
|
99
|
+
const hasNgOnDestroy = /ngOnDestroy\s*\(/.test(code);
|
|
100
|
+
if (!hasNgOnDestroy && subscribeMatches.length > 0) {
|
|
101
|
+
result.recommendations.push('Implement OnDestroy lifecycle hook for cleanup');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else if (lifecycle === 'react') {
|
|
105
|
+
// Check for useEffect cleanup
|
|
106
|
+
const hasUseEffect = /useEffect\s*\(/.test(code);
|
|
107
|
+
// Match various cleanup return patterns:
|
|
108
|
+
// - return () => { ... }
|
|
109
|
+
// - return () => subscription.unsubscribe()
|
|
110
|
+
// - return () => sub.unsubscribe();
|
|
111
|
+
// - return cleanup;
|
|
112
|
+
// - return function cleanup() { ... }
|
|
113
|
+
const hasCleanupReturn = /return\s+(\(\s*\)\s*=>|function\s*\w*\s*\(|[a-zA-Z_$][\w$]*\s*;)/.test(code);
|
|
114
|
+
const hasUnsubscribeInReturn = /return\s+\(\s*\)\s*=>\s*\w+\.unsubscribe\s*\(\s*\)/.test(code);
|
|
115
|
+
if (hasUseEffect && subscribeMatches.length > 0 && !hasCleanupReturn && !hasUnsubscribeInReturn) {
|
|
116
|
+
result.recommendations.push('Return cleanup function from useEffect to unsubscribe');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (lifecycle === 'vue') {
|
|
120
|
+
// Check for beforeDestroy/beforeUnmount
|
|
121
|
+
const hasBeforeDestroy = /beforeDestroy|beforeUnmount|onBeforeUnmount/.test(code);
|
|
122
|
+
if (!hasBeforeDestroy && subscribeMatches.length > 0) {
|
|
123
|
+
result.recommendations.push('Use beforeUnmount/onBeforeUnmount for cleanup in Vue 3');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// General recommendations
|
|
127
|
+
if (result.hasLeak) {
|
|
128
|
+
result.recommendations.push('Use a subscription management pattern (e.g., SubSink, subscription array)');
|
|
129
|
+
result.recommendations.push('Consider using operators that auto-complete (first, take, takeUntil)');
|
|
130
|
+
if (subscribeMatches.length > 3) {
|
|
131
|
+
result.recommendations.push('With many subscriptions, consider combining streams with merge/combineLatest');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
// Generate code example for proper cleanup
|
|
137
|
+
function generateCleanupExample(lifecycle) {
|
|
138
|
+
const examples = {
|
|
139
|
+
angular: `
|
|
140
|
+
// Angular Component with proper cleanup
|
|
141
|
+
export class MyComponent implements OnDestroy {
|
|
142
|
+
private destroy$ = new Subject<void>();
|
|
143
|
+
|
|
144
|
+
ngOnInit() {
|
|
145
|
+
// Method 1: takeUntil pattern
|
|
146
|
+
this.myService.getData()
|
|
147
|
+
.pipe(takeUntil(this.destroy$))
|
|
148
|
+
.subscribe(data => console.log(data));
|
|
149
|
+
|
|
150
|
+
// Method 2: Async pipe in template
|
|
151
|
+
this.data$ = this.myService.getData();
|
|
152
|
+
// Template: {{ data$ | async }}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
ngOnDestroy() {
|
|
156
|
+
this.destroy$.next();
|
|
157
|
+
this.destroy$.complete();
|
|
158
|
+
}
|
|
159
|
+
}`,
|
|
160
|
+
react: `
|
|
161
|
+
// React Hook with proper cleanup
|
|
162
|
+
function MyComponent() {
|
|
163
|
+
useEffect(() => {
|
|
164
|
+
const subscription = dataStream$
|
|
165
|
+
.pipe(/* operators */)
|
|
166
|
+
.subscribe(data => setData(data));
|
|
167
|
+
|
|
168
|
+
// Cleanup function
|
|
169
|
+
return () => {
|
|
170
|
+
subscription.unsubscribe();
|
|
171
|
+
};
|
|
172
|
+
}, [/* dependencies */]);
|
|
173
|
+
}`,
|
|
174
|
+
vue: `
|
|
175
|
+
// Vue 3 Composition API with proper cleanup
|
|
176
|
+
import { onBeforeUnmount } from 'vue';
|
|
177
|
+
|
|
178
|
+
export default {
|
|
179
|
+
setup() {
|
|
180
|
+
const destroy$ = new Subject();
|
|
181
|
+
|
|
182
|
+
// Subscribe with takeUntil
|
|
183
|
+
dataStream$
|
|
184
|
+
.pipe(takeUntil(destroy$))
|
|
185
|
+
.subscribe(data => state.data = data);
|
|
186
|
+
|
|
187
|
+
onBeforeUnmount(() => {
|
|
188
|
+
destroy$.next();
|
|
189
|
+
destroy$.complete();
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}`,
|
|
193
|
+
none: `
|
|
194
|
+
// Generic cleanup pattern
|
|
195
|
+
class StreamManager {
|
|
196
|
+
private subscriptions = new Subscription();
|
|
197
|
+
|
|
198
|
+
init() {
|
|
199
|
+
// Add subscriptions to composite
|
|
200
|
+
this.subscriptions.add(
|
|
201
|
+
stream1$.subscribe(/* ... */)
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
this.subscriptions.add(
|
|
205
|
+
stream2$.subscribe(/* ... */)
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
cleanup() {
|
|
210
|
+
// Unsubscribe all at once
|
|
211
|
+
this.subscriptions.unsubscribe();
|
|
212
|
+
}
|
|
213
|
+
}`,
|
|
214
|
+
};
|
|
215
|
+
return examples[lifecycle] || examples.none;
|
|
216
|
+
}
|
|
217
|
+
// Tool implementation
|
|
218
|
+
export const detectMemoryLeakTool = {
|
|
219
|
+
definition: {
|
|
220
|
+
name: 'detect_memory_leak',
|
|
221
|
+
description: 'Analyze RxJS code for potential memory leaks and subscription management issues',
|
|
222
|
+
inputSchema: inputSchema,
|
|
223
|
+
annotations: {
|
|
224
|
+
readOnlyHint: true,
|
|
225
|
+
idempotentHint: true,
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
handler: async (args) => {
|
|
229
|
+
const input = inputSchema.parse(args);
|
|
230
|
+
try {
|
|
231
|
+
const result = analyzeMemoryLeaks(input.code, input.componentLifecycle);
|
|
232
|
+
const parts = [
|
|
233
|
+
'## Memory Leak Analysis',
|
|
234
|
+
'',
|
|
235
|
+
`**Status:** ${result.hasLeak ? '⚠️ Potential leaks detected' : '✅ No obvious leaks detected'}`,
|
|
236
|
+
'',
|
|
237
|
+
];
|
|
238
|
+
if (result.leakSources.length > 0) {
|
|
239
|
+
parts.push('### Detected Issues');
|
|
240
|
+
result.leakSources.forEach((leak, i) => {
|
|
241
|
+
const severityIcon = leak.severity === 'high' ? '🔴' : leak.severity === 'medium' ? '🟡' : '🟢';
|
|
242
|
+
parts.push(`${i + 1}. ${severityIcon} **${leak.type}** (${leak.severity} severity)`);
|
|
243
|
+
parts.push(` - ${leak.description}`);
|
|
244
|
+
parts.push(` - **Fix:** ${leak.suggestion}`);
|
|
245
|
+
parts.push('');
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
if (result.recommendations.length > 0) {
|
|
249
|
+
parts.push('### Recommendations');
|
|
250
|
+
result.recommendations.forEach(rec => {
|
|
251
|
+
parts.push(`- ${rec}`);
|
|
252
|
+
});
|
|
253
|
+
parts.push('');
|
|
254
|
+
}
|
|
255
|
+
// Add cleanup example
|
|
256
|
+
parts.push('### Proper Cleanup Pattern');
|
|
257
|
+
parts.push('```typescript');
|
|
258
|
+
parts.push(generateCleanupExample(input.componentLifecycle).trim());
|
|
259
|
+
parts.push('```');
|
|
260
|
+
// Add best practices
|
|
261
|
+
parts.push('', '### Best Practices');
|
|
262
|
+
parts.push('1. **Always unsubscribe** from infinite streams (interval, fromEvent, Subject)');
|
|
263
|
+
parts.push('2. **Use limiting operators** (take, takeUntil, first) when possible');
|
|
264
|
+
parts.push('3. **Complete Subjects** in cleanup to free resources');
|
|
265
|
+
parts.push('4. **Prefer async pipe** (Angular) or hooks (React) for auto-cleanup');
|
|
266
|
+
parts.push('5. **Use shareReplay carefully** with refCount: true for shared streams');
|
|
267
|
+
return {
|
|
268
|
+
content: [{
|
|
269
|
+
type: 'text',
|
|
270
|
+
text: parts.join('\n'),
|
|
271
|
+
}],
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
276
|
+
return {
|
|
277
|
+
content: [{
|
|
278
|
+
type: 'text',
|
|
279
|
+
text: `## Error analyzing code\n\n${errorMessage}`,
|
|
280
|
+
}],
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
//# sourceMappingURL=memory-leak.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-leak.js","sourceRoot":"","sources":["../../src/tools/memory-leak.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest-pattern.d.ts","sourceRoot":"","sources":["../../src/tools/suggest-pattern.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAmC,MAAM,aAAa,CAAC;AA8flF,eAAO,MAAM,kBAAkB,EAAE,kBA2EhC,CAAC"}
|