@donkeylabs/server 2.0.19 → 2.0.21

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.
@@ -0,0 +1,656 @@
1
+ # Development Experience Guide
2
+
3
+ This guide covers the development workflow, hot reload system, and tooling for DonkeyLabs framework.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Hot Reload System](#hot-reload-system)
8
+ - [Dev Server Modes](#dev-server-modes)
9
+ - [File Watching](#file-watching)
10
+ - [Type Generation](#type-generation)
11
+ - [Debugging Utilities](#debugging-utilities)
12
+ - [Performance Optimization](#performance-optimization)
13
+ - [VS Code Integration](#vs-code-integration)
14
+
15
+ ---
16
+
17
+ ## Hot Reload System
18
+
19
+ The framework provides sophisticated hot reload capabilities that dramatically speed up development.
20
+
21
+ ### What Gets Hot Reloaded
22
+
23
+ | Component | Hot Reload Support | Trigger | Notes |
24
+ |-----------|-------------------|---------|-------|
25
+ | Route handlers | ✅ Yes | File save in routes/ | Instant, no server restart |
26
+ | Route schemas | ✅ Yes | File save | Requires type regeneration |
27
+ | Plugin service methods | ⚠️ Partial | File save | Type regen needed for full typing |
28
+ | Plugin structure changes | ❌ No | N/A | Requires full restart |
29
+ | Middleware | ✅ Yes | File save | Instant |
30
+ | Database migrations | ⚠️ Partial | Migration added | Auto-runs migration + type gen |
31
+ | Generated types | ✅ Auto | Source changes | Triggered by file watcher |
32
+
33
+ ### How Hot Reload Works
34
+
35
+ **In-Process Mode** (`bun --bun run dev`):
36
+
37
+ 1. Vite's file watcher detects changes in `src/server/`
38
+ 2. Route files are identified by glob pattern `**/routes/**/*.ts`
39
+ 3. Changed module is invalidated in Vite's cache
40
+ 4. Module is re-imported with cache-busting query param
41
+ 5. `appServer.reloadRouter(prefix, newRouter)` updates the route map
42
+ 6. Changes are immediately available without restart
43
+
44
+ ```typescript
45
+ // From packages/adapter-sveltekit/src/vite.ts
46
+ async function hotReloadRoute(filepath: string) {
47
+ // 1. Invalidate Vite module cache
48
+ const mod = viteServer.moduleGraph.getModuleById(filepath);
49
+ if (mod) viteServer.moduleGraph.invalidateModule(mod);
50
+
51
+ // 2. Re-import with timestamp
52
+ const freshModule = await viteServer.ssrLoadModule(`${filepath}?t=${Date.now()}`);
53
+
54
+ // 3. Extract router from exports
55
+ let newRouter = freshModule.router || freshModule.default;
56
+
57
+ // 4. Hot swap in app server
58
+ if (newRouter && prefix) {
59
+ appServer.reloadRouter(prefix, newRouter);
60
+ console.log("[donkeylabs-dev] Route hot reload complete:", prefix);
61
+ }
62
+ }
63
+ ```
64
+
65
+ ### Hot Reload Limitations
66
+
67
+ **Plugin structure changes** (adding new methods, changing signatures):
68
+ - Changes require full type regeneration
69
+ - May need server restart if plugin initialization changed
70
+ - Run `bun run gen:types` after structure changes
71
+
72
+ **Database schema changes**:
73
+ - Migrations are detected and auto-run
74
+ - Schema types are regenerated
75
+ - But plugin may need restart to see new table types
76
+
77
+ **Configuration changes**:
78
+ - `donkeylabs.config.ts` changes require restart
79
+ - Environment variable changes require restart
80
+
81
+ ---
82
+
83
+ ## Dev Server Modes
84
+
85
+ The framework supports two development server modes:
86
+
87
+ ### In-Process Mode (Recommended)
88
+
89
+ ```bash
90
+ bun --bun run dev
91
+ ```
92
+
93
+ **Architecture:**
94
+ ```
95
+ ┌─────────────────────────────────────────────┐
96
+ │ Vite Dev Server │
97
+ │ ┌──────────────────────────────────────┐ │
98
+ │ │ @donkeylabs/server (in-process) │ │
99
+ │ │ - Runs in same Bun process │ │
100
+ │ │ - Shares event loop with Vite │ │
101
+ │ │ - Direct middleware integration │ │
102
+ │ └──────────────────────────────────────┘ │
103
+ │ ┌──────────────────────────────────────┐ │
104
+ │ │ SvelteKit (Vite plugin) │ │
105
+ │ └──────────────────────────────────────┘ │
106
+ └─────────────────────────────────────────────┘
107
+ ↓ Single port (e.g., 5173)
108
+ ```
109
+
110
+ **Advantages:**
111
+ - 🚀 **Fastest performance**: No inter-process communication
112
+ - 🔄 **Full hot reload**: All features work
113
+ - 📦 **Single port**: No CORS, no proxy issues
114
+ - 🧠 **Shared memory**: SSR can directly call server methods
115
+ - ⚡ **Instant startup**: No process spawning
116
+
117
+ **How it works:**
118
+ 1. Vite loads the `@donkeylabs/adapter-sveltekit` plugin
119
+ 2. Plugin detects Bun runtime (`typeof globalThis.Bun !== "undefined"`)
120
+ 3. Server entry file is imported directly (not spawned)
121
+ 4. Server initializes but doesn't start HTTP server
122
+ 5. Vite middleware stack gets custom handler for API routes
123
+ 6. API requests are handled in-process via middleware
124
+
125
+ ### Subprocess Mode (Fallback)
126
+
127
+ ```bash
128
+ bun run dev
129
+ ```
130
+
131
+ **Architecture:**
132
+ ```
133
+ ┌─────────────────────────────────────────────┐
134
+ │ Vite Dev Server │
135
+ │ ┌──────────────────────────────────────┐ │
136
+ │ │ SvelteKit (Vite plugin) │ │
137
+ │ └──────────────────────────────────────┘ │
138
+ │ ┌──────────────────────────────────────┐ │
139
+ │ │ Proxy Middleware (port 5173) │ │
140
+ │ │ - Intercepts /api/* requests │ │
141
+ │ │ - Forwards to backend process │ │
142
+ │ └──────────────────────────────────────┘ │
143
+ └─────────────────────────────────────────────┘
144
+ ↓ HTTP Proxy
145
+ ┌─────────────────────────────────────────────┐
146
+ │ Backend Server (port 3001) │
147
+ │ ┌──────────────────────────────────────┐ │
148
+ │ │ @donkeylabs/server (subprocess) │ │
149
+ │ │ - Spawned via Bun child_process │ │
150
+ │ │ - Runs full HTTP server │ │
151
+ │ └──────────────────────────────────────┘ │
152
+ └─────────────────────────────────────────────┘
153
+ ```
154
+
155
+ **Use when:**
156
+ - Not using Bun runtime
157
+ - Debugging backend separately
158
+ - Need isolated backend process
159
+
160
+ **Limitations:**
161
+ - Requires two ports
162
+ - Proxy overhead
163
+ - Hot reload works but is slower
164
+ - SSR calls require HTTP instead of direct
165
+
166
+ ---
167
+
168
+ ## File Watching
169
+
170
+ The framework has multiple file watchers for different purposes:
171
+
172
+ ### 1. Route/Type Watcher (Vite Plugin)
173
+
174
+ **Location:** `packages/adapter-sveltekit/src/vite.ts`
175
+
176
+ **Watches:** `src/server/**/*.ts` (configurable)
177
+
178
+ **Triggers:**
179
+ - Route file changes → Hot reload
180
+ - Any `.ts` file → Type regeneration
181
+
182
+ **Config:**
183
+ ```typescript
184
+ // vite.config.ts
185
+ donkeylabsDev({
186
+ watchDir: "./src/server", // Watch this directory
187
+ watchTypes: true, // Auto-generate types
188
+ hotReloadRoutes: true, // Enable hot reload
189
+ routePatterns: ["**/routes/**/*.ts"], // Route file glob
190
+ })
191
+ ```
192
+
193
+ ### 2. Plugin Watcher (CLI Script)
194
+
195
+ **Location:** `packages/cli/scripts/watcher.ts`
196
+
197
+ **Usage:**
198
+ ```bash
199
+ # Watch a specific plugin for changes
200
+ bun scripts/watcher.ts users
201
+ ```
202
+
203
+ **Watches:** Individual plugin directory
204
+
205
+ **Triggers:**
206
+ - `migrations/*.ts` changes → Generate schema types
207
+ - `index.ts` changes → Regenerate registry
208
+
209
+ **Why use it:**
210
+ - Focused watching for plugin development
211
+ - Prevents unnecessary type regeneration
212
+ - Better performance than full watcher
213
+
214
+ ### 3. Migration Watcher
215
+
216
+ **Triggers:**
217
+ - New migration file created
218
+ - Migration modified
219
+
220
+ **Actions:**
221
+ 1. Runs `bun scripts/generate-types.ts <plugin>`
222
+ 2. Generates `schema.ts` with Kysely types
223
+ 3. Updates plugin `index.ts` to import schema
224
+ 4. Regenerates registry
225
+
226
+ **Debouncing:**
227
+ - 500ms debounce to batch rapid changes
228
+ - 2s cooldown after generation to prevent loops
229
+
230
+ ---
231
+
232
+ ## Type Generation
233
+
234
+ Type generation is automatic but can be triggered manually:
235
+
236
+ ### Auto-Generation (Dev Mode)
237
+
238
+ **Triggers:**
239
+ - File changes in watched directories
240
+ - Migration file added
241
+ - Plugin structure modified
242
+
243
+ **Generated files:**
244
+ - `registry.d.ts` - Plugin registry types
245
+ - `context.d.ts` - App context with merged schemas
246
+ - `routes.ts` - Route input/output types
247
+ - `client.ts` or `api.ts` - API client
248
+
249
+ ### Manual Generation
250
+
251
+ ```bash
252
+ # Generate all types
253
+ bun run gen:types
254
+
255
+ # Or via CLI
256
+ bunx donkeylabs generate
257
+
258
+ # Generate for specific plugin
259
+ bun scripts/generate-types.ts users
260
+ ```
261
+
262
+ ### Generation Pipeline
263
+
264
+ ```
265
+ 1. Parse all plugin index.ts files
266
+
267
+ 2. Extract schema types (if withSchema used)
268
+
269
+ 3. Merge schemas from all plugins
270
+
271
+ 4. Generate registry.d.ts (PluginRegistry augmentation)
272
+
273
+ 5. Generate context.d.ts (GlobalContext with merged DB)
274
+
275
+ 6. Extract route definitions from route files
276
+
277
+ 7. Generate route types (input/output validation)
278
+
279
+ 8. Generate API client with full typing
280
+ ```
281
+
282
+ **Time:** ~1-3 seconds for typical project
283
+
284
+ ---
285
+
286
+ ## Debugging Utilities
287
+
288
+ ### Debug Logging
289
+
290
+ Enable detailed logging:
291
+
292
+ ```typescript
293
+ // src/server/index.ts
294
+ const server = new AppServer({
295
+ logger: { level: "debug" },
296
+ });
297
+ ```
298
+
299
+ **Log prefixes:**
300
+ - `[donkeylabs-dev]` - Dev server activity
301
+ - `[donkeylabs-hot-reload]` - Hot reload events
302
+ - `[plugin-name]` - Plugin-specific logs
303
+
304
+ ### Dev Server Logs
305
+
306
+ When running `bun --bun run dev`:
307
+
308
+ ```
309
+ [donkeylabs-dev] Starting in-process mode (Bun runtime detected)
310
+ [donkeylabs-dev] Watching src/server for type generation, hot reload...
311
+ [donkeylabs-dev] Server initialized (in-process mode)
312
+ [donkeylabs-dev] Ready at http://localhost:5173
313
+
314
+ [donkeylabs-dev] Hot reloading route: /src/server/routes/users/index.ts
315
+ [donkeylabs-dev] Route hot reload complete: users
316
+ ```
317
+
318
+ ### Inspecting Hot Reload
319
+
320
+ To debug hot reload issues:
321
+
322
+ 1. **Check mode:**
323
+ ```bash
324
+ bun --bun run dev # Should show "in-process mode"
325
+ ```
326
+
327
+ 2. **Verify file pattern:**
328
+ Your route files should match the pattern:
329
+ ```typescript
330
+ // Default: **/routes/**/*.ts
331
+ src/server/routes/users/index.ts ✅
332
+ src/server/plugins/users/index.ts ❌ (not a route)
333
+ ```
334
+
335
+ 3. **Check console:**
336
+ Look for `[donkeylabs-dev]` messages
337
+
338
+ 4. **Manual test:**
339
+ ```typescript
340
+ // Add to route file
341
+ console.log("Route loaded:", Date.now());
342
+ ```
343
+
344
+ ---
345
+
346
+ ## Performance Optimization
347
+
348
+ ### Dev Server Performance
349
+
350
+ **Fastest setup:**
351
+ ```bash
352
+ # Use Bun runtime
353
+ bun --bun run dev
354
+
355
+ # Disable type watching if not needed (rare)
356
+ donkeylabsDev({ watchTypes: false })
357
+ ```
358
+
359
+ **Slowdown causes:**
360
+ 1. Subprocess mode (proxy overhead)
361
+ 2. Type regeneration on every save (debounced but still frequent)
362
+ 3. Too many plugins (increases init time)
363
+ 4. Complex middleware chains
364
+
365
+ ### Type Generation Performance
366
+
367
+ **Fast:**
368
+ - Few plugins (< 10)
369
+ - Simple schemas
370
+ - SSD storage
371
+
372
+ **Slow:**
373
+ - Many plugins (> 20)
374
+ - Complex type definitions
375
+ - Network drives
376
+
377
+ **Optimization:**
378
+ - Use plugin watcher for focused work
379
+ - Commit generated types to avoid regeneration
380
+ - Skip validation in dev: `skipLibCheck: true`
381
+
382
+ ---
383
+
384
+ ## VS Code Integration
385
+
386
+ ### Recommended Extensions
387
+
388
+ 1. **Svelte for VS Code** - Svelte/SvelteKit support
389
+ 2. **TypeScript Importer** - Auto-import types
390
+ 3. **Error Lens** - Inline error display
391
+ 4. **TODO Highlight** - Mark todos in code
392
+
393
+ ### VS Code Extension Opportunities
394
+
395
+ A custom DonkeyLabs VS Code extension could provide:
396
+
397
+ #### 1. Code Snippets
398
+
399
+ **Plugin snippet:**
400
+ ```json
401
+ {
402
+ "DonkeyLabs Plugin": {
403
+ "prefix": "plugin",
404
+ "body": [
405
+ "export const ${1:name}Plugin = createPlugin",
406
+ " .withSchema<${2:Schema}>()",
407
+ " .define({",
408
+ " name: '${1:name}',",
409
+ " service: async (ctx) => ({",
410
+ " $3",
411
+ " }),",
412
+ " });"
413
+ ]
414
+ }
415
+ }
416
+ ```
417
+
418
+ **Route snippet:**
419
+ ```json
420
+ {
421
+ "DonkeyLabs Route": {
422
+ "prefix": "route",
423
+ "body": [
424
+ "router.route('${1:name}').typed(defineRoute({",
425
+ " input: ${2:inputSchema},",
426
+ " output: ${3:outputSchema},",
427
+ " handle: async (input, ctx) => {",
428
+ " $4",
429
+ " },",
430
+ "}));"
431
+ ]
432
+ }
433
+ }
434
+ ```
435
+
436
+ #### 2. Go to Definition
437
+
438
+ **Route → Plugin:**
439
+ - Click on `ctx.plugins.users.getById`
440
+ - Jump to plugin service method definition
441
+
442
+ **Implementation:**
443
+ ```typescript
444
+ // VS Code extension
445
+ vscode.languages.registerDefinitionProvider('typescript', {
446
+ provideDefinition(document, position) {
447
+ // Detect ctx.plugins.* pattern
448
+ // Resolve plugin path from registry
449
+ // Return Location to plugin method
450
+ }
451
+ });
452
+ ```
453
+
454
+ #### 3. Auto-Import
455
+
456
+ **Context-aware suggestions:**
457
+ - Type `ctx.plugins.` → Suggest all available plugins
458
+ - Type `ctx.core.` → Suggest core services
459
+ - Type `router.` → Suggest middleware methods
460
+
461
+ #### 4. Type Hints
462
+
463
+ **Show generated types inline:**
464
+ ```typescript
465
+ // Hover shows:
466
+ // (property) users: {
467
+ // getById: (id: string) => Promise<User | undefined>
468
+ // create: (data: CreateUserInput) => Promise<User>
469
+ // }
470
+ ctx.plugins.users
471
+ ```
472
+
473
+ #### 5. Status Bar
474
+
475
+ **Display:**
476
+ - ⏳ Type generation in progress
477
+ - ✅ Types up to date
478
+ - 🔄 Hot reload active
479
+ - 🌡️ Backend status (in-process/subprocess)
480
+
481
+ **Click actions:**
482
+ - Regenerate types
483
+ - Restart dev server
484
+ - Toggle hot reload
485
+
486
+ #### 6. Commands
487
+
488
+ **Command palette:**
489
+ - `DonkeyLabs: Generate Types`
490
+ - `DonkeyLabs: Create Plugin`
491
+ - `DonkeyLabs: Add Migration`
492
+ - `DonkeyLabs: Restart Dev Server`
493
+
494
+ #### 7. File Explorer Integration
495
+
496
+ **Context menus:**
497
+ - Right-click on `plugins/` folder → "Create Plugin"
498
+ - Right-click on plugin folder → "Add Migration"
499
+ - Right-click on route file → "Add Route Handler"
500
+
501
+ #### 8. Error Diagnostics
502
+
503
+ **Custom linting:**
504
+ - Warn about raw SQL in migrations
505
+ - Detect missing type regeneration
506
+ - Flag business logic in routes
507
+ - Check plugin dependency cycles
508
+
509
+ ### Implementation Approach
510
+
511
+ **Option 1: Language Server Protocol (LSP)**
512
+ - Full IDE integration
513
+ - Real-time type checking
514
+ - Complex to implement
515
+
516
+ **Option 2: VS Code Extension API**
517
+ - Simpler implementation
518
+ - Good enough for most features
519
+ - Can use existing TypeScript compiler API
520
+
521
+ **Priority features:**
522
+ 1. Code snippets (easy win)
523
+ 2. Status bar indicator
524
+ 3. Commands palette integration
525
+ 4. Go to definition (high value)
526
+ 5. Auto-import (high value)
527
+ 6. Diagnostics (nice to have)
528
+
529
+ ### Example Extension Structure
530
+
531
+ ```
532
+ donkeylabs-vscode/
533
+ ├── package.json
534
+ ├── src/
535
+ │ ├── extension.ts # Main entry
536
+ │ ├── providers/
537
+ │ │ ├── definition.ts # Go to definition
538
+ │ │ ├── completion.ts # Auto-complete
539
+ │ │ └── diagnostics.ts # Linting
540
+ │ ├── commands/
541
+ │ │ ├── generateTypes.ts
542
+ │ │ ├── createPlugin.ts
543
+ │ │ └── addMigration.ts
544
+ │ └── status/
545
+ │ └── bar.ts # Status bar
546
+ └── snippets/
547
+ ├── plugin.json
548
+ ├── route.json
549
+ └── migration.json
550
+ ```
551
+
552
+ ---
553
+
554
+ ## Troubleshooting
555
+
556
+ ### Hot Reload Not Working
557
+
558
+ **Symptoms:** Changes don't appear after save
559
+
560
+ **Checklist:**
561
+ 1. ✅ Using `bun --bun run dev`
562
+ 2. ✅ File is in `src/server/routes/`
563
+ 3. ✅ File matches pattern `**/routes/**/*.ts`
564
+ 4. ✅ No TypeScript errors in file
565
+ 5. ✅ Console shows `[donkeylabs-dev]` messages
566
+
567
+ **Fixes:**
568
+ ```bash
569
+ # Restart dev server
570
+ Ctrl+C && bun --bun run dev
571
+
572
+ # Manual type regeneration
573
+ bun run gen:types
574
+
575
+ # Check file pattern
576
+ grep "routePatterns" vite.config.ts
577
+ ```
578
+
579
+ ### Types Not Updating
580
+
581
+ **Symptoms:** `api.ts` shows old types
582
+
583
+ **Causes:**
584
+ 1. Type generation skipped due to cooldown
585
+ 2. Plugin has TypeScript errors
586
+ 3. Migration doesn't compile
587
+
588
+ **Fix:**
589
+ ```bash
590
+ # Force regeneration
591
+ bun run gen:types
592
+
593
+ # Check for errors
594
+ bun --bun tsc --noEmit
595
+
596
+ # Regenerate specific plugin
597
+ bun scripts/generate-types.ts <plugin-name>
598
+ ```
599
+
600
+ ### Slow Dev Server
601
+
602
+ **Symptoms:** Long startup, slow requests
603
+
604
+ **Causes:**
605
+ 1. Using subprocess mode
606
+ 2. Too many plugins initializing
607
+ 3. Slow database connection
608
+ 4. Heavy middleware chains
609
+
610
+ **Fix:**
611
+ ```bash
612
+ # Switch to in-process
613
+ bun --bun run dev
614
+
615
+ # Check plugin count
616
+ ls -1 src/server/plugins/ | wc -l
617
+
618
+ # Profile startup
619
+ DEBUG=* bun --bun run dev
620
+ ```
621
+
622
+ ### "Cannot find module" Errors
623
+
624
+ **Causes:**
625
+ 1. Types not generated
626
+ 2. Import path wrong
627
+ 3. Plugin not registered
628
+
629
+ **Fix:**
630
+ ```bash
631
+ # Generate types
632
+ bun run gen:types
633
+
634
+ # Verify import path
635
+ # Check plugin is registered in server/index.ts
636
+ ```
637
+
638
+ ---
639
+
640
+ ## Summary
641
+
642
+ The DonkeyLabs dev experience includes:
643
+
644
+ 1. **Sophisticated hot reload** - Route changes without restart
645
+ 2. **Two dev modes** - In-process (fast) and subprocess (compatible)
646
+ 3. **Automatic type generation** - Triggered by file changes
647
+ 4. **File watchers** - Route watcher + plugin watcher
648
+ 5. **Debugging tools** - Console logging, status indicators
649
+ 6. **VS Code opportunities** - Snippets, go-to-def, auto-import
650
+
651
+ **Best practices:**
652
+ - Always use `bun --bun run dev`
653
+ - Run `gen:types` after structural changes
654
+ - Use plugin watcher for focused plugin dev
655
+ - Commit generated types for faster CI
656
+ - Check console for `[donkeylabs-dev]` messages