skeleton-crew-runtime 0.1.1 → 0.1.2
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 +149 -584
- package/dist/runtime-context.d.ts +14 -55
- package/dist/runtime-context.d.ts.map +1 -1
- package/dist/runtime-context.js +21 -4
- package/dist/runtime-context.js.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +3 -1
- package/dist/runtime.js.map +1 -1
- package/package.json +43 -26
package/README.md
CHANGED
|
@@ -1,671 +1,264 @@
|
|
|
1
1
|
# Skeleton Crew Runtime
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**A minimal plugin runtime for building modular JavaScript applications.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Stop wiring up infrastructure. Start building features.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- Different parts use different patterns (callbacks, promises, globals)
|
|
13
|
-
- Testing is hard because everything is tightly coupled
|
|
14
|
-
- You want to use modern patterns but can't justify a full rewrite
|
|
15
|
-
|
|
16
|
-
**Sound familiar?**
|
|
17
|
-
|
|
18
|
-
## The Solution
|
|
19
|
-
|
|
20
|
-
Skeleton Crew lets you write new features as isolated plugins that can access your existing services — without touching legacy code.
|
|
7
|
+
```bash
|
|
8
|
+
npm install skeleton-crew-runtime
|
|
9
|
+
```
|
|
10
|
+
---
|
|
11
|
+
## Documentation
|
|
21
12
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
userService: new UserService()
|
|
28
|
-
};
|
|
13
|
+
### Getting Started
|
|
14
|
+
- **[Installation](docs/getting-started/installation.md)** - Install and setup
|
|
15
|
+
- **[API Reference](docs/api/reference.md)** - Complete TypeScript API
|
|
16
|
+
- **[Core Concepts](docs/getting-started/README.md)** - Understand the fundamentals
|
|
17
|
+
- **[Your First Plugin](docs/getting-started/your-first-plugin.md)** - Build your first feature
|
|
29
18
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
db: legacyApp.database,
|
|
34
|
-
logger: legacyApp.logger,
|
|
35
|
-
users: legacyApp.userService
|
|
36
|
-
}
|
|
37
|
-
});
|
|
19
|
+
### Guides & Examples
|
|
20
|
+
- **[Migration Guide](docs/guides/migration-guide.md)** - Integrate with existing apps
|
|
21
|
+
- **[Examples Guide](docs/guides/EXAMPLES_GUIDE.md)** - Learn through code examples
|
|
38
22
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
setup(ctx) {
|
|
44
|
-
// Access legacy services through context
|
|
45
|
-
const { db, logger } = ctx.host;
|
|
46
|
-
|
|
47
|
-
ctx.actions.registerAction({
|
|
48
|
-
id: "analytics:track",
|
|
49
|
-
handler: async (event) => {
|
|
50
|
-
logger.info("Tracking event:", event);
|
|
51
|
-
await db.insert("analytics", event);
|
|
52
|
-
ctx.events.emit("analytics:tracked", event);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
};
|
|
23
|
+
### Use Cases
|
|
24
|
+
- **[Browser Extensions](docs/use-cases/BROWSER_TOOLS.md)** - Build browser tools
|
|
25
|
+
- **[CLI Applications](docs/use-cases/)** - Command-line tools
|
|
26
|
+
- **[Real-Time Apps](docs/use-cases/)** - Collaboration and sync
|
|
57
27
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
28
|
+
### Advanced
|
|
29
|
+
- **[Architecture](docs/architecture/)** - How it works under the hood
|
|
30
|
+
- **[Troubleshooting](docs/troubleshooting/)** - Common issues and solutions
|
|
61
31
|
|
|
62
|
-
|
|
32
|
+
---
|
|
63
33
|
|
|
64
|
-
##
|
|
34
|
+
## What is this?
|
|
65
35
|
|
|
66
|
-
|
|
67
|
-
Your existing code doesn't change. New features run alongside it.
|
|
36
|
+
Skeleton Crew Runtime is a lightweight foundation for building applications where features can be added, removed, or replaced without touching existing code. Think VS Code's extension system, but for any JavaScript application.
|
|
68
37
|
|
|
69
|
-
|
|
70
|
-
Migrate one feature at a time. No big-bang rewrites.
|
|
38
|
+
**Core idea:** Your app is a collection of plugins. Each plugin registers actions (business logic), screens (UI definitions), and events (communication). The runtime coordinates everything.
|
|
71
39
|
|
|
72
|
-
|
|
73
|
-
Start writing better code today. See benefits immediately.
|
|
40
|
+
**Result:** Add features by dropping in plugins. Remove features by taking them out. No refactoring. No breaking changes.
|
|
74
41
|
|
|
75
|
-
|
|
76
|
-
New developers work in clean plugin code. Legacy experts maintain old code.
|
|
42
|
+
## Why would I use this?
|
|
77
43
|
|
|
78
|
-
|
|
79
|
-
When you're ready, gradually replace legacy services. Or don't — both work fine.
|
|
44
|
+
You're building something modular and you might know these challenges:
|
|
80
45
|
|
|
46
|
+
- **Wiring up infrastructure** - Event buses, plugin loaders, action registries
|
|
47
|
+
- **Tight coupling** - Changing one feature breaks three others
|
|
48
|
+
- **Testing nightmares** - Can't test features in isolation
|
|
49
|
+
- **Framework lock-in** - Married to React/Vue/whatever forever
|
|
50
|
+
- **Refactoring hell** - Adding features means touching existing code
|
|
81
51
|
|
|
82
|
-
|
|
52
|
+
**Skeleton Crew Runtime gives you:**
|
|
83
53
|
|
|
84
|
-
|
|
54
|
+
- **Plugin isolation** - Features don't know about each other
|
|
55
|
+
- **Event-driven communication** - Plugins coordinate without coupling
|
|
56
|
+
- **Framework freedom** - Business logic separate from UI
|
|
57
|
+
- **Testability** - Mock what you need, test what matters
|
|
58
|
+
- **Minimal core** - < 5KB, zero dependencies
|
|
85
59
|
|
|
86
|
-
|
|
87
|
-
npm install skeleton-crew-runtime
|
|
88
|
-
```
|
|
60
|
+
## Show me code
|
|
89
61
|
|
|
90
|
-
|
|
62
|
+
Here's a complete plugin that adds a feature to your app:
|
|
91
63
|
|
|
92
64
|
```typescript
|
|
93
|
-
import { Runtime } from
|
|
94
|
-
|
|
95
|
-
// Inject your existing services
|
|
96
|
-
const runtime = new Runtime({
|
|
97
|
-
hostContext: {
|
|
98
|
-
db: yourDatabase,
|
|
99
|
-
api: yourApiClient,
|
|
100
|
-
logger: yourLogger,
|
|
101
|
-
config: yourConfig
|
|
102
|
-
}
|
|
103
|
-
});
|
|
65
|
+
import { Runtime, PluginDefinition } from 'skeleton-crew-runtime';
|
|
104
66
|
|
|
67
|
+
// 1. Create runtime
|
|
68
|
+
const runtime = new Runtime();
|
|
105
69
|
await runtime.initialize();
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
### 3. Write a Plugin for Your New Feature
|
|
70
|
+
const ctx = runtime.getContext();
|
|
109
71
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
version: "1.0.0",
|
|
72
|
+
// 2. Write a plugin (this is a complete feature)
|
|
73
|
+
const notificationsPlugin: PluginDefinition = {
|
|
74
|
+
name: 'notifications',
|
|
75
|
+
version: '1.0.0',
|
|
115
76
|
|
|
116
77
|
setup(ctx) {
|
|
117
|
-
//
|
|
118
|
-
const { db, logger } = ctx.host;
|
|
119
|
-
|
|
120
|
-
// Register an action
|
|
78
|
+
// Register business logic
|
|
121
79
|
ctx.actions.registerAction({
|
|
122
|
-
id:
|
|
123
|
-
handler: async ({ userId, message }) => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
// Use your existing database
|
|
127
|
-
await db.insert("notifications", {
|
|
128
|
-
userId,
|
|
129
|
-
message,
|
|
130
|
-
createdAt: new Date()
|
|
131
|
-
});
|
|
80
|
+
id: 'notifications:send',
|
|
81
|
+
handler: async ({ userId, message }, ctx) => {
|
|
82
|
+
// Your logic here
|
|
83
|
+
await sendPushNotification(userId, message);
|
|
132
84
|
|
|
133
|
-
//
|
|
134
|
-
ctx.events.emit(
|
|
85
|
+
// Let other plugins know
|
|
86
|
+
ctx.events.emit('notification:sent', { userId });
|
|
135
87
|
|
|
136
88
|
return { success: true };
|
|
137
89
|
}
|
|
138
90
|
});
|
|
139
91
|
|
|
140
|
-
//
|
|
141
|
-
ctx.events.on(
|
|
142
|
-
await ctx.actions.runAction(
|
|
92
|
+
// React to other plugins
|
|
93
|
+
ctx.events.on('user:registered', async (user) => {
|
|
94
|
+
await ctx.actions.runAction('notifications:send', {
|
|
143
95
|
userId: user.id,
|
|
144
|
-
message:
|
|
96
|
+
message: 'Welcome!'
|
|
145
97
|
});
|
|
146
98
|
});
|
|
147
99
|
}
|
|
148
100
|
};
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### 4. Register and Use
|
|
152
101
|
|
|
153
|
-
|
|
154
|
-
|
|
102
|
+
// 3. Register and use
|
|
103
|
+
ctx.plugins.registerPlugin(notificationsPlugin);
|
|
155
104
|
|
|
156
|
-
//
|
|
157
|
-
ctx.
|
|
158
|
-
|
|
159
|
-
// Call from anywhere in your app
|
|
160
|
-
await ctx.actions.runAction("notifications:send", {
|
|
105
|
+
// anywhere in your app
|
|
106
|
+
await ctx.actions.runAction('notifications:send', {
|
|
161
107
|
userId: 123,
|
|
162
|
-
message:
|
|
108
|
+
message: 'Your order shipped!'
|
|
163
109
|
});
|
|
164
110
|
```
|
|
165
111
|
|
|
166
|
-
**That's it.**
|
|
112
|
+
**That's it.** The plugin is isolated, testable, and can be removed without breaking anything.
|
|
167
113
|
|
|
168
|
-
## Core
|
|
114
|
+
## Core concepts (5 minutes)
|
|
169
115
|
|
|
170
|
-
### 1.
|
|
116
|
+
### 1. Plugins: Isolated Features
|
|
171
117
|
|
|
172
|
-
|
|
118
|
+
A plugin is just an object with a name and a setup function:
|
|
173
119
|
|
|
174
120
|
```typescript
|
|
175
|
-
|
|
176
|
-
hostContext: {
|
|
177
|
-
db: legacyDatabase, // Your existing DB connection
|
|
178
|
-
cache: redisClient, // Your existing cache
|
|
179
|
-
auth: authService // Your existing auth
|
|
180
|
-
}
|
|
181
|
-
});
|
|
121
|
+
import type { PluginDefinition, RuntimeContext } from 'skeleton-crew-runtime';
|
|
182
122
|
|
|
183
|
-
|
|
184
|
-
|
|
123
|
+
export const myPlugin: PluginDefinition = {
|
|
124
|
+
name: 'my-plugin',
|
|
125
|
+
version: '1.0.0',
|
|
126
|
+
|
|
127
|
+
setup(ctx: RuntimeContext) {
|
|
128
|
+
// Register your feature here
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
dispose(ctx: RuntimeContext) {
|
|
132
|
+
// Optional: cleanup resources when plugin is removed
|
|
133
|
+
// Use this for: closing connections, clearing timers, releasing memory
|
|
134
|
+
// Event listeners auto-cleanup, so you usually don't need this
|
|
135
|
+
}
|
|
136
|
+
};
|
|
185
137
|
```
|
|
186
138
|
|
|
187
139
|
### 2. Actions: Business Logic
|
|
188
140
|
|
|
189
|
-
|
|
141
|
+
Actions are named functions that do work:
|
|
190
142
|
|
|
191
143
|
```typescript
|
|
144
|
+
// Register an action
|
|
192
145
|
ctx.actions.registerAction({
|
|
193
|
-
id:
|
|
194
|
-
handler: async (orderData) => {
|
|
146
|
+
id: 'orders:create',
|
|
147
|
+
handler: async (orderData, ctx) => {
|
|
195
148
|
const { db } = ctx.host;
|
|
196
|
-
const order = await db.insert(
|
|
197
|
-
ctx.events.emit(
|
|
149
|
+
const order = await db.insert('orders', orderData);
|
|
150
|
+
ctx.events.emit('order:created', order);
|
|
198
151
|
return order;
|
|
199
152
|
}
|
|
200
153
|
});
|
|
201
154
|
|
|
202
155
|
// Call from anywhere
|
|
203
|
-
const order = await ctx.actions.runAction(
|
|
156
|
+
const order = await ctx.actions.runAction('orders:create', data);
|
|
204
157
|
```
|
|
205
158
|
|
|
206
159
|
### 3. Events: Decouple Features
|
|
207
160
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
```typescript
|
|
211
|
-
// Feature A: Emit event
|
|
212
|
-
ctx.events.emit("order:created", order);
|
|
213
|
-
|
|
214
|
-
// Feature B: React to event (doesn't know about Feature A)
|
|
215
|
-
ctx.events.on("order:created", (order) => {
|
|
216
|
-
ctx.actions.runAction("email:send", {
|
|
217
|
-
to: order.customerEmail,
|
|
218
|
-
template: "order-confirmation"
|
|
219
|
-
});
|
|
220
|
-
});
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### 4. Plugins: Isolated Features
|
|
224
|
-
|
|
225
|
-
Group related functionality into plugins:
|
|
161
|
+
Plugins communicate without knowing about each other:
|
|
226
162
|
|
|
227
163
|
```typescript
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
version: "1.0.0",
|
|
231
|
-
setup(ctx) {
|
|
232
|
-
// Register actions, screens, event handlers
|
|
233
|
-
// Everything for "orders" feature in one place
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### 5. Screens (Optional): UI Definitions
|
|
239
|
-
|
|
240
|
-
Define screens that any UI framework can render:
|
|
164
|
+
// Plugin A: Emit event
|
|
165
|
+
ctx.events.emit('order:created', order);
|
|
241
166
|
|
|
242
|
-
|
|
243
|
-
ctx.
|
|
244
|
-
|
|
245
|
-
title: "Orders",
|
|
246
|
-
component: OrderListComponent // React, Vue, or anything
|
|
167
|
+
// Plugin B: React (doesn't know about Plugin A)
|
|
168
|
+
ctx.events.on('order:created', (order) => {
|
|
169
|
+
sendConfirmationEmail(order);
|
|
247
170
|
});
|
|
248
171
|
```
|
|
249
172
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
### Pattern 1: Feature Flags (Safest)
|
|
253
|
-
|
|
254
|
-
Gradually switch features from legacy to plugins:
|
|
255
|
-
|
|
256
|
-
```typescript
|
|
257
|
-
const features = {
|
|
258
|
-
notifications: 'plugin', // Using Skeleton Crew
|
|
259
|
-
payments: 'legacy', // Still using old code
|
|
260
|
-
reports: 'plugin' // Using Skeleton Crew
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
class App {
|
|
264
|
-
async sendNotification(userId, message) {
|
|
265
|
-
if (features.notifications === 'plugin') {
|
|
266
|
-
return this.runtime.getContext().actions.runAction(
|
|
267
|
-
'notifications:send',
|
|
268
|
-
{ userId, message }
|
|
269
|
-
);
|
|
270
|
-
} else {
|
|
271
|
-
return this.legacyNotifications.send(userId, message);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
**Benefits:** Roll back instantly if issues arise. Test in production with small user percentage.
|
|
173
|
+
### 4. Host Context: Bridge to Existing Code
|
|
278
174
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
Keep legacy code frozen. All new features are plugins:
|
|
175
|
+
Inject your existing services so plugins can use them:
|
|
282
176
|
|
|
283
177
|
```typescript
|
|
284
|
-
|
|
285
|
-
class LegacyApp {
|
|
286
|
-
constructor() {
|
|
287
|
-
this.db = new Database();
|
|
288
|
-
this.users = new UserService(this.db);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
178
|
+
import { Runtime } from 'skeleton-crew-runtime';
|
|
291
179
|
|
|
292
|
-
// New features as plugins
|
|
293
180
|
const runtime = new Runtime({
|
|
294
181
|
hostContext: {
|
|
295
|
-
db:
|
|
296
|
-
|
|
182
|
+
db: yourDatabase,
|
|
183
|
+
cache: redisClient,
|
|
184
|
+
logger: yourLogger
|
|
297
185
|
}
|
|
298
186
|
});
|
|
299
187
|
|
|
300
|
-
|
|
301
|
-
const
|
|
302
|
-
name: "analytics",
|
|
303
|
-
version: "1.0.0",
|
|
304
|
-
setup(ctx) {
|
|
305
|
-
const { db, users } = ctx.host;
|
|
306
|
-
|
|
307
|
-
ctx.actions.registerAction({
|
|
308
|
-
id: "analytics:track",
|
|
309
|
-
handler: async (event) => {
|
|
310
|
-
await db.insert("analytics", event);
|
|
311
|
-
}
|
|
312
|
-
});
|
|
313
|
-
}
|
|
314
|
-
};
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
**Benefits:** Legacy code stays stable. New code is clean and testable. No rewrite needed.
|
|
318
|
-
|
|
319
|
-
### Pattern 3: Strangler Fig
|
|
320
|
-
|
|
321
|
-
Gradually replace legacy services with plugin-based ones:
|
|
322
|
-
|
|
323
|
-
```typescript
|
|
324
|
-
// Phase 1: Legacy service
|
|
325
|
-
const legacyAuth = new LegacyAuthService();
|
|
326
|
-
|
|
327
|
-
// Phase 2: New auth plugin (same interface)
|
|
328
|
-
const AuthPlugin = {
|
|
329
|
-
name: "auth",
|
|
330
|
-
version: "2.0.0",
|
|
331
|
-
setup(ctx) {
|
|
332
|
-
ctx.actions.registerAction({
|
|
333
|
-
id: "auth:login",
|
|
334
|
-
handler: async (credentials) => {
|
|
335
|
-
// New implementation
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
// Phase 3: Switch gradually
|
|
342
|
-
const useNewAuth = process.env.NEW_AUTH === 'true';
|
|
188
|
+
await runtime.initialize();
|
|
189
|
+
const ctx = runtime.getContext();
|
|
343
190
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
return runtime.getContext().actions.runAction('auth:login', credentials);
|
|
347
|
-
} else {
|
|
348
|
-
return legacyAuth.login(credentials);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
191
|
+
// Plugins access via ctx.host
|
|
192
|
+
const { db, logger } = ctx.host;
|
|
351
193
|
```
|
|
352
194
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
### Pattern 4: Event-Driven Integration
|
|
195
|
+
### 5. Screens (Optional): UI Definitions
|
|
356
196
|
|
|
357
|
-
|
|
197
|
+
Define screens that any UI framework can render:
|
|
358
198
|
|
|
359
199
|
```typescript
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
// Add this one line
|
|
366
|
-
eventBus.emit('user:created', user);
|
|
367
|
-
|
|
368
|
-
return user;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// New plugin reacts to legacy events
|
|
373
|
-
const WelcomeEmailPlugin = {
|
|
374
|
-
name: "welcome-emails",
|
|
375
|
-
version: "1.0.0",
|
|
376
|
-
setup(ctx) {
|
|
377
|
-
ctx.events.on('user:created', async (user) => {
|
|
378
|
-
await ctx.actions.runAction('email:send', {
|
|
379
|
-
to: user.email,
|
|
380
|
-
template: 'welcome'
|
|
381
|
-
});
|
|
382
|
-
});
|
|
383
|
-
}
|
|
384
|
-
};
|
|
200
|
+
ctx.screens.registerScreen({
|
|
201
|
+
id: 'orders:list',
|
|
202
|
+
title: 'Orders',
|
|
203
|
+
component: 'OrderListComponent' // string, class, function, or any type
|
|
204
|
+
});
|
|
385
205
|
```
|
|
386
206
|
|
|
387
|
-
**Benefits:** Minimal legacy changes. New features are completely isolated. Easy to add/remove features.
|
|
388
|
-
|
|
389
|
-
## When to Use Skeleton Crew
|
|
390
|
-
|
|
391
|
-
### ✅ Perfect For
|
|
392
|
-
|
|
393
|
-
- **Legacy modernization** - Add features without touching old code
|
|
394
|
-
- **Internal tools** - Admin panels, dashboards, dev tools
|
|
395
|
-
- **Browser extensions** - Background scripts with plugin architecture
|
|
396
|
-
- **Modular applications** - Features that can be enabled/disabled
|
|
397
|
-
- **Multi-team codebases** - Teams work on isolated plugins
|
|
398
|
-
- **Gradual rewrites** - Migrate piece by piece
|
|
399
|
-
|
|
400
|
-
### ❌ Not Ideal For
|
|
401
|
-
|
|
402
|
-
- **Greenfield apps with simple needs** - Might be overkill
|
|
403
|
-
- **Static websites** - No need for runtime architecture
|
|
404
|
-
- **Apps with single feature** - Plugin system adds unnecessary complexity
|
|
405
|
-
|
|
406
207
|
---
|
|
407
208
|
|
|
408
|
-
##
|
|
409
|
-
|
|
410
|
-
### Introspection API
|
|
411
|
-
|
|
412
|
-
Debug and monitor your runtime:
|
|
413
|
-
|
|
414
|
-
```typescript
|
|
415
|
-
const ctx = runtime.getContext();
|
|
416
|
-
|
|
417
|
-
// List all registered resources
|
|
418
|
-
const actions = ctx.introspect.listActions();
|
|
419
|
-
const plugins = ctx.introspect.listPlugins();
|
|
420
|
-
const screens = ctx.introspect.listScreens();
|
|
209
|
+
## What can I build?
|
|
421
210
|
|
|
422
|
-
|
|
423
|
-
const stats = ctx.introspect.getMetadata();
|
|
424
|
-
// { runtimeVersion: "0.1.0", totalActions: 15, totalPlugins: 5 }
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
**Use cases:** Admin dashboards, debugging tools, runtime monitoring.
|
|
211
|
+
Skeleton Crew works for any modular JavaScript application:
|
|
428
212
|
|
|
429
|
-
###
|
|
213
|
+
### Developer Tools
|
|
214
|
+
- **CLI tools** - Task runners, deployment scripts, dev environments
|
|
215
|
+
- **Browser extensions** - Tab managers, productivity tools, dev tools
|
|
216
|
+
- **Build tools** - Custom bundlers, code generators, linters
|
|
430
217
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
id: "api:fetch",
|
|
436
|
-
timeout: 5000, // 5 seconds max
|
|
437
|
-
handler: async () => {
|
|
438
|
-
return await fetch('/api/data');
|
|
439
|
-
}
|
|
440
|
-
});
|
|
441
|
-
```
|
|
218
|
+
### Internal Applications
|
|
219
|
+
- **Admin panels** - User management, content moderation, analytics
|
|
220
|
+
- **Dashboards** - Monitoring, reporting, data visualization
|
|
221
|
+
- **Workflow tools** - Approval systems, task management, automation
|
|
442
222
|
|
|
443
|
-
###
|
|
223
|
+
### Real-Time Applications
|
|
224
|
+
- **Collaboration tools** - Shared editing, presence, chat
|
|
225
|
+
- **Live dashboards** - Stock tickers, sports scores, IoT monitoring
|
|
226
|
+
- **Multiplayer features** - Game state sync, player coordination
|
|
444
227
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
228
|
+
### Modular Systems
|
|
229
|
+
- **Plugin marketplaces** - Let users extend your app
|
|
230
|
+
- **White-label products** - Different features for different customers
|
|
231
|
+
- **Microservices** - Coordinate distributed services
|
|
449
232
|
|
|
450
|
-
**
|
|
451
|
-
```typescript
|
|
452
|
-
await ctx.events.emitAsync('order:processed', order); // Asynchronous
|
|
453
|
-
```
|
|
233
|
+
**Not ideal for:** Public-facing websites (use Next.js), complex routing (use React Router), heavy state management (use Redux).
|
|
454
234
|
|
|
455
235
|
---
|
|
456
236
|
|
|
457
|
-
##
|
|
237
|
+
## Real examples
|
|
458
238
|
|
|
459
|
-
###
|
|
460
|
-
|
|
461
|
-
See [Migration Guide](docs/guides/migration-guide.md) for:
|
|
462
|
-
- Step-by-step migration strategies
|
|
463
|
-
- Real-world examples
|
|
464
|
-
- Common pitfalls and solutions
|
|
465
|
-
- Testing strategies
|
|
466
|
-
|
|
467
|
-
### Tutorial: Build a Task Manager
|
|
468
|
-
|
|
469
|
-
Learn by building a complete app from scratch:
|
|
239
|
+
### CLI Tool (150 lines vs 500+)
|
|
240
|
+
**What you'll see:** Interactive CLI that runs commands, shows output, handles errors. All plugin-based.
|
|
470
241
|
|
|
471
242
|
```bash
|
|
472
|
-
npm
|
|
473
|
-
|
|
243
|
+
# Build a command palette for Git, npm, and Docker:
|
|
244
|
+
cd demo/dev-launcher
|
|
245
|
+
npm install && npm start
|
|
474
246
|
```
|
|
475
247
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
### Example Applications
|
|
479
|
-
|
|
480
|
-
Run focused examples:
|
|
248
|
+
### Real-Time Collaboration (130 lines vs 500+)
|
|
249
|
+
**What you'll see:** Multiple clients syncing state in real-time. No Firebase, no Socket.io boilerplate.
|
|
481
250
|
|
|
482
251
|
```bash
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
npm
|
|
486
|
-
npm run
|
|
487
|
-
npm run
|
|
488
|
-
npm run example # Complete playground
|
|
489
|
-
```
|
|
490
|
-
|
|
491
|
-
## How It Works
|
|
492
|
-
|
|
493
|
-
```
|
|
494
|
-
┌─────────────────────────────────────────────────┐
|
|
495
|
-
│ Your Legacy Application │
|
|
496
|
-
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
497
|
-
│ │ Database │ │ API │ │ Logger │ │
|
|
498
|
-
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
|
|
499
|
-
│ │ │ │ │
|
|
500
|
-
│ └─────────────┴──────────────┘ │
|
|
501
|
-
│ │ │
|
|
502
|
-
│ Host Context (injected) │
|
|
503
|
-
└─────────────────────┬───────────────────────────┘
|
|
504
|
-
│
|
|
505
|
-
┌─────────────────────▼───────────────────────────┐
|
|
506
|
-
│ Skeleton Crew Runtime │
|
|
507
|
-
│ │
|
|
508
|
-
│ ┌──────────────────────────────────────────┐ │
|
|
509
|
-
│ │ Plugin 1 Plugin 2 Plugin 3 │ │
|
|
510
|
-
│ │ (new code) (new code) (new code) │ │
|
|
511
|
-
│ └──────────────────────────────────────────┘ │
|
|
512
|
-
│ │ │ │ │
|
|
513
|
-
│ ┌────▼────┐ ┌───▼────┐ ┌───▼────┐ │
|
|
514
|
-
│ │ Actions │ │ Events │ │Screens │ │
|
|
515
|
-
│ └─────────┘ └────────┘ └────────┘ │
|
|
516
|
-
└─────────────────────────────────────────────────┘
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
**Key insight:** Legacy services flow up through host context. New features are isolated plugins that use those services.
|
|
520
|
-
|
|
521
|
-
## Testing Your Plugins
|
|
522
|
-
|
|
523
|
-
One of the biggest wins: plugins are easy to test.
|
|
524
|
-
|
|
525
|
-
```typescript
|
|
526
|
-
import { describe, it, expect, beforeEach } from 'vitest';
|
|
527
|
-
import { Runtime } from 'skeleton-crew-runtime';
|
|
528
|
-
import { NotificationsPlugin } from './notifications.js';
|
|
529
|
-
|
|
530
|
-
describe('NotificationsPlugin', () => {
|
|
531
|
-
let runtime;
|
|
532
|
-
let mockDb;
|
|
533
|
-
|
|
534
|
-
beforeEach(async () => {
|
|
535
|
-
// Mock your legacy services
|
|
536
|
-
mockDb = {
|
|
537
|
-
insert: vi.fn().mockResolvedValue({ id: 1 })
|
|
538
|
-
};
|
|
539
|
-
|
|
540
|
-
// Create isolated runtime for testing
|
|
541
|
-
runtime = new Runtime({
|
|
542
|
-
hostContext: { db: mockDb }
|
|
543
|
-
});
|
|
544
|
-
|
|
545
|
-
await runtime.initialize();
|
|
546
|
-
runtime.getContext().plugins.registerPlugin(NotificationsPlugin);
|
|
547
|
-
});
|
|
548
|
-
|
|
549
|
-
it('sends notification', async () => {
|
|
550
|
-
const ctx = runtime.getContext();
|
|
551
|
-
|
|
552
|
-
const result = await ctx.actions.runAction('notifications:send', {
|
|
553
|
-
userId: 123,
|
|
554
|
-
message: 'Test'
|
|
555
|
-
});
|
|
556
|
-
|
|
557
|
-
expect(result.success).toBe(true);
|
|
558
|
-
expect(mockDb.insert).toHaveBeenCalledWith('notifications', {
|
|
559
|
-
userId: 123,
|
|
560
|
-
message: 'Test',
|
|
561
|
-
createdAt: expect.any(Date)
|
|
562
|
-
});
|
|
563
|
-
});
|
|
564
|
-
});
|
|
565
|
-
```
|
|
566
|
-
|
|
567
|
-
**Benefits:**
|
|
568
|
-
- No need to set up entire legacy app
|
|
569
|
-
- Mock only what you need
|
|
570
|
-
- Fast, isolated tests
|
|
571
|
-
- Easy to test edge cases
|
|
572
|
-
|
|
573
|
-
## API Quick Reference
|
|
574
|
-
|
|
575
|
-
### Runtime Setup
|
|
576
|
-
|
|
577
|
-
```typescript
|
|
578
|
-
import { Runtime } from 'skeleton-crew-runtime';
|
|
579
|
-
|
|
580
|
-
const runtime = new Runtime({
|
|
581
|
-
hostContext: {
|
|
582
|
-
// Your existing services
|
|
583
|
-
db: yourDatabase,
|
|
584
|
-
logger: yourLogger
|
|
585
|
-
}
|
|
586
|
-
});
|
|
587
|
-
|
|
588
|
-
await runtime.initialize();
|
|
589
|
-
const ctx = runtime.getContext();
|
|
590
|
-
```
|
|
591
|
-
|
|
592
|
-
### Working with Actions
|
|
593
|
-
|
|
594
|
-
```typescript
|
|
595
|
-
// Register
|
|
596
|
-
ctx.actions.registerAction({
|
|
597
|
-
id: 'feature:action',
|
|
598
|
-
timeout: 5000, // optional
|
|
599
|
-
handler: async (params) => {
|
|
600
|
-
const { db } = ctx.host;
|
|
601
|
-
return await db.query(params);
|
|
602
|
-
}
|
|
603
|
-
});
|
|
604
|
-
|
|
605
|
-
// Execute
|
|
606
|
-
const result = await ctx.actions.runAction('feature:action', params);
|
|
607
|
-
```
|
|
608
|
-
|
|
609
|
-
### Working with Events
|
|
610
|
-
|
|
611
|
-
```typescript
|
|
612
|
-
// Subscribe
|
|
613
|
-
ctx.events.on('entity:changed', (data) => {
|
|
614
|
-
console.log('Changed:', data);
|
|
615
|
-
});
|
|
616
|
-
|
|
617
|
-
// Emit (fire-and-forget)
|
|
618
|
-
ctx.events.emit('entity:changed', { id: 123 });
|
|
619
|
-
|
|
620
|
-
// Emit (wait for handlers)
|
|
621
|
-
await ctx.events.emitAsync('entity:changed', { id: 123 });
|
|
252
|
+
# Build a multi-user sync system:
|
|
253
|
+
cd demo/collab-hub
|
|
254
|
+
npm install && npm run build
|
|
255
|
+
npm run server # Terminal 1
|
|
256
|
+
npm run client # Terminal 2-3
|
|
622
257
|
```
|
|
623
258
|
|
|
624
|
-
|
|
259
|
+
**[See all demos →](demo/README.md)**
|
|
625
260
|
|
|
626
|
-
|
|
627
|
-
// Define
|
|
628
|
-
export const MyPlugin = {
|
|
629
|
-
name: 'my-plugin',
|
|
630
|
-
version: '1.0.0',
|
|
631
|
-
setup(ctx) {
|
|
632
|
-
// Register actions, screens, events
|
|
633
|
-
},
|
|
634
|
-
dispose(ctx) {
|
|
635
|
-
// Optional cleanup
|
|
636
|
-
}
|
|
637
|
-
};
|
|
638
|
-
|
|
639
|
-
// Register
|
|
640
|
-
ctx.plugins.registerPlugin(MyPlugin);
|
|
641
|
-
```
|
|
642
|
-
|
|
643
|
-
### Accessing Host Context
|
|
644
|
-
|
|
645
|
-
```typescript
|
|
646
|
-
// In any plugin
|
|
647
|
-
setup(ctx) {
|
|
648
|
-
const { db, logger, cache } = ctx.host;
|
|
649
|
-
|
|
650
|
-
// Use your existing services
|
|
651
|
-
await db.query('SELECT * FROM users');
|
|
652
|
-
logger.info('Plugin initialized');
|
|
653
|
-
}
|
|
654
|
-
```
|
|
655
|
-
|
|
656
|
-
### Introspection
|
|
657
|
-
|
|
658
|
-
```typescript
|
|
659
|
-
// List resources
|
|
660
|
-
const actions = ctx.introspect.listActions();
|
|
661
|
-
const plugins = ctx.introspect.listPlugins();
|
|
662
|
-
|
|
663
|
-
// Get metadata
|
|
664
|
-
const actionMeta = ctx.introspect.getActionDefinition('feature:action');
|
|
665
|
-
const stats = ctx.introspect.getMetadata();
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
**Full API documentation:** [API.md](docs/api/API.md)
|
|
261
|
+
---
|
|
669
262
|
|
|
670
263
|
## FAQ
|
|
671
264
|
|
|
@@ -695,32 +288,4 @@ Yes. The runtime is stable and tested. Start with non-critical features, then ex
|
|
|
695
288
|
|
|
696
289
|
---
|
|
697
290
|
|
|
698
|
-
## Documentation
|
|
699
|
-
|
|
700
|
-
- **[Migration Guide](docs/guides/migration-guide.md)** - Step-by-step migration strategies
|
|
701
|
-
- **[API Reference](docs/api/API.md)** - Complete TypeScript API
|
|
702
|
-
- **[Examples Guide](docs/guides/EXAMPLES_GUIDE.md)** - Learn through examples
|
|
703
|
-
- **[Browser Extensions](docs/use-cases/BROWSER_TOOLS.md)** - Building browser tools
|
|
704
|
-
- **[Project Overview](docs/PROJECT_OVERVIEW.md)** - Architecture deep dive
|
|
705
|
-
|
|
706
|
-
## Get Started
|
|
707
|
-
|
|
708
|
-
```bash
|
|
709
|
-
npm install skeleton-crew-runtime
|
|
710
|
-
```
|
|
711
|
-
|
|
712
|
-
Then follow the [Quick Start](#quick-start-add-your-first-feature) above.
|
|
713
|
-
|
|
714
|
-
---
|
|
715
|
-
|
|
716
|
-
## Contributing
|
|
717
|
-
|
|
718
|
-
We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
719
|
-
|
|
720
|
-
## License
|
|
721
|
-
|
|
722
|
-
MIT
|
|
723
|
-
|
|
724
|
-
---
|
|
725
|
-
|
|
726
291
|
**Built for developers who need to modernize legacy apps without the risk of a full rewrite.**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { RuntimeContext, ScreenDefinition, ActionDefinition, PluginDefinition } from './types.js';
|
|
1
|
+
import type { RuntimeContext, ScreenDefinition, ActionDefinition, PluginDefinition, IntrospectionAPI } from './types.js';
|
|
2
2
|
import type { ScreenRegistry } from './screen-registry.js';
|
|
3
3
|
import type { ActionEngine } from './action-engine.js';
|
|
4
4
|
import type { PluginRegistry } from './plugin-registry.js';
|
|
@@ -16,7 +16,8 @@ export declare class RuntimeContextImpl implements RuntimeContext {
|
|
|
16
16
|
private pluginRegistry;
|
|
17
17
|
private eventBus;
|
|
18
18
|
private runtime;
|
|
19
|
-
private
|
|
19
|
+
private frozenHostContext;
|
|
20
|
+
private introspectionAPI;
|
|
20
21
|
constructor(screenRegistry: ScreenRegistry, actionEngine: ActionEngine, pluginRegistry: PluginRegistry, eventBus: EventBus, runtime: Runtime, hostContext: Record<string, unknown>);
|
|
21
22
|
/**
|
|
22
23
|
* Screens API - exposes Screen Registry operations
|
|
@@ -63,65 +64,23 @@ export declare class RuntimeContextImpl implements RuntimeContext {
|
|
|
63
64
|
* Host context - readonly access to injected host services
|
|
64
65
|
* Requirements: 1.2, 1.3, 1.4
|
|
65
66
|
*
|
|
66
|
-
* Returns a frozen shallow copy of the host context to prevent mutation.
|
|
67
|
+
* Returns a cached frozen shallow copy of the host context to prevent mutation.
|
|
67
68
|
* This ensures plugins can access host services but cannot modify them.
|
|
69
|
+
* The frozen copy is cached to avoid memory leaks from repeated access.
|
|
68
70
|
*/
|
|
69
71
|
get host(): Readonly<Record<string, unknown>>;
|
|
70
72
|
/**
|
|
71
73
|
* Introspection API - query runtime metadata
|
|
72
74
|
* Requirements: 3.1, 4.1, 5.1, 6.1
|
|
75
|
+
*
|
|
76
|
+
* Returns a cached introspection API object to prevent memory leaks
|
|
77
|
+
* from repeated access.
|
|
73
78
|
*/
|
|
74
|
-
get introspect():
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Get action metadata by ID (excludes handler function)
|
|
82
|
-
* Requirements: 3.2, 3.3, 3.4, 3.5
|
|
83
|
-
*/
|
|
84
|
-
getActionDefinition: (id: string) => Readonly<{
|
|
85
|
-
id: string;
|
|
86
|
-
timeout: number | undefined;
|
|
87
|
-
}> | null;
|
|
88
|
-
/**
|
|
89
|
-
* List all registered plugin names
|
|
90
|
-
* Requirements: 4.1
|
|
91
|
-
*/
|
|
92
|
-
listPlugins: () => string[];
|
|
93
|
-
/**
|
|
94
|
-
* Get plugin metadata by name (excludes setup/dispose functions)
|
|
95
|
-
* Requirements: 4.2, 4.3, 4.4, 4.5
|
|
96
|
-
*/
|
|
97
|
-
getPluginDefinition: (name: string) => Readonly<{
|
|
98
|
-
name: string;
|
|
99
|
-
version: string;
|
|
100
|
-
}> | null;
|
|
101
|
-
/**
|
|
102
|
-
* List all registered screen IDs
|
|
103
|
-
* Requirements: 5.1
|
|
104
|
-
*/
|
|
105
|
-
listScreens: () => string[];
|
|
106
|
-
/**
|
|
107
|
-
* Get screen definition by ID (includes all properties)
|
|
108
|
-
* Requirements: 5.2, 5.3, 5.4, 5.5
|
|
109
|
-
*/
|
|
110
|
-
getScreenDefinition: (id: string) => Readonly<{
|
|
111
|
-
id: string;
|
|
112
|
-
title: string;
|
|
113
|
-
component: string;
|
|
114
|
-
}> | null;
|
|
115
|
-
/**
|
|
116
|
-
* Get runtime metadata with statistics
|
|
117
|
-
* Requirements: 6.1, 6.2, 6.3, 6.4, 6.5
|
|
118
|
-
*/
|
|
119
|
-
getMetadata: () => Readonly<{
|
|
120
|
-
runtimeVersion: string;
|
|
121
|
-
totalActions: number;
|
|
122
|
-
totalPlugins: number;
|
|
123
|
-
totalScreens: number;
|
|
124
|
-
}>;
|
|
125
|
-
};
|
|
79
|
+
get introspect(): IntrospectionAPI;
|
|
80
|
+
/**
|
|
81
|
+
* Creates the introspection API object.
|
|
82
|
+
* Called once during construction and cached.
|
|
83
|
+
*/
|
|
84
|
+
private createIntrospectionAPI;
|
|
126
85
|
}
|
|
127
86
|
//# sourceMappingURL=runtime-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-context.d.ts","sourceRoot":"","sources":["../src/runtime-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime-context.d.ts","sourceRoot":"","sources":["../src/runtime-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACzH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAkC1C;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,cAAc;IACvD,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,iBAAiB,CAAoC;IAC7D,OAAO,CAAC,gBAAgB,CAAmB;gBAGzC,cAAc,EAAE,cAAc,EAC9B,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAgBtC;;;OAGG;IACH,IAAI,OAAO;iCAEkB,gBAAgB,KAAG,CAAC,MAAM,IAAI,CAAC;wBAGxC,MAAM,KAAG,gBAAgB,GAAG,IAAI;6BAG7B,gBAAgB,EAAE;MAIxC;IAED;;;OAGG;IACH,IAAI,OAAO;yBAEU,CAAC,YAAY,CAAC,oBAAoB,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,KAAG,CAAC,MAAM,IAAI,CAAC;oBAG5E,CAAC,YAAY,CAAC,gBAAgB,MAAM,WAAW,CAAC,KAAG,OAAO,CAAC,CAAC,CAAC;MAI5E;IAED;;;OAGG;IACH,IAAI,OAAO;iCAEkB,gBAAgB,KAAG,IAAI;0BAG9B,MAAM,KAAG,gBAAgB,GAAG,IAAI;6BAG/B,gBAAgB,EAAE;qCAGV,MAAM,EAAE;MAItC;IAED;;;OAGG;IACH,IAAI,MAAM;sBAEQ,MAAM,SAAS,OAAO,KAAG,IAAI;2BAGxB,MAAM,SAAS,OAAO,KAAG,OAAO,CAAC,IAAI,CAAC;oBAG7C,MAAM,WAAW,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC;MAItE;IAED;;;OAGG;IACH,UAAU,IAAI,OAAO;IAIrB;;;;;;;OAOG;IACH,IAAI,IAAI,IAAI,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAE5C;IAED;;;;;;OAMG;IACH,IAAI,UAAU,IAAI,gBAAgB,CAEjC;IAED;;;OAGG;IACH,OAAO,CAAC,sBAAsB;CAkG/B"}
|
package/dist/runtime-context.js
CHANGED
|
@@ -37,14 +37,20 @@ export class RuntimeContextImpl {
|
|
|
37
37
|
pluginRegistry;
|
|
38
38
|
eventBus;
|
|
39
39
|
runtime;
|
|
40
|
-
|
|
40
|
+
frozenHostContext;
|
|
41
|
+
introspectionAPI;
|
|
41
42
|
constructor(screenRegistry, actionEngine, pluginRegistry, eventBus, runtime, hostContext) {
|
|
42
43
|
this.screenRegistry = screenRegistry;
|
|
43
44
|
this.actionEngine = actionEngine;
|
|
44
45
|
this.pluginRegistry = pluginRegistry;
|
|
45
46
|
this.eventBus = eventBus;
|
|
46
47
|
this.runtime = runtime;
|
|
47
|
-
|
|
48
|
+
// Cache the frozen copy to avoid creating new objects on every access
|
|
49
|
+
// This prevents memory leaks when host context is accessed repeatedly
|
|
50
|
+
this.frozenHostContext = Object.freeze({ ...hostContext });
|
|
51
|
+
// Cache the introspection API to avoid creating new objects on every access
|
|
52
|
+
// This prevents memory leaks when introspection is used repeatedly
|
|
53
|
+
this.introspectionAPI = this.createIntrospectionAPI();
|
|
48
54
|
}
|
|
49
55
|
/**
|
|
50
56
|
* Screens API - exposes Screen Registry operations
|
|
@@ -125,17 +131,28 @@ export class RuntimeContextImpl {
|
|
|
125
131
|
* Host context - readonly access to injected host services
|
|
126
132
|
* Requirements: 1.2, 1.3, 1.4
|
|
127
133
|
*
|
|
128
|
-
* Returns a frozen shallow copy of the host context to prevent mutation.
|
|
134
|
+
* Returns a cached frozen shallow copy of the host context to prevent mutation.
|
|
129
135
|
* This ensures plugins can access host services but cannot modify them.
|
|
136
|
+
* The frozen copy is cached to avoid memory leaks from repeated access.
|
|
130
137
|
*/
|
|
131
138
|
get host() {
|
|
132
|
-
return
|
|
139
|
+
return this.frozenHostContext;
|
|
133
140
|
}
|
|
134
141
|
/**
|
|
135
142
|
* Introspection API - query runtime metadata
|
|
136
143
|
* Requirements: 3.1, 4.1, 5.1, 6.1
|
|
144
|
+
*
|
|
145
|
+
* Returns a cached introspection API object to prevent memory leaks
|
|
146
|
+
* from repeated access.
|
|
137
147
|
*/
|
|
138
148
|
get introspect() {
|
|
149
|
+
return this.introspectionAPI;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Creates the introspection API object.
|
|
153
|
+
* Called once during construction and cached.
|
|
154
|
+
*/
|
|
155
|
+
createIntrospectionAPI() {
|
|
139
156
|
return {
|
|
140
157
|
/**
|
|
141
158
|
* List all registered action IDs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-context.js","sourceRoot":"","sources":["../src/runtime-context.ts"],"names":[],"mappings":"AAOA;;;;;;;;GAQG;AACH,SAAS,UAAU,CAAI,GAAM;IAC3B,6CAA6C;IAC7C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAEnB,gDAAgD;IAChD,MAAM,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QAC7C,MAAM,KAAK,GAAI,GAAW,CAAC,IAAI,CAAC,CAAC;QAEjC,mCAAmC;QACnC,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;YAChC,OAAO;QACT,CAAC;QAED,gDAAgD;QAChD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAClE,uEAAuE;YACvE,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAkB,CAAC;AAC5B,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,kBAAkB;IACrB,cAAc,CAAiB;IAC/B,YAAY,CAAe;IAC3B,cAAc,CAAiB;IAC/B,QAAQ,CAAW;IACnB,OAAO,CAAU;IACjB,
|
|
1
|
+
{"version":3,"file":"runtime-context.js","sourceRoot":"","sources":["../src/runtime-context.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAU,MAAM,YAAY,CAAC;AACvG,OAAO,EAAiB,YAAY,EAAE,MAAM,YAAY,CAAC;AAQzD;;;;;GAKG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAA4C;IACzD,OAAO,CAAC,WAAW,CAA0B;IAE7C;;;;;;;;OAQG;gBACS,OAAO,CAAC,EAAE,cAAc;IAMpC;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;;;;;OAMG;IACH,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAO9C;;;;;;;;;OASG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiEjC;;;;;;;OAOG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAU,MAAM,YAAY,CAAC;AACvG,OAAO,EAAiB,YAAY,EAAE,MAAM,YAAY,CAAC;AAQzD;;;;;GAKG;AACH,qBAAa,OAAO;IAClB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,EAAE,CAAY;IACtB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAA4C;IACzD,OAAO,CAAC,WAAW,CAA0B;IAE7C;;;;;;;;OAQG;gBACS,OAAO,CAAC,EAAE,cAAc;IAMpC;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;;;;;OAMG;IACH,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAO9C;;;;;;;;;OASG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiEjC;;;;;;;OAOG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAwC/B;;;;;;;OAOG;IACH,UAAU,IAAI,cAAc;IAO5B;;;;;;OAMG;IACH,aAAa,IAAI,OAAO;IAIxB;;;;;;OAMG;IACH,QAAQ,IAAI,YAAY;IAIxB;;;;;;;;;OASG;IACH,aAAa,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI;IAIzC;;;;;;;OAOG;IACH,aAAa,IAAI,UAAU,GAAG,IAAI;IAIlC;;;;;;;;;OASG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAYxC"}
|
package/dist/runtime.js
CHANGED
|
@@ -170,7 +170,9 @@ export class Runtime {
|
|
|
170
170
|
this.actions.clear();
|
|
171
171
|
this.events.clear();
|
|
172
172
|
this.plugins.clear();
|
|
173
|
-
// 4.
|
|
173
|
+
// 4. Clear context reference in ActionEngine to break circular reference
|
|
174
|
+
this.actions.setContext(null);
|
|
175
|
+
// 5. Set initialized flag to false (Requirement 4.5)
|
|
174
176
|
this.initialized = false;
|
|
175
177
|
// Set state to Shutdown (Requirement 16.4)
|
|
176
178
|
this.state = RuntimeState.Shutdown;
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,53 +1,70 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skeleton-crew-runtime",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "A minimal
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "A minimal plugin runtime for building modular JavaScript applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"files": [
|
|
9
9
|
"dist/",
|
|
10
10
|
"LICENSE",
|
|
11
|
-
"README.md"
|
|
12
|
-
"package.json"
|
|
13
|
-
],
|
|
14
|
-
"exclude": [
|
|
15
|
-
"dist-example/"
|
|
11
|
+
"README.md"
|
|
16
12
|
],
|
|
17
13
|
"scripts": {
|
|
18
|
-
"build": "
|
|
19
|
-
"build:examples": "tsc -p tsconfig.examples.json",
|
|
14
|
+
"build": "rimraf dist && tsc",
|
|
15
|
+
"build:examples": "rimraf dist-examples && tsc -p tsconfig.examples.json",
|
|
20
16
|
"test": "vitest run",
|
|
21
17
|
"test:watch": "vitest",
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"example:
|
|
25
|
-
"example:
|
|
26
|
-
"example:
|
|
27
|
-
"example:
|
|
28
|
-
"
|
|
29
|
-
"tutorial:
|
|
30
|
-
"tutorial:
|
|
31
|
-
"tutorial:
|
|
32
|
-
"tutorial:
|
|
18
|
+
"prepublishOnly": "npm run build && npm test",
|
|
19
|
+
"examples": "npm run build:examples && node dist-example/examples/playground/index.js",
|
|
20
|
+
"example:01": "npm run build:examples && node dist-example/examples/basics/01-plugin-system/index.js",
|
|
21
|
+
"example:02": "npm run build:examples && node dist-example/examples/basics/02-screen-registry/index.js",
|
|
22
|
+
"example:03": "npm run build:examples && node dist-example/examples/basics/03-action-engine/index.js",
|
|
23
|
+
"example:04": "npm run build:examples && node dist-example/examples/basics/04-event-bus/index.js",
|
|
24
|
+
"example:05": "npm run build:examples && node dist-example/examples/basics/05-runtime-context/index.js",
|
|
25
|
+
"tutorial:01": "npm run build:examples && node dist-example/examples/tutorial/01-basic-task-plugin/index.js",
|
|
26
|
+
"tutorial:02": "npm run build:examples && node dist-example/examples/tutorial/02-multiple-plugins/index.js",
|
|
27
|
+
"tutorial:03": "npm run build:examples && node dist-example/examples/tutorial/03-event-communication/index.js",
|
|
28
|
+
"tutorial:04": "npm run build:examples && vite dist-example/examples/tutorial/04-ui-provider-swap",
|
|
29
|
+
"tutorial:05": "npm run build:examples && node dist-example/examples/tutorial/05-custom-plugin/index.js"
|
|
33
30
|
},
|
|
34
31
|
"keywords": [
|
|
35
32
|
"runtime",
|
|
36
33
|
"plugin",
|
|
34
|
+
"plugin-system",
|
|
37
35
|
"framework",
|
|
38
36
|
"internal-tools",
|
|
39
37
|
"modular",
|
|
40
|
-
"ui-agnostic"
|
|
38
|
+
"ui-agnostic",
|
|
39
|
+
"event-driven",
|
|
40
|
+
"browser-extension",
|
|
41
|
+
"cli-tools",
|
|
42
|
+
"typescript"
|
|
41
43
|
],
|
|
42
|
-
"author":
|
|
43
|
-
|
|
44
|
+
"author": {
|
|
45
|
+
"name": "skcrew",
|
|
46
|
+
"email": "skeletoncrewruntime@gmail.com"
|
|
47
|
+
},
|
|
44
48
|
"license": "MIT",
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "https://github.com/skcrew/runtime.git"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/skcrew/runtime#readme",
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/skcrew/runtime/issues"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=18.0.0",
|
|
59
|
+
"npm": ">=8.0.0"
|
|
60
|
+
},
|
|
45
61
|
"devDependencies": {
|
|
46
62
|
"@types/node": "^20.10.0",
|
|
47
|
-
"@vitest/coverage-v8": "^
|
|
63
|
+
"@vitest/coverage-v8": "^4.0.15",
|
|
48
64
|
"fast-check": "^3.15.0",
|
|
65
|
+
"rimraf": "^6.1.2",
|
|
49
66
|
"typescript": "^5.3.3",
|
|
50
|
-
"vitest": "^
|
|
67
|
+
"vitest": "^4.0.15"
|
|
51
68
|
},
|
|
52
69
|
"optionalDependencies": {
|
|
53
70
|
"@types/react": "^18.2.0",
|
|
@@ -55,6 +72,6 @@
|
|
|
55
72
|
"@vitejs/plugin-react": "^4.2.0",
|
|
56
73
|
"react": "^18.2.0",
|
|
57
74
|
"react-dom": "^18.2.0",
|
|
58
|
-
"vite": "^
|
|
75
|
+
"vite": "^7.2.6"
|
|
59
76
|
}
|
|
60
77
|
}
|