@grupodiariodaregiao/bunstone 0.4.2 → 0.4.3

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/dist/index.d.ts CHANGED
@@ -55,6 +55,7 @@ export * from "./lib/jwt";
55
55
  export * from "./lib/jwt/jwt-module";
56
56
  export { JwtService } from "./lib/jwt/jwt.service";
57
57
  export * from "./lib/module";
58
+ export * from "./lib/on-module";
58
59
  export * from "./lib/openapi";
59
60
  export * from "./lib/render";
60
61
  export * from "./lib/types/options";
package/dist/index.js CHANGED
@@ -116627,6 +116627,14 @@ function Head2(pathname = "") {
116627
116627
  return HttpMethodDecorator("HEAD", pathname);
116628
116628
  }
116629
116629
 
116630
+ // lib/on-module/on-module-destroy.ts
116631
+ class OnModuleDestroy {
116632
+ }
116633
+
116634
+ // lib/on-module/on-module-init.ts
116635
+ class OnModuleInit {
116636
+ }
116637
+
116630
116638
  // lib/openapi.ts
116631
116639
  var import_reflect_metadata13 = __toESM(require_Reflect(), 1);
116632
116640
  var API_TAGS_METADATA = "dip:openapi:tags";
@@ -117086,12 +117094,22 @@ class AppStartup {
117086
117094
  static elysia = new Elysia;
117087
117095
  static logger = new Logger(AppStartup.name);
117088
117096
  static registeredSagas = new WeakSet;
117097
+ static initializedModuleHooks = new WeakSet;
117098
+ static destroyedModuleHooks = new WeakSet;
117099
+ static destroyPromise = null;
117100
+ static hasBeenDestroyed = false;
117101
+ static rootModule;
117089
117102
  static viewBundles = new Map;
117090
117103
  static globalRateLimitConfig;
117091
117104
  static rateLimitService = new RateLimitService;
117092
117105
  static async create(module, options) {
117093
117106
  try {
117094
117107
  AppStartup.elysia = new Elysia;
117108
+ AppStartup.rootModule = module;
117109
+ AppStartup.initializedModuleHooks = new WeakSet;
117110
+ AppStartup.destroyedModuleHooks = new WeakSet;
117111
+ AppStartup.destroyPromise = null;
117112
+ AppStartup.hasBeenDestroyed = false;
117095
117113
  const publicExists = await Bun.file("public").exists();
117096
117114
  if (!publicExists)
117097
117115
  await mkdir("./public", { recursive: true });
@@ -117144,6 +117162,9 @@ class AppStartup {
117144
117162
  message: error48 instanceof Error ? error48.message : "Internal Server Error"
117145
117163
  };
117146
117164
  });
117165
+ AppStartup.elysia.onStop(async () => {
117166
+ await AppStartup.executeDestroyLifecycle();
117167
+ });
117147
117168
  if (options?.cors) {
117148
117169
  AppStartup.elysia.use(cors(options.cors));
117149
117170
  }
@@ -117181,7 +117202,7 @@ class AppStartup {
117181
117202
  }));
117182
117203
  }
117183
117204
  AppStartup.globalRateLimitConfig = options?.rateLimit;
