@fluxiapi/react 0.3.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Aswin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,231 @@
1
+ # @fluxiapi/react
2
+
3
+ Drop-in React DevTools for [FluxAPI](https://github.com/aswinsasi/fluxapi). Live API health monitoring with TanStack Query & SWR integration.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @fluxiapi/react
9
+ ```
10
+
11
+ ### Requirements
12
+
13
+ - **React >= 17** (hooks required)
14
+ - **@fluxiapi/scan** — installed automatically as a dependency
15
+
16
+ ### Optional Peer Dependencies
17
+
18
+ ```bash
19
+ # For TanStack Query integration
20
+ npm install @tanstack/react-query
21
+
22
+ # For SWR integration
23
+ npm install swr
24
+ ```
25
+
26
+ ---
27
+
28
+ ## Quick Start
29
+
30
+ ### 1. Add `<FluxDevTools />`
31
+
32
+ ```jsx
33
+ import { FluxDevTools } from '@fluxiapi/react';
34
+
35
+ function App() {
36
+ return (
37
+ <>
38
+ <YourApp />
39
+ <FluxDevTools />
40
+ </>
41
+ );
42
+ }
43
+ ```
44
+
45
+ That's it. A floating badge appears in the corner showing your live API health score. Click to expand the full panel.
46
+
47
+ - Only renders in `development` mode
48
+ - Auto-starts scanning on mount
49
+ - Toggle with `Ctrl+Shift+F`
50
+
51
+ ### 2. With TanStack Query (optional)
52
+
53
+ ```jsx
54
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
55
+ import { FluxDevTools, wrapQueryClient } from '@fluxiapi/react';
56
+
57
+ const queryClient = wrapQueryClient(new QueryClient({
58
+ defaultOptions: { queries: { staleTime: 30_000 } },
59
+ }));
60
+
61
+ function App() {
62
+ return (
63
+ <QueryClientProvider client={queryClient}>
64
+ <YourApp />
65
+ <FluxDevTools />
66
+ </QueryClientProvider>
67
+ );
68
+ }
69
+ ```
70
+
71
+ `wrapQueryClient` instruments the QueryClient to capture query keys, staleTime, gcTime, refetch patterns for richer analysis.
72
+
73
+ ### 3. With SWR (optional)
74
+
75
+ ```jsx
76
+ import { SWRConfig } from 'swr';
77
+ import { FluxDevTools, fluxSWRMiddleware } from '@fluxiapi/react';
78
+
79
+ function App() {
80
+ return (
81
+ <SWRConfig value={{ use: [fluxSWRMiddleware] }}>
82
+ <YourApp />
83
+ <FluxDevTools />
84
+ </SWRConfig>
85
+ );
86
+ }
87
+ ```
88
+
89
+ ---
90
+
91
+ ## `<FluxDevTools />` Props
92
+
93
+ | Prop | Type | Default | Description |
94
+ |------|------|---------|-------------|
95
+ | `position` | `'bottom-right'` \| `'bottom-left'` \| `'top-right'` \| `'top-left'` | `'bottom-right'` | Badge position |
96
+ | `network` | `string` | `'wifi'` | Network profile for scoring |
97
+ | `analysisInterval` | `number` | `3000` | Re-analysis interval (ms) |
98
+ | `autoStart` | `boolean` | `true` | Auto-start scanning on mount |
99
+ | `defaultOpen` | `boolean` | `false` | Start with panel expanded |
100
+ | `verbose` | `boolean` | `false` | Console debug logging |
101
+ | `forceShow` | `boolean` | `false` | Show in production mode |
102
+ | `shortcut` | `string \| null` | `'ctrl+shift+f'` | Keyboard toggle shortcut |
103
+
104
+ ---
105
+
106
+ ## Hooks
107
+
108
+ Use hooks to access scan data in your own components:
109
+
110
+ ```jsx
111
+ import {
112
+ useFluxScore,
113
+ useFluxViolations,
114
+ useFluxRequests,
115
+ useFluxReport,
116
+ useFluxScanning,
117
+ } from '@fluxiapi/react';
118
+
119
+ function MyStatusBar() {
120
+ const { overall, grade, color } = useFluxScore();
121
+ const violations = useFluxViolations({ severity: 'critical' });
122
+ const { scanning, elapsed, start, stop } = useFluxScanning();
123
+
124
+ return (
125
+ <div style={{ color }}>
126
+ Score: {overall} ({grade}) · {violations.length} critical issues
127
+ {scanning ? <span>Scanning... {elapsed}s</span> : null}
128
+ </div>
129
+ );
130
+ }
131
+ ```
132
+
133
+ ### Available Hooks
134
+
135
+ | Hook | Returns | Description |
136
+ |------|---------|-------------|
137
+ | `useFluxScore()` | `{ overall, grade, efficiency, caching, patterns, color }` | Current API health score |
138
+ | `useFluxViolations(filter?)` | `RuleViolation[]` | Active violations, filterable by severity/category/ruleId |
139
+ | `useFluxRequests(filter?)` | `FluxRequestRecord[]` | Captured requests, filterable by type/method/duration |
140
+ | `useFluxReport()` | `FluxReport \| null` | Full analysis report |
141
+ | `useFluxScanning()` | `{ scanning, elapsed, requestCount, start, stop, reset }` | Scan lifecycle control |
142
+
143
+ ---
144
+
145
+ ## Advanced: Custom Provider
146
+
147
+ For shared state across components without `<FluxDevTools />`:
148
+
149
+ ```jsx
150
+ import { FluxProvider, useFluxScore } from '@fluxiapi/react';
151
+
152
+ function App() {
153
+ return (
154
+ <FluxProvider network="jio-4g" analysisInterval={5000}>
155
+ <Dashboard />
156
+ </FluxProvider>
157
+ );
158
+ }
159
+
160
+ function Dashboard() {
161
+ const { overall } = useFluxScore();
162
+ return <h1>API Score: {overall}</h1>;
163
+ }
164
+ ```
165
+
166
+ ---
167
+
168
+ ## Advanced: Scanner Bridge
169
+
170
+ For full control over the scan engine:
171
+
172
+ ```jsx
173
+ import { ScannerBridge } from '@fluxiapi/react';
174
+
175
+ const bridge = new ScannerBridge({
176
+ network: 'jio-4g',
177
+ analysisInterval: 5000,
178
+ verbose: true,
179
+ });
180
+
181
+ // Subscribe to state changes
182
+ bridge.subscribe((state) => {
183
+ console.log('Score:', state.score, 'Violations:', state.violations.length);
184
+ });
185
+
186
+ // Start/stop
187
+ await bridge.start();
188
+ const report = bridge.stop();
189
+
190
+ // Pass to FluxDevTools
191
+ <FluxDevTools bridge={bridge} />
192
+ ```
193
+
194
+ ---
195
+
196
+ ## What the DevTools Panel Shows
197
+
198
+ ### Overview Tab
199
+ - API health score gauge (0-100)
200
+ - Category breakdown (Efficiency / Caching / Patterns)
201
+ - Stats cards (critical, warnings, API calls)
202
+ - Impact banner (time saved, requests eliminated)
203
+ - Top 3 issues
204
+
205
+ ### Violations Tab
206
+ - All violations with severity dots
207
+ - Rule ID badges (E1, C1, P2, etc.)
208
+ - Impact pills (time, requests, bandwidth)
209
+ - Expandable details with endpoints and fix code
210
+
211
+ ### Requests Tab
212
+ - Live request feed (newest first)
213
+ - Method badges (GET/POST/PUT/DELETE)
214
+ - Status codes with color coding
215
+ - Duration with performance coloring
216
+
217
+ ---
218
+
219
+ ## 13 Rules Detected
220
+
221
+ | Category | Rules |
222
+ |----------|-------|
223
+ | ⚡ Efficiency | E1 Waterfalls, E2 Duplicates, E3 N+1, E4 Over-fetching, E5 Batchable |
224
+ | 💾 Caching | C1 No Cache, C2 Under-Caching, C3 Over-Caching, C4 Missing Revalidation |
225
+ | 🔄 Patterns | P1 Missing Prefetch, P2 Unnecessary Polling, P3 No Error Recovery, P4 Uncompressed |
226
+
227
+ ---
228
+
229
+ ## License
230
+
231
+ MIT
@@ -0,0 +1,266 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { FluxRequestRecord, FluxReport, RuleViolation } from '@fluxiapi/scan';
3
+ import { ReactNode } from 'react';
4
+
5
+ interface FluxState {
6
+ /** Whether the scanner is actively capturing */
7
+ scanning: boolean;
8
+ /** Captured requests so far */
9
+ requests: FluxRequestRecord[];
10
+ /** Latest analysis report (null before first analysis) */
11
+ report: FluxReport | null;
12
+ /** Current API health score 0-100 */
13
+ score: number;
14
+ /** Active violations */
15
+ violations: RuleViolation[];
16
+ /** Scan start time */
17
+ startTime: number;
18
+ /** Elapsed seconds */
19
+ elapsed: number;
20
+ /** Selected network profile */
21
+ network: string;
22
+ /** Framework info if detected */
23
+ framework: string | null;
24
+ }
25
+ type FluxStateListener = (state: FluxState) => void;
26
+ interface ScannerBridgeConfig {
27
+ /** Network profile for scoring */
28
+ network?: string;
29
+ /** How often to re-analyze (ms, default: 3000) */
30
+ analysisInterval?: number;
31
+ /** Auto-start scanning on mount */
32
+ autoStart?: boolean;
33
+ /** Verbose console logging */
34
+ verbose?: boolean;
35
+ }
36
+ declare class ScannerBridge {
37
+ private _state;
38
+ private _listeners;
39
+ private _analyzeTimer;
40
+ private _tickTimer;
41
+ private _config;
42
+ private _scanner;
43
+ private _analyzer;
44
+ constructor(config?: ScannerBridgeConfig);
45
+ get state(): FluxState;
46
+ subscribe(listener: FluxStateListener): () => void;
47
+ private _emit;
48
+ private _update;
49
+ start(): Promise<void>;
50
+ stop(): FluxReport | null;
51
+ reset(): void;
52
+ setNetwork(network: string): void;
53
+ private _runAnalysis;
54
+ /**
55
+ * Capture a TanStack Query event. Called by FluxQueryClient wrapper.
56
+ */
57
+ captureQueryEvent(event: {
58
+ type: 'query-added' | 'query-updated' | 'query-removed';
59
+ queryKey: unknown[];
60
+ state?: {
61
+ status: string;
62
+ fetchStatus: string;
63
+ dataUpdatedAt: number;
64
+ };
65
+ options?: {
66
+ staleTime?: number;
67
+ gcTime?: number;
68
+ refetchInterval?: number | false;
69
+ enabled?: boolean;
70
+ retry?: number | boolean;
71
+ };
72
+ }): void;
73
+ /**
74
+ * Capture a SWR event.
75
+ */
76
+ captureSWREvent(event: {
77
+ type: 'swr-request' | 'swr-success' | 'swr-error';
78
+ key: string;
79
+ config?: {
80
+ refreshInterval?: number;
81
+ dedupingInterval?: number;
82
+ revalidateOnFocus?: boolean;
83
+ errorRetryCount?: number;
84
+ };
85
+ }): void;
86
+ destroy(): void;
87
+ }
88
+ declare function getGlobalBridge(config?: ScannerBridgeConfig): ScannerBridge;
89
+ declare function resetGlobalBridge(): void;
90
+
91
+ interface FluxDevToolsProps {
92
+ /**
93
+ * Position of the floating badge.
94
+ * @default 'bottom-right'
95
+ */
96
+ position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
97
+ /**
98
+ * Network profile for scoring.
99
+ * @default 'wifi'
100
+ */
101
+ network?: string;
102
+ /**
103
+ * Re-analysis interval in ms.
104
+ * @default 3000
105
+ */
106
+ analysisInterval?: number;
107
+ /**
108
+ * Auto-start scanning when component mounts.
109
+ * @default true
110
+ */
111
+ autoStart?: boolean;
112
+ /**
113
+ * Start with panel expanded.
114
+ * @default false
115
+ */
116
+ defaultOpen?: boolean;
117
+ /**
118
+ * Console logging for debug.
119
+ * @default false
120
+ */
121
+ verbose?: boolean;
122
+ /**
123
+ * Custom scanner bridge (for shared state with other components).
124
+ */
125
+ bridge?: ScannerBridge;
126
+ /**
127
+ * Force show even in production. By default, only renders in development.
128
+ * @default false
129
+ */
130
+ forceShow?: boolean;
131
+ /**
132
+ * Keyboard shortcut to toggle panel. Set to null to disable.
133
+ * @default 'ctrl+shift+f'
134
+ */
135
+ shortcut?: string | null;
136
+ }
137
+ declare function FluxDevTools({ position, network, analysisInterval, autoStart, defaultOpen, verbose, bridge, forceShow, shortcut, }: FluxDevToolsProps): react_jsx_runtime.JSX.Element | null;
138
+
139
+ interface FluxContextValue {
140
+ bridge: ScannerBridge;
141
+ state: FluxState;
142
+ }
143
+ interface FluxProviderProps {
144
+ children: ReactNode;
145
+ /** Network profile for scoring */
146
+ network?: string;
147
+ /** Re-analysis interval in ms (default: 3000) */
148
+ analysisInterval?: number;
149
+ /** Auto-start scanning on mount (default: true) */
150
+ autoStart?: boolean;
151
+ /** Console logging */
152
+ verbose?: boolean;
153
+ /** Custom scanner bridge instance */
154
+ bridge?: ScannerBridge;
155
+ }
156
+ declare function FluxProvider({ children, network, analysisInterval, autoStart, verbose, bridge: customBridge, }: FluxProviderProps): react_jsx_runtime.JSX.Element;
157
+ declare function useFlux(): FluxContextValue;
158
+ declare function useFluxBridge(): ScannerBridge;
159
+ declare function useFluxState(): FluxState;
160
+
161
+ interface ScoreInfo {
162
+ overall: number;
163
+ grade: string;
164
+ efficiency: number;
165
+ caching: number;
166
+ patterns: number;
167
+ color: string;
168
+ }
169
+ declare function useFluxScore(): ScoreInfo;
170
+ interface ViolationFilter {
171
+ severity?: 'critical' | 'warning' | 'info';
172
+ category?: 'efficiency' | 'caching' | 'patterns';
173
+ ruleId?: string;
174
+ }
175
+ declare function useFluxViolations(filter?: ViolationFilter): RuleViolation[];
176
+ interface RequestFilter {
177
+ type?: 'api-rest' | 'api-graphql' | 'static' | 'document';
178
+ method?: string;
179
+ minDuration?: number;
180
+ }
181
+ declare function useFluxRequests(filter?: RequestFilter): FluxRequestRecord[];
182
+ declare function useFluxReport(): FluxReport | null;
183
+ declare function useFluxScanning(): {
184
+ scanning: boolean;
185
+ elapsed: number;
186
+ requestCount: number;
187
+ start: () => void;
188
+ stop: () => void;
189
+ reset: () => void;
190
+ };
191
+
192
+ /**
193
+ * Wraps a TanStack QueryClient to instrument all queries for FluxAPI monitoring.
194
+ *
195
+ * Usage:
196
+ * ```tsx
197
+ * import { QueryClient } from '@tanstack/react-query';
198
+ * import { wrapQueryClient } from '@fluxiapi/react';
199
+ *
200
+ * const queryClient = wrapQueryClient(new QueryClient({
201
+ * defaultOptions: { queries: { staleTime: 30_000 } },
202
+ * }));
203
+ * ```
204
+ */
205
+ declare function wrapQueryClient<T extends object>(queryClient: T, bridge?: ScannerBridge): T;
206
+ interface QueryMetrics {
207
+ /** Total unique query keys seen */
208
+ uniqueQueries: number;
209
+ /** Queries without staleTime configured */
210
+ queriesWithoutStaleTime: number;
211
+ /** Queries with refetchInterval (polling) */
212
+ pollingQueries: number;
213
+ /** Queries with retry disabled */
214
+ noRetryQueries: number;
215
+ /** Average staleTime across queries */
216
+ avgStaleTime: number;
217
+ }
218
+ /**
219
+ * Extracts TanStack Query-specific metrics from the current scan report.
220
+ * Call this after getting a report to see query-level insights.
221
+ */
222
+ declare function extractQueryMetrics(queryClient: any): QueryMetrics;
223
+
224
+ type SWRKey = string | unknown[] | null | undefined | (() => string | unknown[] | null);
225
+ interface SWRConfig {
226
+ refreshInterval?: number;
227
+ dedupingInterval?: number;
228
+ revalidateOnFocus?: boolean;
229
+ revalidateOnReconnect?: boolean;
230
+ errorRetryCount?: number;
231
+ [key: string]: unknown;
232
+ }
233
+ type SWRHook = (useSWRNext: any) => (key: SWRKey, fetcher: any, config: SWRConfig) => any;
234
+ /**
235
+ * SWR middleware that instruments all SWR hooks for FluxAPI monitoring.
236
+ *
237
+ * Usage:
238
+ * ```tsx
239
+ * import { SWRConfig } from 'swr';
240
+ * import { fluxSWRMiddleware } from '@fluxiapi/react';
241
+ *
242
+ * function App() {
243
+ * return (
244
+ * <SWRConfig value={{ use: [fluxSWRMiddleware] }}>
245
+ * <MyApp />
246
+ * </SWRConfig>
247
+ * );
248
+ * }
249
+ * ```
250
+ */
251
+ declare function createFluxSWRMiddleware(bridge?: ScannerBridge): SWRHook;
252
+ declare const fluxSWRMiddleware: SWRHook;
253
+ interface SWRMetrics {
254
+ /** Number of unique SWR keys */
255
+ totalKeys: number;
256
+ /** Keys with refreshInterval (polling) */
257
+ pollingKeys: number;
258
+ /** Keys with revalidateOnFocus enabled */
259
+ revalidateOnFocusKeys: number;
260
+ /** Keys with errorRetryCount = 0 */
261
+ noRetryKeys: number;
262
+ /** Average deduping interval */
263
+ avgDedupingInterval: number;
264
+ }
265
+
266
+ export { FluxDevTools, type FluxDevToolsProps, FluxProvider, type FluxProviderProps, type FluxState, type FluxStateListener, type QueryMetrics, type RequestFilter, type SWRMetrics, ScannerBridge, type ScannerBridgeConfig, type ScoreInfo, type ViolationFilter, createFluxSWRMiddleware, extractQueryMetrics, fluxSWRMiddleware, getGlobalBridge, resetGlobalBridge, useFlux, useFluxBridge, useFluxReport, useFluxRequests, useFluxScanning, useFluxScore, useFluxState, useFluxViolations, wrapQueryClient };