@@ -20,6 +20,8 @@ import { CommandKitEventsChannel } from './events/CommandKitEventsChannel';
20
20
import { isRuntimePlugin } from './plugins' ;
21
21
import { generateTypesPackage } from './utils/types-package' ;
22
22
import { Logger } from './logger/Logger' ;
23
+ import { GenericFunction } from './context/async-context' ;
24
+ import { AsyncFunction } from './cache' ;
23
25
24
26
export interface CommandKitConfiguration {
25
27
defaultLocale : Locale ;
@@ -29,6 +31,49 @@ export interface CommandKitConfiguration {
29
31
// @ts -ignore
30
32
export let commandkit : CommandKit ;
31
33
34
+ export type BootstrapFunction =
35
+ | GenericFunction < [ CommandKit ] >
36
+ | AsyncFunction < [ CommandKit ] > ;
37
+
38
+ const bootstrapHooks = new Set < BootstrapFunction > ( ) ;
39
+ const onApplicationBootstrapHooks = new Set < BootstrapFunction > ( ) ;
40
+
41
+ /**
42
+ * Registers a bootstrap hook that will be called when the CommandKit instance is created.
43
+ * This is useful for plugins that need to run some code after the CommandKit instance is fully initialized.
44
+ * Note that not all commandkit dependiencs are available at this point. It is recommended to use the `onApplicationBootstrap` hook instead,
45
+ * if you need access to the commandkit dependencies.
46
+ * @param fn The bootstrap function to register.
47
+ * @example ```ts
48
+ * import { onBootstrap } from 'commandkit';
49
+ *
50
+ * onBootstrap(async (commandkit) => {
51
+ * // Do something with the commandkit instance
52
+ * })
53
+ * ```
54
+ */
55
+ export function onBootstrap < F extends BootstrapFunction > ( fn : F ) : void {
56
+ bootstrapHooks . add ( fn ) ;
57
+ }
58
+
59
+ /**
60
+ * Registers a bootstrap hook that will be called when the CommandKit instance is created.
61
+ * This is useful for plugins that need to run some code after the CommandKit instance is fully initialized.
62
+ * @param fn The bootstrap function to register.
63
+ * @example ```ts
64
+ * import { onApplicationBootstrap } from 'commandkit';
65
+ *
66
+ * onApplicationBootstrap(async (commandkit) => {
67
+ * // Do something with the commandkit instance
68
+ * })
69
+ * ```
70
+ */
71
+ export function onApplicationBootstrap < F extends BootstrapFunction > (
72
+ fn : F ,
73
+ ) : void {
74
+ onApplicationBootstrapHooks . add ( fn ) ;
75
+ }
76
+
32
77
export class CommandKit extends EventEmitter {
33
78
#started = false ;
34
79
public eventInterceptor ! : EventInterceptor ;
@@ -90,6 +135,37 @@ export class CommandKit extends EventEmitter {
90
135
91
136
// @ts -ignore
92
137
commandkit = CommandKit . instance ;
138
+
139
+ this . #bootstrapHooks( ) ;
140
+ }
141
+
142
+ async #bootstrapHooks( ) {
143
+ for ( const hook of bootstrapHooks ) {
144
+ try {
145
+ await hook ( this ) ;
146
+ } catch ( e ) {
147
+ Logger . error ( 'Error while executing bootstrap hook: ' , e ) ;
148
+ } finally {
149
+ bootstrapHooks . delete ( hook ) ;
150
+ }
151
+ }
152
+
153
+ // force clear just in case we missed something
154
+ bootstrapHooks . clear ( ) ;
155
+ }
156
+
157
+ async #applicationBootstrapHooks( ) {
158
+ for ( const hook of onApplicationBootstrapHooks ) {
159
+ try {
160
+ await hook ( this ) ;
161
+ } catch ( e ) {
162
+ Logger . error ( 'Error while executing application bootstrap hook: ' , e ) ;
163
+ } finally {
164
+ onApplicationBootstrapHooks . delete ( hook ) ;
165
+ }
166
+ }
167
+ // force clear just in case we missed something
168
+ onApplicationBootstrapHooks . clear ( ) ;
93
169
}
94
170
95
171
/**
@@ -151,6 +227,8 @@ export class CommandKit extends EventEmitter {
151
227
}
152
228
153
229
this . #started = true ;
230
+
231
+ await this . #applicationBootstrapHooks( ) ;
154
232
}
155
233
156
234
/**
0 commit comments