117184
- AppStartup.registerModules(module);
117205
+ await AppStartup.registerModules(module);
117185
117206
  return {
117186
117207
  listen: AppStartup.listen,
117187
117208
  getElysia: () => AppStartup.elysia
@@ -117293,6 +117314,28 @@ if (document.readyState === 'loading') {
117293
117314
  AppStartup.logger.log(`App is running at http://localhost:${port}`);
117294
117315
  AppStartup.elysia.listen(port);
117295
117316
  }
117317
+ static async executeDestroyLifecycle() {
117318
+ if (!AppStartup.rootModule) {
117319
+ return;
117320
+ }
117321
+ if (AppStartup.hasBeenDestroyed) {
117322
+ return;
117323
+ }
117324
+ if (AppStartup.destroyPromise) {
117325
+ await AppStartup.destroyPromise;
117326
+ return;
117327
+ }
117328
+ AppStartup.destroyPromise = (async () => {
117329
+ await AppStartup.destroyModules(AppStartup.rootModule);
117330
+ AppStartup.hasBeenDestroyed = true;
117331
+ })().catch((error48) => {
117332
+ AppStartup.logger.error(`Error while executing OnModuleDestroy hooks: ${error48?.message || error48}`);
117333
+ throw error48;
117334
+ }).finally(() => {
117335
+ AppStartup.destroyPromise = null;
117336
+ });
117337
+ await AppStartup.destroyPromise;
117338
+ }
117296
117339
  static async executeControllerMethod(context, controller, method) {
117297
117340
  const args = await processParameters(context, controller, method);
117298
117341
  const result = await controller[method](...args);
@@ -117336,7 +117379,7 @@ if (document.readyState === 'loading') {
117336
117379
  }
117337
117380
  return result;
117338
117381
  }
117339
- static registerModules(module) {
117382
+ static async registerModules(module) {
117340
117383
  const isGlobal = Reflect.getMetadata("dip:module:global", module);
117341
117384
  if (isGlobal) {
117342
117385
  const injectables = Reflect.getMetadata("dip:injectables", module);
@@ -117355,7 +117398,47 @@ if (document.readyState === 'loading') {
117355
117398
  AppStartup.registerRabbitMQConsumers(module);
117356
117399
  const modules = Reflect.getMetadata("dip:modules", module) || [];
117357
117400
  for (const mod of modules) {
117358
- AppStartup.registerModules(mod);
117401
+ await AppStartup.registerModules(mod);
117402
+ }
117403
+ await AppStartup.executeOnModuleInit(module);
117404
+ }
117405
+ static async destroyModules(module) {
117406
+ const modules = Reflect.getMetadata("dip:modules", module) || [];
117407
+ for (const mod of modules) {
117408
+ await AppStartup.destroyModules(mod);
117409
+ }
117410
+ await AppStartup.executeOnModuleDestroy(module);
117411
+ }
117412
+ static async executeOnModuleInit(module) {
117413
+ const injectables = Reflect.getMetadata("dip:injectables", module);
117414
+ if (!injectables) {
117415
+ return;
117416
+ }
117417
+ for (const provider of injectables.values()) {
117418
+ if (!(provider instanceof OnModuleInit)) {
117419
+ continue;
117420
+ }
117421
+ if (AppStartup.initializedModuleHooks.has(provider)) {
117422
+ continue;
117423
+ }
117424
+ AppStartup.initializedModuleHooks.add(provider);
117425
+ await provider.onModuleInit();
117426
+ }
117427
+ }
117428
+ static async executeOnModuleDestroy(module) {
117429
+ const injectables = Reflect.getMetadata("dip:injectables", module);
117430
+ if (!injectables) {
117431
+ return;
117432
+ }
117433
+ for (const provider of injectables.values()) {
117434
+ if (!(provider instanceof OnModuleDestroy)) {
117435
+ continue;
117436
+ }
117437
+ if (AppStartup.destroyedModuleHooks.has(provider)) {
117438
+ continue;
117439
+ }
117440
+ AppStartup.destroyedModuleHooks.add(provider);
117441
+ await provider.onModuleDestroy();
117359
117442
  }
117360
117443
  }
117361
117444
  static registerRoutes(module) {
@@ -119976,6 +120059,8 @@ export {
119976
120059
  ParamType,
119977
120060
  Param,
119978
120061
  Options,
120062
+ OnModuleInit,
120063
+ OnModuleDestroy,
119979
120064
  OkResponse,
119980
120065
  NotFoundException,
119981
120066
  NoContentResponse,
@@ -9,6 +9,11 @@ export declare class AppStartup {
9
9
  private static elysia;
10
10
  private static readonly logger;
11
11
  private static readonly registeredSagas;
12
+ private static initializedModuleHooks;
13
+ private static destroyedModuleHooks;
14
+ private static destroyPromise;
15
+ private static hasBeenDestroyed;
16
+ private static rootModule;
12
17
  private static readonly viewBundles;
13
18
  private static globalRateLimitConfig;
14
19
  private static rateLimitService;
@@ -67,8 +72,12 @@ export declare class AppStartup {
67
72
  * @param port The port number to listen on.
68
73
  */
69
74
  static listen(port: number): void;
75
+ private static executeDestroyLifecycle;
70
76
  private static executeControllerMethod;
71
77
  private static registerModules;
78
+ private static destroyModules;
79
+ private static executeOnModuleInit;
80
+ private static executeOnModuleDestroy;
72
81
  private static registerRoutes;
73
82
  /**
74
83
  * Builds effective rate limit configuration by merging global config with method config
@@ -0,0 +1,2 @@
1
+ export * from "./on-module-destroy";
2
+ export * from "./on-module-init";
@@ -0,0 +1,3 @@
1
+ export declare abstract class OnModuleDestroy {
2
+ abstract onModuleDestroy(): Promise<void> | void;
3
+ }
@@ -0,0 +1,3 @@
1
+ export declare abstract class OnModuleInit {
2
+ abstract onModuleInit(): Promise<void> | void;
3
+ }
@@ -28,6 +28,8 @@ import { ConfigurationError } from "./errors";
28
28
  import { HttpException } from "./http-exceptions";
29
29
  import { HTTP_HEADERS_METADATA } from "./http-methods";
30
30
  import { ParamType, processParameters } from "./http-params";
31
+ import { OnModuleDestroy } from "./on-module/on-module-destroy";
32
+ import { OnModuleInit } from "./on-module/on-module-init";
31
33
  import {
32
34
  API_HEADERS_METADATA,
33
35
  API_OPERATION_METADATA,
@@ -57,6 +59,11 @@ export class AppStartup {
57
59
  private static elysia: Elysia = new Elysia();
58
60
  private static readonly logger = new Logger(AppStartup.name);
59
61
  private static readonly registeredSagas = new WeakSet<any>();
62
+ private static initializedModuleHooks = new WeakSet<OnModuleInit>();
63
+ private static destroyedModuleHooks = new WeakSet<OnModuleDestroy>();
64
+ private static destroyPromise: Promise<void> | null = null;
65
+ private static hasBeenDestroyed = false;
66
+ private static rootModule: any;
60
67
  private static readonly viewBundles = new Map<string, string>();
61
68
  private static globalRateLimitConfig: RateLimitGlobalConfig | undefined;
62
69
  private static rateLimitService: RateLimitService = new RateLimitService();
@@ -71,6 +78,11 @@ export class AppStartup {
71
78
  static async create(module: any, options?: Options) {
72
79
  try {
73
80
  AppStartup.elysia = new Elysia(); // Reset for each creation
81
+ AppStartup.rootModule = module;
82
+ AppStartup.initializedModuleHooks = new WeakSet<OnModuleInit>();
83
+ AppStartup.destroyedModuleHooks = new WeakSet<OnModuleDestroy>();
84
+ AppStartup.destroyPromise = null;
85
+ AppStartup.hasBeenDestroyed = false;
74
86
 
75
87
  const publicExists = await Bun.file("public").exists();
76
88
  // Ensure public directory exists before static plugin uses it
@@ -149,6 +161,10 @@ export class AppStartup {
149
161
  };
150
162
  });
151
163
 
164
+ AppStartup.elysia.onStop(async () => {
165
+ await AppStartup.executeDestroyLifecycle();
166
+ });
167
+
152
168
  if (options?.cors) {
153
169
  AppStartup.elysia.use(cors(options.cors));
154
170
  }
@@ -202,7 +218,7 @@ export class AppStartup {
202
218
  // Store global rate limit config
203
219
  AppStartup.globalRateLimitConfig = options?.rateLimit;
204
220
 
205
- AppStartup.registerModules(module);
221
+ await AppStartup.registerModules(module);
206
222
  return {
207
223
  /**
208
224
  * Starts the server on the specified port.
@@ -352,6 +368,37 @@ if (document.readyState === 'loading') {
352
368
  AppStartup.elysia.listen(port);
353
369
  }
354
370
 
371
+ private static async executeDestroyLifecycle() {
372
+ if (!AppStartup.rootModule) {
373
+ return;
374
+ }
375
+
376
+ if (AppStartup.hasBeenDestroyed) {
377
+ return;
378
+ }
379
+
380
+ if (AppStartup.destroyPromise) {
381
+ await AppStartup.destroyPromise;
382
+ return;
383
+ }
384
+
385
+ AppStartup.destroyPromise = (async () => {
386
+ await AppStartup.destroyModules(AppStartup.rootModule);
387
+ AppStartup.hasBeenDestroyed = true;
388
+ })()
389
+ .catch((error) => {
390
+ AppStartup.logger.error(
391
+ `Error while executing OnModuleDestroy hooks: ${error?.message || error}`,
392
+ );
393
+ throw error;
394
+ })
395
+ .finally(() => {
396
+ AppStartup.destroyPromise = null;
397
+ });
398
+
399
+ await AppStartup.destroyPromise;
400
+ }
401
+
355
402
  private static async executeControllerMethod(
356
403
  context: any,
357
404
  controller: any,
@@ -436,7 +483,7 @@ if (document.readyState === 'loading') {
436
483
  return result;
437
484
  }
438
485
 
439
- private static registerModules(module: any) {
486
+ private static async registerModules(module: any) {
440
487
  const isGlobal = Reflect.getMetadata("dip:module:global", module);
441
488
  if (isGlobal) {
442
489
  const injectables: Map<any, any> = Reflect.getMetadata(
@@ -461,7 +508,67 @@ if (document.readyState === 'loading') {
461
508
  const modules = Reflect.getMetadata("dip:modules", module) || [];
462
509
 
463
510
  for (const mod of modules) {
464
- AppStartup.registerModules(mod);
511
+ await AppStartup.registerModules(mod);
512
+ }
513
+
514
+ await AppStartup.executeOnModuleInit(module);
515
+ }
516
+
517
+ private static async destroyModules(module: any) {
518
+ const modules = Reflect.getMetadata("dip:modules", module) || [];
519
+
520
+ for (const mod of modules) {
521
+ await AppStartup.destroyModules(mod);
522
+ }
523
+
524
+ await AppStartup.executeOnModuleDestroy(module);
525
+ }
526
+
527
+ private static async executeOnModuleInit(module: any) {
528
+ const injectables: Map<any, any> | undefined = Reflect.getMetadata(
529
+ "dip:injectables",
530
+ module,
531
+ );
532
+
533
+ if (!injectables) {
534
+ return;
535
+ }
536
+
537
+ for (const provider of injectables.values()) {
538
+ if (!(provider instanceof OnModuleInit)) {
539
+ continue;
540
+ }
541
+
542
+ if (AppStartup.initializedModuleHooks.has(provider)) {
543
+ continue;
544
+ }
545
+
546
+ AppStartup.initializedModuleHooks.add(provider);
547
+ await provider.onModuleInit();
548
+ }
549
+ }
550
+
551
+ private static async executeOnModuleDestroy(module: any) {
552
+ const injectables: Map<any, any> | undefined = Reflect.getMetadata(
553
+ "dip:injectables",
554
+ module,
555
+ );
556
+
557
+ if (!injectables) {
558
+ return;
559
+ }
560
+
561
+ for (const provider of injectables.values()) {
562
+ if (!(provider instanceof OnModuleDestroy)) {
563
+ continue;
564
+ }
565
+
566
+ if (AppStartup.destroyedModuleHooks.has(provider)) {
567
+ continue;
568
+ }
569
+
570
+ AppStartup.destroyedModuleHooks.add(provider);
571
+ await provider.onModuleDestroy();
465
572
  }
466
573
  }
467
574
 
@@ -0,0 +1,2 @@
1
+ export * from "./on-module-destroy";
2
+ export * from "./on-module-init";
@@ -0,0 +1,3 @@
1
+ export abstract class OnModuleDestroy {
2
+ abstract onModuleDestroy(): Promise<void> | void;
3
+ }
@@ -0,0 +1,3 @@
1
+ export abstract class OnModuleInit {
2
+ abstract onModuleInit(): Promise<void> | void;
3
+ }
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "types": "./dist/*.d.ts"
14
14
  }
15
15
  },
16
- "version": "0.4.2",
16
+ "version": "0.4.3",
17
17
  "homepage": "https://bunstone.diario.one/",
18
18
  "repository": {
19
19
  "url": "https://github.com/diariodaregiao/bunstone.git",