-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathapp-framework.ts
More file actions
120 lines (100 loc) · 2.77 KB
/
Copy pathapp-framework.ts
File metadata and controls
120 lines (100 loc) · 2.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
export interface KernelContext {
invocation_id: string;
}
export interface KernelAction {
name: string;
handler: (context: KernelContext, payload?: any) => Promise<any>;
}
export interface KernelJson {
apps: KernelAppJson[];
}
export interface KernelAppJson {
name: string;
actions: KernelActionJson[];
}
export interface KernelActionJson {
name: string;
}
export class KernelApp {
name: string;
actions: Map<string, KernelAction> = new Map();
constructor(name: string) {
this.name = name;
// Register this app in the global registry
appRegistry.registerApp(this);
}
/**
* Define an action
*/
action<T, R>(
name: string,
handler: ((context: KernelContext) => Promise<R>) | ((context: KernelContext, payload?: T) => Promise<R>),
) {
let actionHandler: (context: KernelContext, payload?: T) => Promise<R>;
// Create a handler that accepts context and payload, adapting if needed
if (handler.length === 0) {
// Handlers with no arguments are not supported
throw new Error('Action handlers must accept at least the context parameter');
} else if (handler.length === 1) {
// Handler takes context only
const contextOnlyHandler = handler as (context: KernelContext) => Promise<R>;
actionHandler = async (context: KernelContext, _payload?: T) => contextOnlyHandler(context);
} else {
// Handler takes both context and payload
const twoArgHandler = handler as (context: KernelContext, payload?: T) => Promise<R>;
actionHandler = twoArgHandler;
}
// Register the action
this.actions.set(name, {
name,
handler: actionHandler,
});
return actionHandler;
}
/**
* Get all actions for this app
*/
getActions(): KernelAction[] {
return Array.from(this.actions.values());
}
/**
* Get an action by name
*/
getAction(name: string): KernelAction | undefined {
return this.actions.get(name);
}
/**
* Export app information without handlers
*/
toJSON(): KernelAppJson {
return {
name: this.name,
actions: this.getActions().map((action) => ({
name: action.name,
})),
};
}
}
// Registry for storing all Kernel apps
class KernelAppRegistry {
private apps: Map<string, KernelApp> = new Map();
registerApp(app: KernelApp): void {
this.apps.set(app.name, app);
}
getApps(): KernelApp[] {
return Array.from(this.apps.values());
}
getAppByName(name: string): KernelApp | undefined {
return this.apps.get(name);
}
export(): KernelJson {
return {
apps: this.getApps().map((app) => app.toJSON()),
};
}
exportJSON(): string {
return JSON.stringify(this.export(), null, 2);
}
}
// Create a singleton registry for apps
export const appRegistry = new KernelAppRegistry();