@chromahq/core 1.0.55 → 1.0.57
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/{boot-Bty0U5M4.js → boot-C2Rq9czO.js} +236 -37
- package/dist/boot-C2Rq9czO.js.map +1 -0
- package/dist/{boot-BMZdye6C.js → boot-DIMyFZvd.js} +239 -36
- package/dist/boot-DIMyFZvd.js.map +1 -0
- package/dist/boot.cjs.js +2 -1
- package/dist/boot.cjs.js.map +1 -1
- package/dist/boot.es.js +2 -1
- package/dist/boot.es.js.map +1 -1
- package/dist/index.cjs.js +12 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +158 -2
- package/dist/index.es.js +4 -3
- package/dist/index.es.js.map +1 -1
- package/package.json +1 -1
- package/dist/boot-BMZdye6C.js.map +0 -1
- package/dist/boot-Bty0U5M4.js.map +0 -1
|
@@ -1,4 +1,124 @@
|
|
|
1
1
|
import { Container } from '@inversifyjs/container';
|
|
2
|
+
import { injectable } from '@inversifyjs/core';
|
|
3
|
+
|
|
4
|
+
const SUBSCRIBE_METADATA_KEY = "chroma:subscribe";
|
|
5
|
+
function Subscribe(eventName) {
|
|
6
|
+
return function(target, propertyKey, _descriptor) {
|
|
7
|
+
const key = "chroma:subscribe";
|
|
8
|
+
const constructor = target.constructor;
|
|
9
|
+
const existing = Reflect.getMetadata(key, constructor) || [];
|
|
10
|
+
existing.push({ eventName, methodName: propertyKey });
|
|
11
|
+
Reflect.defineMetadata(key, existing, constructor);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function getSubscribeMetadata(constructor) {
|
|
15
|
+
return Reflect.getMetadata("chroma:subscribe", constructor) || [];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
19
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
20
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
21
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
22
|
+
if (decorator = decorators[i])
|
|
23
|
+
result = (decorator(result)) || result;
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
const EventBusToken = /* @__PURE__ */ Symbol.for("EventBus");
|
|
27
|
+
let AppEventBus = class {
|
|
28
|
+
constructor() {
|
|
29
|
+
/** Registry of all active subscriptions */
|
|
30
|
+
this.subscriptions = [];
|
|
31
|
+
/** Auto-incrementing ID counter */
|
|
32
|
+
this.nextId = 0;
|
|
33
|
+
}
|
|
34
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
35
|
+
// Subscribe
|
|
36
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Subscribe to a named event.
|
|
39
|
+
*
|
|
40
|
+
* @param eventName - the event to listen for
|
|
41
|
+
* @param handler - callback invoked with the event payload
|
|
42
|
+
* @param handlerName - human-readable name for logging
|
|
43
|
+
* @returns an unsubscribe function
|
|
44
|
+
*/
|
|
45
|
+
on(eventName, handler, handlerName) {
|
|
46
|
+
const id = ++this.nextId;
|
|
47
|
+
this.subscriptions.push({
|
|
48
|
+
id,
|
|
49
|
+
eventName,
|
|
50
|
+
handler,
|
|
51
|
+
handlerName
|
|
52
|
+
});
|
|
53
|
+
return () => {
|
|
54
|
+
this.subscriptions = this.subscriptions.filter((s) => s.id !== id);
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
58
|
+
// Emit
|
|
59
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
60
|
+
/**
|
|
61
|
+
* Emit a named event to all matching subscribers.
|
|
62
|
+
*
|
|
63
|
+
* Handlers execute in parallel. Individual handler failures are caught
|
|
64
|
+
* and logged — they do not propagate or block other handlers.
|
|
65
|
+
*
|
|
66
|
+
* @param eventName - the event to emit
|
|
67
|
+
* @param payload - optional data passed to every handler
|
|
68
|
+
*/
|
|
69
|
+
async emit(eventName, payload) {
|
|
70
|
+
const matching = this.subscriptions.filter((s) => s.eventName === eventName);
|
|
71
|
+
if (matching.length === 0) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const results = await Promise.allSettled(
|
|
75
|
+
matching.map(async (sub) => {
|
|
76
|
+
try {
|
|
77
|
+
await sub.handler(payload);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
console.error(
|
|
80
|
+
`[AppEventBus] Handler "${sub.handlerName}" failed for event "${eventName}":`,
|
|
81
|
+
error
|
|
82
|
+
);
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
);
|
|
87
|
+
const failed = results.filter((r) => r.status === "rejected").length;
|
|
88
|
+
if (failed > 0) {
|
|
89
|
+
console.warn(
|
|
90
|
+
`[AppEventBus] ${failed}/${matching.length} handler(s) failed for event "${eventName}"`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
95
|
+
// Utilities
|
|
96
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
97
|
+
/**
|
|
98
|
+
* Get the total number of active subscriptions.
|
|
99
|
+
* Useful for debugging and testing.
|
|
100
|
+
*/
|
|
101
|
+
getSubscriptionCount() {
|
|
102
|
+
return this.subscriptions.length;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get the number of subscriptions for a specific event.
|
|
106
|
+
*
|
|
107
|
+
* @param eventName - the event to count subscriptions for
|
|
108
|
+
*/
|
|
109
|
+
getSubscriptionCountForEvent(eventName) {
|
|
110
|
+
return this.subscriptions.filter((s) => s.eventName === eventName).length;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Remove all subscriptions. Primarily for testing.
|
|
114
|
+
*/
|
|
115
|
+
clearAllSubscriptions() {
|
|
116
|
+
this.subscriptions = [];
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
AppEventBus = __decorateClass([
|
|
120
|
+
injectable()
|
|
121
|
+
], AppEventBus);
|
|
2
122
|
|
|
3
123
|
const NONCE_STORE_STORAGE_KEY = "__CHROMA_NONCE_STORE__";
|
|
4
124
|
class NonceService {
|
|
@@ -2200,6 +2320,7 @@ class ApplicationBootstrap {
|
|
|
2200
2320
|
constructor() {
|
|
2201
2321
|
this.serviceDependencies = /* @__PURE__ */ new Map();
|
|
2202
2322
|
this.serviceRegistry = /* @__PURE__ */ new Map();
|
|
2323
|
+
this.jobRegistry = /* @__PURE__ */ new Map();
|
|
2203
2324
|
this.logger = new BootstrapLogger();
|
|
2204
2325
|
this.storeDefinitions = [];
|
|
2205
2326
|
}
|
|
@@ -2230,7 +2351,8 @@ class ApplicationBootstrap {
|
|
|
2230
2351
|
}) {
|
|
2231
2352
|
try {
|
|
2232
2353
|
this.logger = new BootstrapLogger(enableLogs);
|
|
2233
|
-
this.logger.info("
|
|
2354
|
+
this.logger.info("Starting Chroma application bootstrap...");
|
|
2355
|
+
this.initializeEventBus();
|
|
2234
2356
|
await this.discoverAndInitializeStores();
|
|
2235
2357
|
await this.discoverServices();
|
|
2236
2358
|
const store = this.storeDefinitions[0].store;
|
|
@@ -2250,10 +2372,11 @@ class ApplicationBootstrap {
|
|
|
2250
2372
|
if (!disableBootMethods) {
|
|
2251
2373
|
await this.bootMessages();
|
|
2252
2374
|
await this.bootServices();
|
|
2375
|
+
this.wireEventSubscriptions();
|
|
2253
2376
|
}
|
|
2254
|
-
this.logger.success("
|
|
2377
|
+
this.logger.success("Chroma application initialization complete");
|
|
2255
2378
|
} catch (error) {
|
|
2256
|
-
this.logger.error("
|
|
2379
|
+
this.logger.error("Application bootstrap failed:", error);
|
|
2257
2380
|
throw error;
|
|
2258
2381
|
}
|
|
2259
2382
|
}
|
|
@@ -2261,7 +2384,7 @@ class ApplicationBootstrap {
|
|
|
2261
2384
|
* Boot all registered services by calling their onBoot method if present
|
|
2262
2385
|
*/
|
|
2263
2386
|
async bootServices() {
|
|
2264
|
-
this.logger.info("
|
|
2387
|
+
this.logger.info("Booting services...");
|
|
2265
2388
|
const bootPromises = Array.from(this.serviceRegistry.entries()).map(
|
|
2266
2389
|
async ([serviceName, ServiceClass]) => {
|
|
2267
2390
|
try {
|
|
@@ -2280,11 +2403,67 @@ class ApplicationBootstrap {
|
|
|
2280
2403
|
);
|
|
2281
2404
|
await Promise.all(bootPromises);
|
|
2282
2405
|
}
|
|
2406
|
+
/**
|
|
2407
|
+
* Create and bind the global AppEventBus singleton to the DI container.
|
|
2408
|
+
* Called early in bootstrap so any service can inject it.
|
|
2409
|
+
*/
|
|
2410
|
+
initializeEventBus() {
|
|
2411
|
+
if (!container.isBound(AppEventBus)) {
|
|
2412
|
+
container.bind(AppEventBus).toSelf().inSingletonScope();
|
|
2413
|
+
}
|
|
2414
|
+
if (!container.isBound(EventBusToken)) {
|
|
2415
|
+
container.bind(EventBusToken).toDynamicValue(() => container.get(AppEventBus)).inSingletonScope();
|
|
2416
|
+
}
|
|
2417
|
+
this.logger.debug("AppEventBus bound to DI container");
|
|
2418
|
+
}
|
|
2419
|
+
/**
|
|
2420
|
+
* Scan all registered services and jobs for @Subscribe metadata and
|
|
2421
|
+
* wire the decorated methods to the AppEventBus.
|
|
2422
|
+
*
|
|
2423
|
+
* This runs after bootServices so every singleton is already instantiated.
|
|
2424
|
+
*/
|
|
2425
|
+
wireEventSubscriptions() {
|
|
2426
|
+
this.logger.info("Wiring @Subscribe event subscriptions...");
|
|
2427
|
+
const bus = container.get(AppEventBus);
|
|
2428
|
+
let wiredCount = 0;
|
|
2429
|
+
const scan = (name, Constructor) => {
|
|
2430
|
+
const metadata = getSubscribeMetadata(Constructor);
|
|
2431
|
+
if (metadata.length === 0) {
|
|
2432
|
+
return;
|
|
2433
|
+
}
|
|
2434
|
+
let instance;
|
|
2435
|
+
try {
|
|
2436
|
+
instance = container.get(Constructor);
|
|
2437
|
+
} catch {
|
|
2438
|
+
this.logger.warn(`Could not resolve instance for ${name}, skipping @Subscribe wiring`);
|
|
2439
|
+
return;
|
|
2440
|
+
}
|
|
2441
|
+
for (const { eventName, methodName } of metadata) {
|
|
2442
|
+
const method = instance[methodName];
|
|
2443
|
+
if (typeof method !== "function") {
|
|
2444
|
+
this.logger.warn(
|
|
2445
|
+
`@Subscribe('${eventName}') on ${name}.${methodName} is not a function, skipping`
|
|
2446
|
+
);
|
|
2447
|
+
continue;
|
|
2448
|
+
}
|
|
2449
|
+
bus.on(eventName, method.bind(instance), `${name}.${methodName}`);
|
|
2450
|
+
wiredCount++;
|
|
2451
|
+
this.logger.debug(`Wired @Subscribe('${eventName}') \u2192 ${name}.${methodName}`);
|
|
2452
|
+
}
|
|
2453
|
+
};
|
|
2454
|
+
for (const [name, Constructor] of this.serviceRegistry) {
|
|
2455
|
+
scan(name, Constructor);
|
|
2456
|
+
}
|
|
2457
|
+
for (const [name, Constructor] of this.jobRegistry) {
|
|
2458
|
+
scan(name, Constructor);
|
|
2459
|
+
}
|
|
2460
|
+
this.logger.success(`Wired ${wiredCount} @Subscribe handler(s) to AppEventBus`);
|
|
2461
|
+
}
|
|
2283
2462
|
/**
|
|
2284
2463
|
* Discover all services in the application directory
|
|
2285
2464
|
*/
|
|
2286
2465
|
async discoverServices() {
|
|
2287
|
-
this.logger.info("
|
|
2466
|
+
this.logger.info("Discovering services...");
|
|
2288
2467
|
const serviceModules = import.meta.glob(
|
|
2289
2468
|
"/src/app/services/**/*.service.{ts,js}",
|
|
2290
2469
|
{ eager: true }
|
|
@@ -2299,7 +2478,7 @@ class ApplicationBootstrap {
|
|
|
2299
2478
|
}
|
|
2300
2479
|
const circularDepsResult = this.detectCircularDependencies(serviceClasses);
|
|
2301
2480
|
if (circularDepsResult.hasCircularDependencies) {
|
|
2302
|
-
this.logger.error("
|
|
2481
|
+
this.logger.error("Circular dependencies detected!");
|
|
2303
2482
|
circularDepsResult.cycles.forEach((cycle, index) => {
|
|
2304
2483
|
this.logger.error(`Cycle ${index + 1}: ${cycle.cycle.join(" \u2192 ")} \u2192 ${cycle.cycle[0]}`);
|
|
2305
2484
|
});
|
|
@@ -2307,10 +2486,10 @@ class ApplicationBootstrap {
|
|
|
2307
2486
|
}
|
|
2308
2487
|
for (const ServiceClass of serviceClasses) {
|
|
2309
2488
|
container.bind(ServiceClass).toSelf().inSingletonScope();
|
|
2310
|
-
this.logger.debug(
|
|
2489
|
+
this.logger.debug(`Discovered service: ${ServiceClass.name}`);
|
|
2311
2490
|
}
|
|
2312
2491
|
this.logger.success(
|
|
2313
|
-
|
|
2492
|
+
`Registered ${serviceClasses.length} services without circular dependencies`
|
|
2314
2493
|
);
|
|
2315
2494
|
}
|
|
2316
2495
|
/**
|
|
@@ -2442,17 +2621,17 @@ class ApplicationBootstrap {
|
|
|
2442
2621
|
analyzeDependencies() {
|
|
2443
2622
|
const serviceClasses = Array.from(this.serviceRegistry.values());
|
|
2444
2623
|
const result = this.detectCircularDependencies(serviceClasses);
|
|
2445
|
-
this.logger.info("
|
|
2624
|
+
this.logger.info("Dependency Analysis Report:");
|
|
2446
2625
|
this.logger.info(`Total Services: ${result.dependencyGraph.size}`);
|
|
2447
2626
|
if (result.hasCircularDependencies) {
|
|
2448
|
-
this.logger.error(
|
|
2627
|
+
this.logger.error(`Circular Dependencies Found: ${result.cycles.length}`);
|
|
2449
2628
|
result.cycles.forEach((cycle, index) => {
|
|
2450
2629
|
this.logger.error(` Cycle ${index + 1}: ${cycle.cycle.join(" \u2192 ")} \u2192 ${cycle.cycle[0]}`);
|
|
2451
2630
|
});
|
|
2452
2631
|
} else {
|
|
2453
|
-
this.logger.success("
|
|
2632
|
+
this.logger.success("No circular dependencies detected");
|
|
2454
2633
|
}
|
|
2455
|
-
this.logger.info("
|
|
2634
|
+
this.logger.info("Service Dependency Tree:");
|
|
2456
2635
|
for (const [serviceName, node] of result.dependencyGraph) {
|
|
2457
2636
|
if (node.dependencies.length > 0) {
|
|
2458
2637
|
this.logger.info(` ${serviceName} depends on:`);
|
|
@@ -2470,7 +2649,7 @@ class ApplicationBootstrap {
|
|
|
2470
2649
|
async discoverAndInitializeStores() {
|
|
2471
2650
|
try {
|
|
2472
2651
|
if (this.storeDefinitions.length === 0) {
|
|
2473
|
-
this.logger.debug("
|
|
2652
|
+
this.logger.debug("No store definitions provided");
|
|
2474
2653
|
return;
|
|
2475
2654
|
}
|
|
2476
2655
|
this.logger.info(`Initializing ${this.storeDefinitions.length} store(s)...`);
|
|
@@ -2481,7 +2660,7 @@ class ApplicationBootstrap {
|
|
|
2481
2660
|
const classes = store.classes;
|
|
2482
2661
|
container.bind(diKey).toConstantValue(storeInstance);
|
|
2483
2662
|
if (isFirstStore) {
|
|
2484
|
-
container.bind(Symbol.for("Store")).toConstantValue(storeInstance);
|
|
2663
|
+
container.bind(/* @__PURE__ */ Symbol.for("Store")).toConstantValue(storeInstance);
|
|
2485
2664
|
isFirstStore = false;
|
|
2486
2665
|
}
|
|
2487
2666
|
await this.registerMessageClass(
|
|
@@ -2498,18 +2677,18 @@ class ApplicationBootstrap {
|
|
|
2498
2677
|
`store:${store.def.name}:reset`
|
|
2499
2678
|
);
|
|
2500
2679
|
}
|
|
2501
|
-
this.logger.debug(
|
|
2680
|
+
this.logger.debug(`Initialized store: ${store.def.name}`);
|
|
2502
2681
|
}
|
|
2503
|
-
this.logger.success(
|
|
2682
|
+
this.logger.success(`Initialized ${this.storeDefinitions.length} store(s)`);
|
|
2504
2683
|
} catch (error) {
|
|
2505
|
-
this.logger.error("
|
|
2684
|
+
this.logger.error("Failed to initialize stores:", error);
|
|
2506
2685
|
}
|
|
2507
2686
|
}
|
|
2508
2687
|
/**
|
|
2509
2688
|
* Register message handlers
|
|
2510
2689
|
*/
|
|
2511
2690
|
async registerMessages() {
|
|
2512
|
-
this.logger.info("
|
|
2691
|
+
this.logger.info("Registering messages...");
|
|
2513
2692
|
const messageModules = import.meta.glob(
|
|
2514
2693
|
"/src/app/messages/**/*.message.{ts,js}",
|
|
2515
2694
|
{ eager: true }
|
|
@@ -2522,7 +2701,7 @@ class ApplicationBootstrap {
|
|
|
2522
2701
|
if (messageClasses.length > 0) {
|
|
2523
2702
|
const circularDepsResult = this.detectCircularDependencies(messageClasses);
|
|
2524
2703
|
if (circularDepsResult.hasCircularDependencies) {
|
|
2525
|
-
this.logger.error("
|
|
2704
|
+
this.logger.error("Circular dependencies detected in messages!");
|
|
2526
2705
|
circularDepsResult.cycles.forEach((cycle, index) => {
|
|
2527
2706
|
this.logger.error(
|
|
2528
2707
|
`Message Cycle ${index + 1}: ${cycle.cycle.join(" \u2192 ")} \u2192 ${cycle.cycle[0]}`
|
|
@@ -2537,30 +2716,30 @@ class ApplicationBootstrap {
|
|
|
2537
2716
|
try {
|
|
2538
2717
|
for (const [name, ServiceClass] of this.serviceRegistry) {
|
|
2539
2718
|
if (!ServiceClass) {
|
|
2540
|
-
this.logger.warn(
|
|
2719
|
+
this.logger.warn(`Service not found in registry: ${name}`);
|
|
2541
2720
|
}
|
|
2542
2721
|
if (!container.isBound(ServiceClass)) {
|
|
2543
|
-
this.logger.warn(
|
|
2722
|
+
this.logger.warn(`Service not bound in container: ${name}`);
|
|
2544
2723
|
}
|
|
2545
2724
|
}
|
|
2546
2725
|
const messageMetadata = Reflect.getMetadata("name", MessageClass);
|
|
2547
2726
|
const messageName = messageMetadata || MessageClass.name;
|
|
2548
2727
|
container.bind(messageName).to(MessageClass).inSingletonScope();
|
|
2549
|
-
this.logger.success(
|
|
2728
|
+
this.logger.success(`Registered message: ${messageName}`);
|
|
2550
2729
|
} catch (error) {
|
|
2551
|
-
this.logger.error(
|
|
2730
|
+
this.logger.error(`Failed to register message ${MessageClass.name}:`, error);
|
|
2552
2731
|
}
|
|
2553
2732
|
}
|
|
2554
2733
|
}
|
|
2555
2734
|
async registerMessageClass(MessageClass, name) {
|
|
2556
2735
|
container.bind(name).to(MessageClass).inSingletonScope();
|
|
2557
|
-
this.logger.success(
|
|
2736
|
+
this.logger.success(`Registered message: ${name}`);
|
|
2558
2737
|
}
|
|
2559
2738
|
/**
|
|
2560
2739
|
* Boot all registered messages
|
|
2561
2740
|
*/
|
|
2562
2741
|
async bootMessages() {
|
|
2563
|
-
this.logger.info("
|
|
2742
|
+
this.logger.info("Booting messages...");
|
|
2564
2743
|
const messageModules = import.meta.glob(
|
|
2565
2744
|
"/src/app/messages/**/*.message.{ts,js}",
|
|
2566
2745
|
{ eager: true }
|
|
@@ -2575,10 +2754,10 @@ class ApplicationBootstrap {
|
|
|
2575
2754
|
const messageName = messageMetadata || MessageClass.name;
|
|
2576
2755
|
const messageInstance = container.get(messageName);
|
|
2577
2756
|
await messageInstance.boot();
|
|
2578
|
-
this.logger.success(
|
|
2757
|
+
this.logger.success(`Booted message: ${messageName}`);
|
|
2579
2758
|
return { messageName, success: true };
|
|
2580
2759
|
} catch (error) {
|
|
2581
|
-
this.logger.error(
|
|
2760
|
+
this.logger.error(`Failed to boot message ${MessageClass.name}:`, error);
|
|
2582
2761
|
return { messageName: MessageClass.name, success: false, error };
|
|
2583
2762
|
}
|
|
2584
2763
|
});
|
|
@@ -2588,7 +2767,7 @@ class ApplicationBootstrap {
|
|
|
2588
2767
|
* Register jobs for scheduled execution
|
|
2589
2768
|
*/
|
|
2590
2769
|
async registerJobs() {
|
|
2591
|
-
this.logger.info("
|
|
2770
|
+
this.logger.info("Registering jobs...");
|
|
2592
2771
|
const jobModules = import.meta.glob(
|
|
2593
2772
|
"/src/app/jobs/**/*.job.{ts,js}",
|
|
2594
2773
|
{ eager: true }
|
|
@@ -2599,10 +2778,10 @@ class ApplicationBootstrap {
|
|
|
2599
2778
|
this.logger.debug("container isBound(Scheduler)", { isBound: container.isBound(Scheduler) });
|
|
2600
2779
|
for (const [name, ServiceClass] of this.serviceRegistry) {
|
|
2601
2780
|
if (!ServiceClass) {
|
|
2602
|
-
this.logger.warn(
|
|
2781
|
+
this.logger.warn(`Service not found in registry: ${name}`);
|
|
2603
2782
|
}
|
|
2604
2783
|
if (!container.isBound(ServiceClass)) {
|
|
2605
|
-
this.logger.warn(
|
|
2784
|
+
this.logger.warn(`Service not bound in container: ${name}`);
|
|
2606
2785
|
} else {
|
|
2607
2786
|
container.get(ServiceClass);
|
|
2608
2787
|
}
|
|
@@ -2622,23 +2801,43 @@ class ApplicationBootstrap {
|
|
|
2622
2801
|
container.bind(id).to(JobClass).inSingletonScope();
|
|
2623
2802
|
const options = Reflect.getMetadata("job:options", JobClass) || {};
|
|
2624
2803
|
jobEntries.push({ JobClass, jobName, id, options });
|
|
2625
|
-
this.
|
|
2804
|
+
this.jobRegistry.set(jobName, JobClass);
|
|
2805
|
+
this.logger.debug(`Bound job: ${jobName}`);
|
|
2626
2806
|
} catch (error) {
|
|
2627
|
-
this.logger.error(
|
|
2807
|
+
this.logger.error(`Failed to bind job ${JobClass.name}:`, error);
|
|
2628
2808
|
}
|
|
2629
2809
|
}
|
|
2630
2810
|
for (const { JobClass, jobName, id, options } of jobEntries) {
|
|
2631
2811
|
try {
|
|
2632
2812
|
const instance = container.get(JobClass);
|
|
2633
2813
|
JobRegistry.instance.register(id, instance, options);
|
|
2814
|
+
if (typeof instance.onBoot === "function") {
|
|
2815
|
+
this.logger.info(`Executing onBoot for job: ${jobName}`);
|
|
2816
|
+
try {
|
|
2817
|
+
if (options.requiresPopup) {
|
|
2818
|
+
const isPopupVisible = PopupVisibilityService.instance.isPopupVisible();
|
|
2819
|
+
if (!isPopupVisible) {
|
|
2820
|
+
this.logger.debug(`Skipping onBoot for job ${jobName} - popup not visible`);
|
|
2821
|
+
} else {
|
|
2822
|
+
await instance.onBoot();
|
|
2823
|
+
this.logger.debug(`Executed onBoot for job: ${jobName}`);
|
|
2824
|
+
}
|
|
2825
|
+
} else {
|
|
2826
|
+
await instance.onBoot();
|
|
2827
|
+
this.logger.debug(`Executed onBoot for job: ${jobName}`);
|
|
2828
|
+
}
|
|
2829
|
+
} catch (error) {
|
|
2830
|
+
this.logger.error(`Failed to execute onBoot for job ${jobName}:`, error);
|
|
2831
|
+
}
|
|
2832
|
+
}
|
|
2634
2833
|
if (!options.startPaused) {
|
|
2635
2834
|
this.scheduler.schedule(id, options);
|
|
2636
2835
|
} else {
|
|
2637
|
-
this.logger.info(
|
|
2836
|
+
this.logger.info(`Job ${jobName} registered but paused (startPaused: true)`);
|
|
2638
2837
|
}
|
|
2639
|
-
this.logger.success(
|
|
2838
|
+
this.logger.success(`Registered job: ${jobName}`);
|
|
2640
2839
|
} catch (error) {
|
|
2641
|
-
this.logger.error(
|
|
2840
|
+
this.logger.error(`Failed to register job ${JobClass.name}:`, error);
|
|
2642
2841
|
}
|
|
2643
2842
|
}
|
|
2644
2843
|
}
|
|
@@ -2723,5 +2922,5 @@ class BootstrapBuilder {
|
|
|
2723
2922
|
}
|
|
2724
2923
|
}
|
|
2725
2924
|
|
|
2726
|
-
export { JobRegistry as J, NonceService as N, PopupVisibilityService as P,
|
|
2727
|
-
//# sourceMappingURL=boot-
|
|
2925
|
+
export { AppEventBus as A, EventBusToken as E, JobRegistry as J, NonceService as N, PopupVisibilityService as P, Subscribe as S, SUBSCRIBE_METADATA_KEY as a, getNonceService as b, getPopupVisibilityService as c, claimEarlyPorts as d, arePortsClaimed as e, container as f, getSubscribeMetadata as g, create as h, isEarlyListenerSetup as i, bootstrap as j, Scheduler as k, JobState as l, setupEarlyListener as s };
|
|
2926
|
+
//# sourceMappingURL=boot-C2Rq9czO.js.map
|