vite-plugin-smart-prefetch 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/README.md ADDED
@@ -0,0 +1,605 @@
1
+ # @farmart/vite-plugin-smart-prefetch
2
+
3
+ **Smart prefetch plugin for Vite applications powered by BigQuery GA4 analytics**
4
+
5
+ Automatically prefetch route chunks based on real user navigation patterns from BigQuery GA4 export. Improve perceived performance by up to 80-90% for predicted route transitions.
6
+
7
+ ## Features
8
+
9
+ - 🤖 **Smart Learning** - Analyzes BigQuery GA4 event data to learn user navigation patterns
10
+ - 📊 **Data-Driven** - Prefetch decisions based on actual user behavior, not assumptions
11
+ - ⚡ **Multiple Strategies** - Auto, hover, visible, idle, or hybrid prefetching
12
+ - 🌐 **Network-Aware** - Respects data-saver mode and connection quality
13
+ - 💾 **Smart Caching** - Caches computed models with TTL for efficiency
14
+ - 🎯 **Framework Support** - React (Vue and Svelte coming soon)
15
+ - 🔧 **Zero Config** - Works out of the box with sensible defaults
16
+ - 📈 **Environment-Specific** - Different models for production, staging, development
17
+
18
+ ---
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ # Using pnpm (recommended for monorepos)
24
+ pnpm add @farmart/vite-plugin-smart-prefetch
25
+
26
+ # Using npm
27
+ npm install @farmart/vite-plugin-smart-prefetch
28
+
29
+ # Using yarn
30
+ yarn add @farmart/vite-plugin-smart-prefetch
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Quick Start
36
+
37
+ ### 1. Setup BigQuery for GA4 Export
38
+
39
+ ```bash
40
+ # 1. Enable BigQuery export from GA4 Console
41
+ # GA4 Admin > Data Export > BigQuery
42
+
43
+ # 2. Create Google Cloud service account
44
+ # https://console.cloud.google.com/iam-admin/serviceaccounts
45
+
46
+ # 3. Grant "BigQuery Data Viewer" and "BigQuery Job User" roles
47
+
48
+ # 4. Create and download JSON key
49
+ # Service Accounts > Keys > Add Key > Create New Key > JSON
50
+
51
+ # 5. Add to environment variables
52
+ ```
53
+
54
+ `.env`:
55
+ ```bash
56
+ VITE_GA_PROPERTY_ID=123456789
57
+ VITE_GA_CLIENT_EMAIL=prefetch@your-project.iam.gserviceaccount.com
58
+ VITE_GA_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
59
+ ```
60
+
61
+ ### 2. Configure Vite Plugin
62
+
63
+ `vite.config.mts`:
64
+ ```typescript
65
+ import { defineConfig } from 'vite';
66
+ import react from '@vitejs/plugin-react';
67
+ import { smartPrefetch } from '@farmart/vite-plugin-smart-prefetch';
68
+
69
+ export default defineConfig({
70
+ plugins: [
71
+ react(),
72
+ smartPrefetch({
73
+ framework: 'react',
74
+ strategy: 'hybrid',
75
+ analytics: {
76
+ provider: 'google-analytics',
77
+ credentials: {
78
+ propertyId: process.env.VITE_GA_PROPERTY_ID!,
79
+ clientEmail: process.env.VITE_GA_CLIENT_EMAIL!,
80
+ privateKey: process.env.VITE_GA_PRIVATE_KEY!,
81
+ },
82
+ dataRange: {
83
+ days: 30, // Analyze last 30 days
84
+ minSessions: 100, // Minimum sessions threshold
85
+ },
86
+ model: {
87
+ type: 'probability',
88
+ threshold: 0.3, // 30% probability threshold
89
+ maxPrefetch: 3, // Max 3 routes per page
90
+ },
91
+ environment: process.env.NODE_ENV || 'production',
92
+ },
93
+ manualRules: {
94
+ // Optional: Override ML predictions
95
+ '/checkout': ['/payment'],
96
+ },
97
+ cache: {
98
+ enabled: true,
99
+ ttl: 24 * 60 * 60 * 1000, // 24 hours
100
+ },
101
+ }),
102
+ ],
103
+ });
104
+ ```
105
+
106
+ ### 3. Add to Your App
107
+
108
+ `App.tsx`:
109
+ ```typescript
110
+ import { usePrefetch } from '@farmart/vite-plugin-smart-prefetch/react';
111
+
112
+ function App() {
113
+ // That's it! Plugin handles everything
114
+ usePrefetch();
115
+
116
+ return (
117
+ <Routes>
118
+ <Route path="/" element={<Home />} />
119
+ <Route path="/orders" element={<Orders />} />
120
+ <Route path="/dispatch-order" element={<DispatchOrder />} />
121
+ </Routes>
122
+ );
123
+ }
124
+ ```
125
+
126
+ ### 4. Build & Deploy
127
+
128
+ ```bash
129
+ npm run build
130
+ ```
131
+
132
+ The plugin will:
133
+ 1. ✅ Connect to Google Analytics
134
+ 2. ✅ Fetch navigation data
135
+ 3. ✅ Train probability model
136
+ 4. ✅ Generate `prefetch-config.json`
137
+ 5. ✅ Cache model for future builds
138
+
139
+ ---
140
+
141
+ ## Configuration
142
+
143
+ ### Plugin Options
144
+
145
+ ```typescript
146
+ interface PluginOptions {
147
+ /** Framework (default: 'react') */
148
+ framework?: 'react' | 'vue' | 'svelte';
149
+
150
+ /** Prefetch strategy (default: 'hybrid') */
151
+ strategy?: 'auto' | 'hover' | 'visible' | 'idle' | 'hybrid';
152
+
153
+ /** Google Analytics integration */
154
+ analytics?: AnalyticsConfig;
155
+
156
+ /** Manual prefetch rules */
157
+ manualRules?: {
158
+ [sourceRoute: string]: string[];
159
+ };
160
+
161
+ /** Cache configuration */
162
+ cache?: {
163
+ enabled?: boolean;
164
+ ttl?: number;
165
+ path?: string;
166
+ };
167
+
168
+ /** Advanced options */
169
+ advanced?: {
170
+ debug?: boolean;
171
+ excludeRoutes?: string[];
172
+ };
173
+ }
174
+ ```
175
+
176
+ ### Prefetch Strategies
177
+
178
+ | Strategy | Description | Use Case |
179
+ |----------|-------------|----------|
180
+ | `auto` | Prefetch immediately on route change | High-confidence predictions |
181
+ | `hover` | Prefetch when user hovers over link | User intent signals |
182
+ | `visible` | Prefetch when link becomes visible | Below-the-fold content |
183
+ | `idle` | Prefetch during browser idle time | Low priority routes |
184
+ | **`hybrid`** | **Smart combination based on probability** | **Recommended** |
185
+
186
+ #### Hybrid Strategy (Recommended)
187
+
188
+ - **High priority** (>70% probability): Prefetch immediately
189
+ - **Medium priority** (40-70%): Prefetch on idle
190
+ - **Low priority** (30-40%): Prefetch on hover/visible
191
+
192
+ ---
193
+
194
+ ## React Integration
195
+
196
+ ### usePrefetch Hook
197
+
198
+ ```typescript
199
+ import { usePrefetch } from '@farmart/vite-plugin-smart-prefetch/react';
200
+
201
+ function App() {
202
+ // Automatically prefetches routes based on navigation
203
+ usePrefetch();
204
+
205
+ return <Routes>...</Routes>;
206
+ }
207
+ ```
208
+
209
+ ### PrefetchLink Component
210
+
211
+ Enhanced `Link` component with manual control:
212
+
213
+ ```tsx
214
+ import { PrefetchLink } from '@farmart/vite-plugin-smart-prefetch/react';
215
+
216
+ // Prefetch on hover
217
+ <PrefetchLink to="/orders" prefetch="hover">
218
+ View Orders
219
+ </PrefetchLink>
220
+
221
+ // Prefetch when visible (great for lists)
222
+ <PrefetchLink to="/dispatch-order" prefetch="visible">
223
+ Create Dispatch
224
+ </PrefetchLink>
225
+
226
+ // Manual control (no automatic prefetch)
227
+ <PrefetchLink to="/settings" prefetch="manual">
228
+ Settings
229
+ </PrefetchLink>
230
+ ```
231
+
232
+ ### Manual Prefetch Control
233
+
234
+ ```typescript
235
+ import { getPrefetchManager } from '@farmart/vite-plugin-smart-prefetch/react';
236
+
237
+ function MyComponent() {
238
+ const handleMouseEnter = () => {
239
+ const manager = getPrefetchManager();
240
+ manager?.prefetchRoute('/orders');
241
+ };
242
+
243
+ return (
244
+ <button onMouseEnter={handleMouseEnter}>
245
+ View Orders
246
+ </button>
247
+ );
248
+ }
249
+ ```
250
+
251
+ ---
252
+
253
+ ## How It Works
254
+
255
+ ### Build Time
256
+
257
+ ```
258
+ 1. Connect to Google Analytics
259
+ ├── Authenticate with service account
260
+ └── Fetch last 30 days of navigation data
261
+
262
+ 2. Train Model
263
+ ├── Calculate transition probabilities
264
+ │ Example: P(/dispatch-order | /orders) = 0.58
265
+ ├── Apply threshold filter (>30%)
266
+ └── Select top 3 predictions per route
267
+
268
+ 3. Generate Configuration
269
+ ├── Map routes to Vite chunks
270
+ │ /dispatch-order → assets/dispatch-order-abc123.js
271
+ └── Emit prefetch-config.json
272
+
273
+ 4. Cache Model
274
+ ├── Save to node_modules/.cache/smart-prefetch/
275
+ └── TTL: 24 hours (configurable)
276
+ ```
277
+
278
+ ### Runtime
279
+
280
+ ```
281
+ 1. App Loads
282
+ ├── usePrefetch() initializes
283
+ └── Fetch /prefetch-config.json
284
+
285
+ 2. User on /orders page
286
+ ├── Check network conditions (Data Saver, 2G, etc.)
287
+ ├── Read predictions: [/dispatch-order (58%), /orders/:id (42%)]
288
+ └── Apply strategy:
289
+ - High priority: Prefetch immediately
290
+ - Medium: Prefetch on idle
291
+ - Low: Wait for hover/visible
292
+
293
+ 3. Inject <link rel="prefetch">
294
+ <link rel="prefetch" href="/assets/dispatch-order-abc123.js">
295
+
296
+ 4. User clicks "Dispatch Order"
297
+ ├── Chunk already in browser cache!
298
+ └── Load time: ~10ms instead of ~300ms
299
+ ```
300
+
301
+ ---
302
+
303
+ ## Performance Impact
304
+
305
+ ### Before vs After
306
+
307
+ | Metric | Without Prefetch | With Prefetch | Improvement |
308
+ |--------|------------------|---------------|-------------|
309
+ | Route transition | 250-500ms | 10-50ms | **80-90% faster** |
310
+ | Cache hit rate | 0% | 60-80% | **New capability** |
311
+ | Time to Interactive | Baseline | -15-20% | **Faster** |
312
+
313
+ ### Real-World Example
314
+
315
+ ```
316
+ Example: /orders → /dispatch-order (58% probability)
317
+
318
+ Without prefetch:
319
+ 1. User clicks link
320
+ 2. Download dispatch-order-abc123.js (300ms)
321
+ 3. Parse and execute (50ms)
322
+ Total: 350ms
323
+
324
+ With prefetch:
325
+ 1. User lands on /orders
326
+ 2. Plugin prefetches dispatch-order-abc123.js in background
327
+ 3. User clicks link
328
+ 4. Load from cache (5ms)
329
+ 5. Parse and execute (50ms)
330
+ Total: 55ms (84% faster!)
331
+ ```
332
+
333
+ ---
334
+
335
+ ## Network-Aware Prefetching
336
+
337
+ The plugin automatically detects and respects:
338
+
339
+ - ✅ **Data Saver mode** - No prefetch if enabled
340
+ - ✅ **Slow connections** - No prefetch on 2G/slow-2G
341
+ - ✅ **Metered connections** - Conservative prefetch on cellular
342
+ - ✅ **Connection quality** - Uses Network Information API
343
+
344
+ ```typescript
345
+ // Automatic detection (no configuration needed)
346
+ if (navigator.connection.saveData) {
347
+ // Skip prefetch
348
+ }
349
+
350
+ if (connection.effectiveType === '2g') {
351
+ // Skip prefetch
352
+ }
353
+ ```
354
+
355
+ ---
356
+
357
+ ## Cache Management
358
+
359
+ ### Cache Location
360
+
361
+ ```
362
+ node_modules/.cache/smart-prefetch/
363
+ ├── model-production.json # Production model
364
+ ├── model-staging.json # Staging model
365
+ └── metadata.json # Cache metadata
366
+ ```
367
+
368
+ ### Invalidate Cache
369
+
370
+ ```bash
371
+ # Invalidate all cache
372
+ rm -rf node_modules/.cache/smart-prefetch
373
+
374
+ # Or programmatically
375
+ const cacheManager = new CacheManager();
376
+ await cacheManager.invalidate();
377
+ ```
378
+
379
+ ### Cache Stats
380
+
381
+ ```typescript
382
+ const stats = cacheManager.getStats();
383
+ // {
384
+ // enabled: true,
385
+ // cacheDir: './node_modules/.cache/smart-prefetch',
386
+ // ttl: 86400000,
387
+ // cachedEnvironments: ['production', 'staging'],
388
+ // totalSize: 45678
389
+ // }
390
+ ```
391
+
392
+ ---
393
+
394
+ ## Manual Rules
395
+
396
+ Override ML predictions with manual rules:
397
+
398
+ ```typescript
399
+ smartPrefetch({
400
+ manualRules: {
401
+ // Always prefetch payment on checkout
402
+ '/checkout': ['/payment'],
403
+
404
+ // Multiple targets
405
+ '/': ['/products', '/orders', '/dashboard'],
406
+
407
+ // Dynamic routes (use :id notation)
408
+ '/orders/:id': ['/dispatch-order/:id'],
409
+ },
410
+ })
411
+ ```
412
+
413
+ Manual rules:
414
+ - ✅ Take precedence over ML predictions
415
+ - ✅ Always have `priority: 'high'`
416
+ - ✅ Always have `probability: 1.0`
417
+ - ✅ Merged with analytics data
418
+
419
+ ---
420
+
421
+ ## Debugging
422
+
423
+ Enable debug mode to see detailed logs:
424
+
425
+ ```typescript
426
+ smartPrefetch({
427
+ advanced: {
428
+ debug: true,
429
+ },
430
+ })
431
+ ```
432
+
433
+ ### Build-Time Logs
434
+
435
+ ```
436
+ 🚀 Smart Prefetch Plugin Initialized
437
+ Framework: react
438
+ Strategy: hybrid
439
+ Analytics: enabled
440
+
441
+ 📊 Fetching analytics data...
442
+ Date range: Last 30 days
443
+ Min sessions threshold: 100
444
+
445
+ ✅ Fetched 87 navigation patterns
446
+
447
+ 🤖 Training prefetch model...
448
+ Model type: probability
449
+ Threshold: 30%
450
+ Max prefetch per route: 3
451
+
452
+ ✅ Model trained successfully
453
+ Routes with predictions: 42
454
+
455
+ 📦 Generating prefetch configuration...
456
+ Manifest entries: 156
457
+ Mapped chunks: 89
458
+ ```
459
+
460
+ ### Runtime Logs
461
+
462
+ ```
463
+ 🚀 Prefetch Manager Initialized
464
+ Strategy: hybrid
465
+ Routes: 42
466
+ Environment: production
467
+
468
+ 📦 Prefetching for route: /orders
469
+ Targets: 2
470
+ ✅ Prefetched: /dispatch-order (58%, high)
471
+ ✅ Prefetched: /orders/:id (42%, medium)
472
+ ```
473
+
474
+ ---
475
+
476
+ ## Troubleshooting
477
+
478
+ ### Issue: "Failed to load prefetch config"
479
+
480
+ **Solution:** Ensure `/prefetch-config.json` is in your build output (`dist/`).
481
+
482
+ ```bash
483
+ # Check if file exists
484
+ ls dist/prefetch-config.json
485
+ ```
486
+
487
+ ### Issue: "Google Analytics connection test failed"
488
+
489
+ **Solutions:**
490
+ 1. Verify service account has "Viewer" access to GA4 property
491
+ 2. Check credentials in `.env` file
492
+ 3. Ensure private key has correct newlines (`\n`)
493
+
494
+ ```bash
495
+ # Test credentials
496
+ echo $VITE_GA_PRIVATE_KEY | grep "BEGIN PRIVATE KEY"
497
+ ```
498
+
499
+ ### Issue: "No navigation data found"
500
+
501
+ **Solutions:**
502
+ 1. Ensure GA4 property has at least 30 days of data
503
+ 2. Lower `minSessions` threshold
504
+ 3. Check GA4 property ID is correct
505
+
506
+ ### Issue: "No chunk found for route"
507
+
508
+ **Solution:** Adjust route normalization or use manual rules:
509
+
510
+ ```typescript
511
+ smartPrefetch({
512
+ manualRules: {
513
+ '/my-route': ['/target-route'],
514
+ },
515
+ advanced: {
516
+ routeNormalization: (path) => {
517
+ // Custom normalization logic
518
+ return path.replace(/\/[0-9]+/g, '/:id');
519
+ },
520
+ },
521
+ })
522
+ ```
523
+
524
+ ---
525
+
526
+ ## Best Practices
527
+
528
+ ### 1. Use Hybrid Strategy
529
+
530
+ ```typescript
531
+ strategy: 'hybrid' // ✅ Recommended
532
+ ```
533
+
534
+ Automatically prioritizes prefetch based on prediction confidence.
535
+
536
+ ### 2. Set Appropriate Thresholds
537
+
538
+ ```typescript
539
+ model: {
540
+ threshold: 0.3, // 30% - Good balance
541
+ maxPrefetch: 3, // Limit bandwidth usage
542
+ }
543
+ ```
544
+
545
+ - **Too low** (<20%): Wastes bandwidth
546
+ - **Too high** (>50%): Misses opportunities
547
+
548
+ ### 3. Use Manual Rules for Critical Paths
549
+
550
+ ```typescript
551
+ manualRules: {
552
+ '/checkout': ['/payment'], // Always prefetch payment
553
+ }
554
+ ```
555
+
556
+ ### 4. Monitor Prefetch Performance
557
+
558
+ Enable dashboard to visualize predictions:
559
+
560
+ ```typescript
561
+ analytics: {
562
+ dashboard: true, // Generates prefetch-report.html
563
+ }
564
+ ```
565
+
566
+ Access at: `https://your-app.com/prefetch-report.html`
567
+
568
+ ### 5. Environment-Specific Models
569
+
570
+ ```typescript
571
+ // Production
572
+ environment: 'production'
573
+
574
+ // Staging
575
+ environment: 'staging'
576
+ ```
577
+
578
+ Keeps models separate for different user behaviors.
579
+
580
+ ---
581
+
582
+ ## API Reference
583
+
584
+ See [RFC-001-SMART-PREFETCH-PLUGIN.md](../../RFC-001-SMART-PREFETCH-PLUGIN.md) for detailed API documentation.
585
+
586
+ ---
587
+
588
+ ## Contributing
589
+
590
+ This is an internal FarmArt Engineering package. For issues or feature requests, please contact the engineering team.
591
+
592
+ ---
593
+
594
+ ## License
595
+
596
+ MIT © FarmArt Engineering
597
+
598
+ ---
599
+
600
+ ## Support
601
+
602
+ For questions or support:
603
+ - Internal Slack: `#engineering`
604
+ - Documentation: See RFC-001 in project root
605
+ - Issues: Create ticket in project management tool