@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.
- package/docs/caching-strategies.md +677 -0
- package/docs/dev-experience.md +656 -0
- package/docs/hot-reload-limitations.md +166 -0
- package/docs/load-testing.md +974 -0
- package/docs/plugin-registry-design.md +1064 -0
- package/docs/production.md +1229 -0
- package/docs/workflows.md +90 -3
- package/package.json +1 -1
- package/src/admin/routes.ts +153 -0
- package/src/core/cron.ts +90 -9
- package/src/core/index.ts +31 -0
- package/src/core/job-adapter-kysely.ts +176 -73
- package/src/core/job-adapter-sqlite.ts +10 -0
- package/src/core/jobs.ts +112 -17
- package/src/core/migrations/workflows/002_add_metadata_column.ts +28 -0
- package/src/core/process-adapter-kysely.ts +62 -21
- package/src/core/storage-adapter-local.test.ts +199 -0
- package/src/core/storage.test.ts +197 -0
- package/src/core/workflow-adapter-kysely.ts +66 -19
- package/src/core/workflow-executor.ts +239 -0
- package/src/core/workflow-proxy.ts +238 -0
- package/src/core/workflow-socket.ts +449 -0
- package/src/core/workflow-state-machine.ts +593 -0
- package/src/core/workflows.test.ts +758 -0
- package/src/core/workflows.ts +705 -595
- package/src/core.ts +17 -6
- package/src/index.ts +14 -0
- package/src/testing/database.test.ts +263 -0
- package/src/testing/database.ts +173 -0
- package/src/testing/e2e.test.ts +189 -0
- package/src/testing/e2e.ts +272 -0
- package/src/testing/index.ts +18 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Hot Reload Limitations & Solutions
|
|
2
|
+
|
|
3
|
+
## The Problem
|
|
4
|
+
|
|
5
|
+
**Plugins don't hot reload** when you make changes. This is a fundamental limitation of the current architecture:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Change: plugins/users/index.ts
|
|
9
|
+
❌ Service methods don't update automatically
|
|
10
|
+
❌ Type definitions don't refresh
|
|
11
|
+
❌ Must restart server to see changes
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Why Plugins Don't Hot Reload
|
|
15
|
+
|
|
16
|
+
1. **Plugin Initialization Happens Once**
|
|
17
|
+
- Plugins register at server startup
|
|
18
|
+
- Services are instantiated with closures
|
|
19
|
+
- Dependencies are resolved at init time
|
|
20
|
+
|
|
21
|
+
2. **Type Generation Required**
|
|
22
|
+
- Plugin schemas generate TypeScript types
|
|
23
|
+
- Types are written to disk
|
|
24
|
+
- TypeScript compiler needs restart to see changes
|
|
25
|
+
|
|
26
|
+
3. **State Management**
|
|
27
|
+
- Plugins may have internal state
|
|
28
|
+
- Connections (DB, Redis) are established
|
|
29
|
+
- Cron jobs are scheduled
|
|
30
|
+
|
|
31
|
+
## Current Workarounds
|
|
32
|
+
|
|
33
|
+
### 1. Plugin Watcher (Best for Plugin Development)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Watch specific plugin
|
|
37
|
+
bun scripts/watcher.ts users
|
|
38
|
+
|
|
39
|
+
# This watches migrations and index.ts
|
|
40
|
+
# Auto-runs type generation on changes
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 2. Manual Type Regeneration
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# After any plugin change
|
|
47
|
+
bun run gen:types
|
|
48
|
+
|
|
49
|
+
# Then restart server
|
|
50
|
+
Ctrl+C && bun run dev
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 3. Use Routes for Rapid Prototyping
|
|
54
|
+
|
|
55
|
+
**During development only:**
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
// Instead of creating full plugin
|
|
59
|
+
// Put logic directly in route temporarily
|
|
60
|
+
|
|
61
|
+
router.route("quick-test").typed(defineRoute({
|
|
62
|
+
handle: async (input, ctx) => {
|
|
63
|
+
// Direct DB access for rapid iteration
|
|
64
|
+
// Move to plugin once stable
|
|
65
|
+
return ctx.db.selectFrom("users").execute();
|
|
66
|
+
},
|
|
67
|
+
}));
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 4. Development Plugin Pattern
|
|
71
|
+
|
|
72
|
+
Create a "dev" plugin that reloads:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// plugins/dev/index.ts
|
|
76
|
+
export const devPlugin = createPlugin.define({
|
|
77
|
+
name: "dev",
|
|
78
|
+
service: async (ctx) => {
|
|
79
|
+
// Only in development
|
|
80
|
+
if (process.env.NODE_ENV === "production") {
|
|
81
|
+
return { hotReload: async () => {} };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
hotReload: async (pluginName: string) => {
|
|
86
|
+
// Force re-import
|
|
87
|
+
const module = await import(`../${pluginName}/index.ts?${Date.now()}`);
|
|
88
|
+
ctx.core.logger.info(`Reloaded ${pluginName}`);
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Future Solutions
|
|
96
|
+
|
|
97
|
+
### Option 1: Plugin Hot Reload API
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// Proposed API
|
|
101
|
+
const server = new AppServer({
|
|
102
|
+
hotReload: {
|
|
103
|
+
plugins: true, // Enable plugin hot reload
|
|
104
|
+
onPluginChange: async (pluginName) => {
|
|
105
|
+
// 1. Clear require cache
|
|
106
|
+
// 2. Re-import plugin
|
|
107
|
+
// 3. Re-generate types
|
|
108
|
+
// 4. Update service registry
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Option 2: Service Re-instantiation
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// Reload just the service methods
|
|
118
|
+
server.reloadPluginService("users", async (ctx) => ({
|
|
119
|
+
// New service implementation
|
|
120
|
+
getById: async (id) => { ... },
|
|
121
|
+
}));
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Option 3: Plugin Development Mode
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# New CLI command
|
|
128
|
+
donkeylabs dev
|
|
129
|
+
|
|
130
|
+
# Features:
|
|
131
|
+
# - Watches all plugin files
|
|
132
|
+
# - Auto-restarts on structural changes
|
|
133
|
+
# - Auto-regenerates types
|
|
134
|
+
# - Maintains DB connection
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Recommended Development Workflow
|
|
138
|
+
|
|
139
|
+
**For Active Plugin Development:**
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Terminal 1: Run server
|
|
143
|
+
bun run dev
|
|
144
|
+
|
|
145
|
+
# Terminal 2: Watch plugin
|
|
146
|
+
bun scripts/watcher.ts users
|
|
147
|
+
|
|
148
|
+
# Make changes to plugin
|
|
149
|
+
# Watcher auto-generates types
|
|
150
|
+
# Server shows new types after restart
|
|
151
|
+
|
|
152
|
+
# When done:
|
|
153
|
+
# Commit both plugin AND generated types
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Summary
|
|
157
|
+
|
|
158
|
+
| What | Hot Reload? | Solution |
|
|
159
|
+
|------|-------------|----------|
|
|
160
|
+
| Route handlers | ✅ Yes | Instant |
|
|
161
|
+
| Route schemas | ⚠️ Needs type gen | Auto-regen |
|
|
162
|
+
| Plugin methods | ❌ No | Restart server |
|
|
163
|
+
| Plugin structure | ❌ No | Restart + type gen |
|
|
164
|
+
| Database changes | ⚠️ Migration + type gen | Run migrations |
|
|
165
|
+
|
|
166
|
+
**Best Practice:** Develop in routes first, extract to plugins once stable.
|