@shuji-bonji/rxjs-mcp 0.1.1 → 0.1.3
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/dist/data/cleanup-examples.d.ts +9 -0
- package/dist/data/cleanup-examples.d.ts.map +1 -0
- package/dist/data/cleanup-examples.js +87 -0
- package/dist/data/cleanup-examples.js.map +1 -0
- package/dist/data/creation-functions.d.ts +7 -0
- package/dist/data/creation-functions.d.ts.map +1 -0
- package/dist/data/creation-functions.js +135 -0
- package/dist/data/creation-functions.js.map +1 -0
- package/dist/data/operators.d.ts +7 -0
- package/dist/data/operators.d.ts.map +1 -0
- package/dist/data/operators.js +500 -0
- package/dist/data/operators.js.map +1 -0
- package/dist/data/patterns.d.ts +10 -0
- package/dist/data/patterns.d.ts.map +1 -0
- package/dist/data/patterns.js +482 -0
- package/dist/data/patterns.js.map +1 -0
- package/dist/data/rxjs-context.d.ts +169 -0
- package/dist/data/rxjs-context.d.ts.map +1 -0
- package/dist/data/rxjs-context.js +209 -0
- package/dist/data/rxjs-context.js.map +1 -0
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/analyze-operators.d.ts.map +1 -1
- package/dist/tools/analyze-operators.js +2 -121
- package/dist/tools/analyze-operators.js.map +1 -1
- package/dist/tools/execute-stream-worker.js +7 -149
- package/dist/tools/execute-stream-worker.js.map +1 -1
- package/dist/tools/execute-stream.d.ts.map +1 -1
- package/dist/tools/execute-stream.js +33 -67
- package/dist/tools/execute-stream.js.map +1 -1
- package/dist/tools/memory-leak.d.ts.map +1 -1
- package/dist/tools/memory-leak.js +2 -82
- package/dist/tools/memory-leak.js.map +1 -1
- package/dist/tools/suggest-pattern.d.ts.map +1 -1
- package/dist/tools/suggest-pattern.js +1 -477
- package/dist/tools/suggest-pattern.js.map +1 -1
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { patterns, adaptPatternForFramework } from '../data/patterns.js';
|
|
2
3
|
// Input schema
|
|
3
4
|
const inputSchema = z.object({
|
|
4
5
|
useCase: z.enum([
|
|
@@ -20,483 +21,6 @@ const inputSchema = z.object({
|
|
|
20
21
|
]).describe('The use case for which to suggest an RxJS pattern'),
|
|
21
22
|
framework: z.enum(['angular', 'react', 'vue', 'vanilla']).optional().default('vanilla').describe('Target framework for the pattern'),
|
|
22
23
|
});
|
|
23
|
-
// Pattern database
|
|
24
|
-
const patterns = {
|
|
25
|
-
'http-retry': {
|
|
26
|
-
name: 'HTTP Request with Retry',
|
|
27
|
-
description: 'Resilient HTTP requests with exponential backoff retry strategy',
|
|
28
|
-
useCase: 'Making API calls that may fail due to network issues or server errors',
|
|
29
|
-
operators: ['retry', 'retryWhen', 'delay', 'catchError', 'timer'],
|
|
30
|
-
code: `// HTTP request with exponential backoff retry
|
|
31
|
-
import { throwError, timer, of } from 'rxjs';
|
|
32
|
-
import { ajax } from 'rxjs/ajax';
|
|
33
|
-
import { retryWhen, mergeMap, catchError, finalize } from 'rxjs/operators';
|
|
34
|
-
|
|
35
|
-
const apiCall$ = ajax.getJSON('/api/data').pipe(
|
|
36
|
-
retryWhen(errors =>
|
|
37
|
-
errors.pipe(
|
|
38
|
-
mergeMap((error, index) => {
|
|
39
|
-
const retryAttempt = index + 1;
|
|
40
|
-
if (retryAttempt > 3) {
|
|
41
|
-
return throwError(() => error);
|
|
42
|
-
}
|
|
43
|
-
console.log(\`Retry attempt \${retryAttempt} after \${retryAttempt * 1000}ms\`);
|
|
44
|
-
return timer(retryAttempt * 1000); // Exponential backoff
|
|
45
|
-
})
|
|
46
|
-
)
|
|
47
|
-
),
|
|
48
|
-
catchError(error => {
|
|
49
|
-
console.error('Failed after 3 retries:', error);
|
|
50
|
-
return of({ error: true, message: 'Service unavailable' });
|
|
51
|
-
}),
|
|
52
|
-
finalize(() => console.log('Request completed'))
|
|
53
|
-
);`,
|
|
54
|
-
considerations: [
|
|
55
|
-
'Set a maximum retry count to prevent infinite retries',
|
|
56
|
-
'Use exponential backoff to avoid overwhelming the server',
|
|
57
|
-
'Provide fallback data on final failure',
|
|
58
|
-
'Log retry attempts for debugging',
|
|
59
|
-
],
|
|
60
|
-
},
|
|
61
|
-
'search-typeahead': {
|
|
62
|
-
name: 'Search Typeahead with Debounce',
|
|
63
|
-
description: 'Efficient search implementation with debouncing and cancellation',
|
|
64
|
-
useCase: 'Real-time search suggestions as user types, minimizing API calls',
|
|
65
|
-
operators: ['debounceTime', 'distinctUntilChanged', 'switchMap', 'catchError', 'filter'],
|
|
66
|
-
code: `// Search typeahead implementation
|
|
67
|
-
import { fromEvent, of, EMPTY } from 'rxjs';
|
|
68
|
-
import { ajax } from 'rxjs/ajax';
|
|
69
|
-
import { debounceTime, distinctUntilChanged, switchMap, catchError, filter, map } from 'rxjs/operators';
|
|
70
|
-
|
|
71
|
-
const searchBox = document.getElementById('search');
|
|
72
|
-
const search$ = fromEvent(searchBox, 'input').pipe(
|
|
73
|
-
map(event => (event.target as HTMLInputElement).value),
|
|
74
|
-
filter(query => query.length > 2), // Min 3 characters
|
|
75
|
-
debounceTime(300), // Wait for pause in typing
|
|
76
|
-
distinctUntilChanged(), // Ignore if same as previous
|
|
77
|
-
switchMap(query =>
|
|
78
|
-
ajax.getJSON(\`/api/search?q=\${query}\`).pipe(
|
|
79
|
-
catchError(error => {
|
|
80
|
-
console.error('Search failed:', error);
|
|
81
|
-
return of([]); // Return empty results on error
|
|
82
|
-
})
|
|
83
|
-
)
|
|
84
|
-
)
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
search$.subscribe(results => {
|
|
88
|
-
displaySearchResults(results);
|
|
89
|
-
});`,
|
|
90
|
-
considerations: [
|
|
91
|
-
'Use debounceTime to wait for typing pause',
|
|
92
|
-
'distinctUntilChanged prevents duplicate searches',
|
|
93
|
-
'switchMap cancels previous requests automatically',
|
|
94
|
-
'Handle errors gracefully with empty results',
|
|
95
|
-
'Set minimum query length to reduce noise',
|
|
96
|
-
],
|
|
97
|
-
},
|
|
98
|
-
'polling': {
|
|
99
|
-
name: 'Smart Polling with Backoff',
|
|
100
|
-
description: 'Periodic data fetching with error handling and dynamic intervals',
|
|
101
|
-
useCase: 'Regularly checking for updates while being respectful of server resources',
|
|
102
|
-
operators: ['interval', 'switchMap', 'retry', 'catchError', 'takeWhile', 'expand'],
|
|
103
|
-
code: `// Smart polling with exponential backoff on errors
|
|
104
|
-
import { interval, timer, throwError, EMPTY } from 'rxjs';
|
|
105
|
-
import { ajax } from 'rxjs/ajax';
|
|
106
|
-
import { switchMap, retry, catchError, takeWhile, expand, tap } from 'rxjs/operators';
|
|
107
|
-
|
|
108
|
-
let errorCount = 0;
|
|
109
|
-
const maxErrors = 3;
|
|
110
|
-
|
|
111
|
-
const polling$ = timer(0, 5000).pipe( // Start immediately, then every 5s
|
|
112
|
-
switchMap(() =>
|
|
113
|
-
ajax.getJSON('/api/status').pipe(
|
|
114
|
-
tap(() => errorCount = 0), // Reset on success
|
|
115
|
-
catchError(error => {
|
|
116
|
-
errorCount++;
|
|
117
|
-
if (errorCount >= maxErrors) {
|
|
118
|
-
console.error('Max errors reached, stopping polling');
|
|
119
|
-
return throwError(() => error);
|
|
120
|
-
}
|
|
121
|
-
console.log(\`Error \${errorCount}, backing off...\`);
|
|
122
|
-
return EMPTY; // Skip this emission
|
|
123
|
-
})
|
|
124
|
-
)
|
|
125
|
-
),
|
|
126
|
-
takeWhile(() => errorCount < maxErrors)
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
// Alternative: Dynamic polling interval
|
|
130
|
-
const dynamicPolling$ = ajax.getJSON('/api/data').pipe(
|
|
131
|
-
expand(data =>
|
|
132
|
-
timer(data.nextPollDelay || 5000).pipe(
|
|
133
|
-
switchMap(() => ajax.getJSON('/api/data'))
|
|
134
|
-
)
|
|
135
|
-
)
|
|
136
|
-
);`,
|
|
137
|
-
considerations: [
|
|
138
|
-
'Implement backoff strategy for errors',
|
|
139
|
-
'Allow server to control polling rate',
|
|
140
|
-
'Stop polling after consecutive failures',
|
|
141
|
-
'Consider WebSockets for real-time requirements',
|
|
142
|
-
'Add jitter to prevent thundering herd',
|
|
143
|
-
],
|
|
144
|
-
},
|
|
145
|
-
'websocket-reconnect': {
|
|
146
|
-
name: 'WebSocket with Auto-Reconnect',
|
|
147
|
-
description: 'Resilient WebSocket connection with automatic reconnection',
|
|
148
|
-
useCase: 'Maintaining persistent real-time connections with fallback',
|
|
149
|
-
operators: ['webSocket', 'retryWhen', 'delay', 'tap', 'catchError'],
|
|
150
|
-
code: `// WebSocket with automatic reconnection
|
|
151
|
-
import { webSocket } from 'rxjs/webSocket';
|
|
152
|
-
import { retry, retryWhen, delay, tap, catchError } from 'rxjs/operators';
|
|
153
|
-
import { EMPTY } from 'rxjs';
|
|
154
|
-
|
|
155
|
-
const createWebSocketSubject = () =>
|
|
156
|
-
webSocket({
|
|
157
|
-
url: 'ws://localhost:8080',
|
|
158
|
-
openObserver: {
|
|
159
|
-
next: () => console.log('WebSocket connected')
|
|
160
|
-
},
|
|
161
|
-
closeObserver: {
|
|
162
|
-
next: () => console.log('WebSocket disconnected')
|
|
163
|
-
}
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
let socket$ = createWebSocketSubject();
|
|
167
|
-
|
|
168
|
-
const resilientSocket$ = socket$.pipe(
|
|
169
|
-
retryWhen(errors =>
|
|
170
|
-
errors.pipe(
|
|
171
|
-
tap(err => console.log('WebSocket error, reconnecting...', err)),
|
|
172
|
-
delay(1000) // Wait before reconnecting
|
|
173
|
-
)
|
|
174
|
-
),
|
|
175
|
-
catchError(err => {
|
|
176
|
-
console.error('WebSocket failed permanently:', err);
|
|
177
|
-
return EMPTY;
|
|
178
|
-
})
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
// Send messages
|
|
182
|
-
const sendMessage = (message: any) => {
|
|
183
|
-
socket$.next(message);
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
// Subscribe to messages
|
|
187
|
-
resilientSocket$.subscribe({
|
|
188
|
-
next: msg => console.log('Received:', msg),
|
|
189
|
-
error: err => console.error('Fatal error:', err),
|
|
190
|
-
complete: () => console.log('Connection closed')
|
|
191
|
-
});`,
|
|
192
|
-
considerations: [
|
|
193
|
-
'Implement exponential backoff for reconnection',
|
|
194
|
-
'Queue messages during disconnection',
|
|
195
|
-
'Handle connection state in UI',
|
|
196
|
-
'Consider fallback to HTTP polling',
|
|
197
|
-
'Implement heartbeat/ping mechanism',
|
|
198
|
-
],
|
|
199
|
-
},
|
|
200
|
-
'form-validation': {
|
|
201
|
-
name: 'Reactive Form Validation',
|
|
202
|
-
description: 'Real-time form validation with debouncing and async validators',
|
|
203
|
-
useCase: 'Validating form inputs with instant feedback and async checks',
|
|
204
|
-
operators: ['combineLatest', 'debounceTime', 'distinctUntilChanged', 'switchMap', 'map'],
|
|
205
|
-
code: `// Reactive form validation
|
|
206
|
-
import { fromEvent, combineLatest, of, timer } from 'rxjs';
|
|
207
|
-
import { debounceTime, distinctUntilChanged, switchMap, map, startWith } from 'rxjs/operators';
|
|
208
|
-
import { ajax } from 'rxjs/ajax';
|
|
209
|
-
|
|
210
|
-
const emailInput = document.getElementById('email') as HTMLInputElement;
|
|
211
|
-
const passwordInput = document.getElementById('password') as HTMLInputElement;
|
|
212
|
-
|
|
213
|
-
const email$ = fromEvent(emailInput, 'input').pipe(
|
|
214
|
-
map(e => (e.target as HTMLInputElement).value),
|
|
215
|
-
startWith(''),
|
|
216
|
-
debounceTime(300),
|
|
217
|
-
distinctUntilChanged(),
|
|
218
|
-
switchMap(email => {
|
|
219
|
-
if (!email) return of({ valid: false, error: 'Email required' });
|
|
220
|
-
if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email)) {
|
|
221
|
-
return of({ valid: false, error: 'Invalid email format' });
|
|
222
|
-
}
|
|
223
|
-
// Async validation - check if email exists
|
|
224
|
-
return ajax.getJSON(\`/api/check-email?email=\${email}\`).pipe(
|
|
225
|
-
map(result => ({
|
|
226
|
-
valid: !(result as any).exists,
|
|
227
|
-
error: (result as any).exists ? 'Email already taken' : null
|
|
228
|
-
}))
|
|
229
|
-
);
|
|
230
|
-
})
|
|
231
|
-
);
|
|
232
|
-
|
|
233
|
-
const password$ = fromEvent(passwordInput, 'input').pipe(
|
|
234
|
-
map(e => (e.target as HTMLInputElement).value),
|
|
235
|
-
startWith(''),
|
|
236
|
-
map(password => ({
|
|
237
|
-
valid: password.length >= 8,
|
|
238
|
-
error: password.length < 8 ? 'Password must be 8+ characters' : null
|
|
239
|
-
}))
|
|
240
|
-
);
|
|
241
|
-
|
|
242
|
-
const formValid$ = combineLatest([email$, password$]).pipe(
|
|
243
|
-
map(([email, password]) => ({
|
|
244
|
-
valid: email.valid && password.valid,
|
|
245
|
-
errors: {
|
|
246
|
-
email: email.error,
|
|
247
|
-
password: password.error
|
|
248
|
-
}
|
|
249
|
-
}))
|
|
250
|
-
);
|
|
251
|
-
|
|
252
|
-
formValid$.subscribe(validation => {
|
|
253
|
-
updateFormUI(validation);
|
|
254
|
-
});`,
|
|
255
|
-
considerations: [
|
|
256
|
-
'Debounce async validators to reduce API calls',
|
|
257
|
-
'Show loading states during validation',
|
|
258
|
-
'Cache validation results when appropriate',
|
|
259
|
-
'Validate on blur for better UX',
|
|
260
|
-
'Consider field dependencies for complex forms',
|
|
261
|
-
],
|
|
262
|
-
},
|
|
263
|
-
'state-management': {
|
|
264
|
-
name: 'Simple State Management',
|
|
265
|
-
description: 'Centralized state management using RxJS subjects',
|
|
266
|
-
useCase: 'Managing application state without external libraries',
|
|
267
|
-
operators: ['scan', 'shareReplay', 'distinctUntilChanged', 'pluck'],
|
|
268
|
-
code: `// Simple state management with RxJS
|
|
269
|
-
import { BehaviorSubject, Subject, merge } from 'rxjs';
|
|
270
|
-
import { scan, shareReplay, distinctUntilChanged, map } from 'rxjs/operators';
|
|
271
|
-
|
|
272
|
-
interface AppState {
|
|
273
|
-
user: { id: string; name: string } | null;
|
|
274
|
-
items: Array<{ id: string; title: string }>;
|
|
275
|
-
loading: boolean;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// Initial state
|
|
279
|
-
const initialState: AppState = {
|
|
280
|
-
user: null,
|
|
281
|
-
items: [],
|
|
282
|
-
loading: false
|
|
283
|
-
};
|
|
284
|
-
|
|
285
|
-
// Actions
|
|
286
|
-
interface Action {
|
|
287
|
-
type: string;
|
|
288
|
-
payload?: any;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// Action creators
|
|
292
|
-
const actions$ = new Subject<Action>();
|
|
293
|
-
|
|
294
|
-
const setUser = (user: AppState['user']) =>
|
|
295
|
-
actions$.next({ type: 'SET_USER', payload: user });
|
|
296
|
-
|
|
297
|
-
const addItem = (item: { id: string; title: string }) =>
|
|
298
|
-
actions$.next({ type: 'ADD_ITEM', payload: item });
|
|
299
|
-
|
|
300
|
-
const setLoading = (loading: boolean) =>
|
|
301
|
-
actions$.next({ type: 'SET_LOADING', payload: loading });
|
|
302
|
-
|
|
303
|
-
// Reducer
|
|
304
|
-
const reducer = (state: AppState, action: Action): AppState => {
|
|
305
|
-
switch (action.type) {
|
|
306
|
-
case 'SET_USER':
|
|
307
|
-
return { ...state, user: action.payload };
|
|
308
|
-
case 'ADD_ITEM':
|
|
309
|
-
return { ...state, items: [...state.items, action.payload] };
|
|
310
|
-
case 'SET_LOADING':
|
|
311
|
-
return { ...state, loading: action.payload };
|
|
312
|
-
default:
|
|
313
|
-
return state;
|
|
314
|
-
}
|
|
315
|
-
};
|
|
316
|
-
|
|
317
|
-
// State stream
|
|
318
|
-
const state$ = actions$.pipe(
|
|
319
|
-
scan(reducer, initialState),
|
|
320
|
-
shareReplay(1)
|
|
321
|
-
);
|
|
322
|
-
|
|
323
|
-
// Selectors
|
|
324
|
-
const user$ = state$.pipe(
|
|
325
|
-
map(state => state.user),
|
|
326
|
-
distinctUntilChanged()
|
|
327
|
-
);
|
|
328
|
-
|
|
329
|
-
const items$ = state$.pipe(
|
|
330
|
-
map(state => state.items),
|
|
331
|
-
distinctUntilChanged()
|
|
332
|
-
);
|
|
333
|
-
|
|
334
|
-
const loading$ = state$.pipe(
|
|
335
|
-
map(state => state.loading),
|
|
336
|
-
distinctUntilChanged()
|
|
337
|
-
);
|
|
338
|
-
|
|
339
|
-
// Subscribe to state changes
|
|
340
|
-
state$.subscribe(state => console.log('State updated:', state));`,
|
|
341
|
-
considerations: [
|
|
342
|
-
'Use BehaviorSubject for synchronous state access',
|
|
343
|
-
'Implement selectors with distinctUntilChanged',
|
|
344
|
-
'Consider immutability for predictable updates',
|
|
345
|
-
'Add middleware for side effects',
|
|
346
|
-
'Use shareReplay for multiple subscribers',
|
|
347
|
-
],
|
|
348
|
-
},
|
|
349
|
-
'cache-refresh': {
|
|
350
|
-
name: 'Cache with Refresh Strategy',
|
|
351
|
-
description: 'Cached data with manual and automatic refresh capabilities',
|
|
352
|
-
useCase: 'Serving cached data instantly while fetching fresh data in background',
|
|
353
|
-
operators: ['shareReplay', 'merge', 'switchMap', 'startWith'],
|
|
354
|
-
code: `// Cache with refresh strategy
|
|
355
|
-
import { BehaviorSubject, Subject, timer, merge } from 'rxjs';
|
|
356
|
-
import { switchMap, shareReplay, startWith, tap } from 'rxjs/operators';
|
|
357
|
-
import { ajax } from 'rxjs/ajax';
|
|
358
|
-
|
|
359
|
-
class CachedDataService {
|
|
360
|
-
private refreshSubject = new Subject<void>();
|
|
361
|
-
private cache$ = new BehaviorSubject<any>(null);
|
|
362
|
-
|
|
363
|
-
// Automatic refresh every 30 seconds
|
|
364
|
-
private autoRefresh$ = timer(0, 30000);
|
|
365
|
-
|
|
366
|
-
// Combine manual and auto refresh triggers
|
|
367
|
-
private dataSource$ = merge(
|
|
368
|
-
this.autoRefresh$,
|
|
369
|
-
this.refreshSubject
|
|
370
|
-
).pipe(
|
|
371
|
-
switchMap(() => ajax.getJSON('/api/data')),
|
|
372
|
-
tap(data => this.cache$.next(data)),
|
|
373
|
-
shareReplay({
|
|
374
|
-
bufferSize: 1,
|
|
375
|
-
refCount: true
|
|
376
|
-
})
|
|
377
|
-
);
|
|
378
|
-
|
|
379
|
-
// Public API
|
|
380
|
-
getData() {
|
|
381
|
-
const cached = this.cache$.value;
|
|
382
|
-
if (cached) {
|
|
383
|
-
// Return cached data immediately, fetch fresh in background
|
|
384
|
-
return merge(
|
|
385
|
-
of(cached),
|
|
386
|
-
this.dataSource$
|
|
387
|
-
).pipe(
|
|
388
|
-
distinctUntilChanged((a, b) =>
|
|
389
|
-
JSON.stringify(a) === JSON.stringify(b)
|
|
390
|
-
)
|
|
391
|
-
);
|
|
392
|
-
}
|
|
393
|
-
return this.dataSource$;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
refresh() {
|
|
397
|
-
this.refreshSubject.next();
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// Cache invalidation
|
|
401
|
-
invalidate() {
|
|
402
|
-
this.cache$.next(null);
|
|
403
|
-
this.refresh();
|
|
404
|
-
}
|
|
405
|
-
}`,
|
|
406
|
-
considerations: [
|
|
407
|
-
'Implement cache expiration policies',
|
|
408
|
-
'Handle stale-while-revalidate pattern',
|
|
409
|
-
'Consider memory limits for cache size',
|
|
410
|
-
'Add cache versioning for updates',
|
|
411
|
-
'Implement offline support with persistence',
|
|
412
|
-
],
|
|
413
|
-
},
|
|
414
|
-
};
|
|
415
|
-
// Add framework-specific modifications
|
|
416
|
-
function adaptPatternForFramework(pattern, framework) {
|
|
417
|
-
const adapted = { ...pattern };
|
|
418
|
-
if (framework === 'angular') {
|
|
419
|
-
adapted.code = `// Angular-specific implementation
|
|
420
|
-
@Injectable({ providedIn: 'root' })
|
|
421
|
-
export class RxJSPatternService implements OnDestroy {
|
|
422
|
-
private destroy$ = new Subject<void>();
|
|
423
|
-
|
|
424
|
-
${pattern.code}
|
|
425
|
-
|
|
426
|
-
ngOnDestroy() {
|
|
427
|
-
this.destroy$.next();
|
|
428
|
-
this.destroy$.complete();
|
|
429
|
-
}
|
|
430
|
-
}`;
|
|
431
|
-
adapted.considerations = [
|
|
432
|
-
...pattern.considerations,
|
|
433
|
-
'Use async pipe in templates for auto-unsubscribe',
|
|
434
|
-
'Inject HttpClient instead of ajax',
|
|
435
|
-
'Consider using NgRx for complex state management',
|
|
436
|
-
];
|
|
437
|
-
}
|
|
438
|
-
else if (framework === 'react') {
|
|
439
|
-
adapted.code = `// React Hook implementation
|
|
440
|
-
import { useEffect, useState, useRef } from 'react';
|
|
441
|
-
import { Subscription } from 'rxjs';
|
|
442
|
-
|
|
443
|
-
export function useRxJSPattern() {
|
|
444
|
-
const [data, setData] = useState(null);
|
|
445
|
-
const subscription = useRef<Subscription>();
|
|
446
|
-
|
|
447
|
-
useEffect(() => {
|
|
448
|
-
${pattern.code.split('\n').map(line => ' ' + line).join('\n')}
|
|
449
|
-
|
|
450
|
-
subscription.current = stream$.subscribe(setData);
|
|
451
|
-
|
|
452
|
-
return () => {
|
|
453
|
-
subscription.current?.unsubscribe();
|
|
454
|
-
};
|
|
455
|
-
}, []);
|
|
456
|
-
|
|
457
|
-
return data;
|
|
458
|
-
}`;
|
|
459
|
-
adapted.considerations = [
|
|
460
|
-
...pattern.considerations,
|
|
461
|
-
'Clean up subscriptions in useEffect return',
|
|
462
|
-
'Consider using a state management library',
|
|
463
|
-
'Be careful with closure stale values',
|
|
464
|
-
];
|
|
465
|
-
}
|
|
466
|
-
else if (framework === 'vue') {
|
|
467
|
-
adapted.code = `// Vue 3 Composition API implementation
|
|
468
|
-
import { ref, onBeforeUnmount } from 'vue';
|
|
469
|
-
import { Subject } from 'rxjs';
|
|
470
|
-
import { takeUntil } from 'rxjs/operators';
|
|
471
|
-
|
|
472
|
-
export function useRxJSPattern() {
|
|
473
|
-
const destroy$ = new Subject();
|
|
474
|
-
const data = ref(null);
|
|
475
|
-
|
|
476
|
-
${pattern.code}
|
|
477
|
-
|
|
478
|
-
stream$.pipe(
|
|
479
|
-
takeUntil(destroy$)
|
|
480
|
-
).subscribe(value => {
|
|
481
|
-
data.value = value;
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
onBeforeUnmount(() => {
|
|
485
|
-
destroy$.next();
|
|
486
|
-
destroy$.complete();
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
return { data };
|
|
490
|
-
}`;
|
|
491
|
-
adapted.considerations = [
|
|
492
|
-
...pattern.considerations,
|
|
493
|
-
'Use Composition API for better TypeScript support',
|
|
494
|
-
'Clean up in onBeforeUnmount',
|
|
495
|
-
'Consider Pinia for state management',
|
|
496
|
-
];
|
|
497
|
-
}
|
|
498
|
-
return adapted;
|
|
499
|
-
}
|
|
500
24
|
// Tool implementation
|
|
501
25
|
export const suggestPatternTool = {
|
|
502
26
|
definition: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"suggest-pattern.js","sourceRoot":"","sources":["../../src/tools/suggest-pattern.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"suggest-pattern.js","sourceRoot":"","sources":["../../src/tools/suggest-pattern.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -82,4 +82,44 @@ export interface MarbleDiagramResult {
|
|
|
82
82
|
value?: any;
|
|
83
83
|
}>;
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Timeline event in stream execution
|
|
87
|
+
*/
|
|
88
|
+
export interface TimelineEvent {
|
|
89
|
+
time: number;
|
|
90
|
+
type: 'next' | 'error' | 'complete';
|
|
91
|
+
value?: unknown;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Input data for Worker thread
|
|
95
|
+
*/
|
|
96
|
+
export interface WorkerInput {
|
|
97
|
+
code: string;
|
|
98
|
+
takeCount: number;
|
|
99
|
+
timeoutMs: number;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Result from Worker thread execution
|
|
103
|
+
*/
|
|
104
|
+
export interface WorkerResult {
|
|
105
|
+
values: unknown[];
|
|
106
|
+
errors: string[];
|
|
107
|
+
completed: boolean;
|
|
108
|
+
hasError: boolean;
|
|
109
|
+
timeline: TimelineEvent[];
|
|
110
|
+
executionTime: number;
|
|
111
|
+
memoryUsage: {
|
|
112
|
+
before: number;
|
|
113
|
+
after: number;
|
|
114
|
+
peak: number;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Message sent from Worker to main thread
|
|
119
|
+
*/
|
|
120
|
+
export interface WorkerMessage {
|
|
121
|
+
success: boolean;
|
|
122
|
+
result?: WorkerResult;
|
|
123
|
+
error?: string;
|
|
124
|
+
}
|
|
85
125
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shuji-bonji/rxjs-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "RxJS MCP Server - Execute, debug, and visualize RxJS streams for AI assistants",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
@@ -49,7 +49,8 @@
|
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@modelcontextprotocol/sdk": "^1.25.0",
|
|
51
51
|
"rxjs": "^7.8.1",
|
|
52
|
-
"zod": "^3.23.0"
|
|
52
|
+
"zod": "^3.23.0",
|
|
53
|
+
"zod-to-json-schema": "^3.25.0"
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
55
56
|
"@types/node": "^20.19.27",
|