@chromahq/core 1.0.56 → 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-c2gJZWBc.js → boot-C2Rq9czO.js} +182 -2
- package/dist/boot-C2Rq9czO.js.map +1 -0
- package/dist/{boot-CUFlC4bu.js → boot-DIMyFZvd.js} +185 -1
- 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 +11 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +152 -2
- package/dist/index.es.js +3 -2
- package/dist/index.es.js.map +1 -1
- package/package.json +1 -1
- package/dist/boot-CUFlC4bu.js.map +0 -1
- package/dist/boot-c2gJZWBc.js.map +0 -1
|
@@ -1,6 +1,126 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var container$1 = require('@inversifyjs/container');
|
|
4
|
+
var core = require('@inversifyjs/core');
|
|
5
|
+
|
|
6
|
+
const SUBSCRIBE_METADATA_KEY = "chroma:subscribe";
|
|
7
|
+
function Subscribe(eventName) {
|
|
8
|
+
return function(target, propertyKey, _descriptor) {
|
|
9
|
+
const key = "chroma:subscribe";
|
|
10
|
+
const constructor = target.constructor;
|
|
11
|
+
const existing = Reflect.getMetadata(key, constructor) || [];
|
|
12
|
+
existing.push({ eventName, methodName: propertyKey });
|
|
13
|
+
Reflect.defineMetadata(key, existing, constructor);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function getSubscribeMetadata(constructor) {
|
|
17
|
+
return Reflect.getMetadata("chroma:subscribe", constructor) || [];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
21
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
22
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
23
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
24
|
+
if (decorator = decorators[i])
|
|
25
|
+
result = (decorator(result)) || result;
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
const EventBusToken = /* @__PURE__ */ Symbol.for("EventBus");
|
|
29
|
+
exports.AppEventBus = class AppEventBus {
|
|
30
|
+
constructor() {
|
|
31
|
+
/** Registry of all active subscriptions */
|
|
32
|
+
this.subscriptions = [];
|
|
33
|
+
/** Auto-incrementing ID counter */
|
|
34
|
+
this.nextId = 0;
|
|
35
|
+
}
|
|
36
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
37
|
+
// Subscribe
|
|
38
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
39
|
+
/**
|
|
40
|
+
* Subscribe to a named event.
|
|
41
|
+
*
|
|
42
|
+
* @param eventName - the event to listen for
|
|
43
|
+
* @param handler - callback invoked with the event payload
|
|
44
|
+
* @param handlerName - human-readable name for logging
|
|
45
|
+
* @returns an unsubscribe function
|
|
46
|
+
*/
|
|
47
|
+
on(eventName, handler, handlerName) {
|
|
48
|
+
const id = ++this.nextId;
|
|
49
|
+
this.subscriptions.push({
|
|
50
|
+
id,
|
|
51
|
+
eventName,
|
|
52
|
+
handler,
|
|
53
|
+
handlerName
|
|
54
|
+
});
|
|
55
|
+
return () => {
|
|
56
|
+
this.subscriptions = this.subscriptions.filter((s) => s.id !== id);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
60
|
+
// Emit
|
|
61
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
62
|
+
/**
|
|
63
|
+
* Emit a named event to all matching subscribers.
|
|
64
|
+
*
|
|
65
|
+
* Handlers execute in parallel. Individual handler failures are caught
|
|
66
|
+
* and logged — they do not propagate or block other handlers.
|
|
67
|
+
*
|
|
68
|
+
* @param eventName - the event to emit
|
|
69
|
+
* @param payload - optional data passed to every handler
|
|
70
|
+
*/
|
|
71
|
+
async emit(eventName, payload) {
|
|
72
|
+
const matching = this.subscriptions.filter((s) => s.eventName === eventName);
|
|
73
|
+
if (matching.length === 0) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const results = await Promise.allSettled(
|
|
77
|
+
matching.map(async (sub) => {
|
|
78
|
+
try {
|
|
79
|
+
await sub.handler(payload);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.error(
|
|
82
|
+
`[AppEventBus] Handler "${sub.handlerName}" failed for event "${eventName}":`,
|
|
83
|
+
error
|
|
84
|
+
);
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
);
|
|
89
|
+
const failed = results.filter((r) => r.status === "rejected").length;
|
|
90
|
+
if (failed > 0) {
|
|
91
|
+
console.warn(
|
|
92
|
+
`[AppEventBus] ${failed}/${matching.length} handler(s) failed for event "${eventName}"`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
97
|
+
// Utilities
|
|
98
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
99
|
+
/**
|
|
100
|
+
* Get the total number of active subscriptions.
|
|
101
|
+
* Useful for debugging and testing.
|
|
102
|
+
*/
|
|
103
|
+
getSubscriptionCount() {
|
|
104
|
+
return this.subscriptions.length;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get the number of subscriptions for a specific event.
|
|
108
|
+
*
|
|
109
|
+
* @param eventName - the event to count subscriptions for
|
|
110
|
+
*/
|
|
111
|
+
getSubscriptionCountForEvent(eventName) {
|
|
112
|
+
return this.subscriptions.filter((s) => s.eventName === eventName).length;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Remove all subscriptions. Primarily for testing.
|
|
116
|
+
*/
|
|
117
|
+
clearAllSubscriptions() {
|
|
118
|
+
this.subscriptions = [];
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
exports.AppEventBus = __decorateClass([
|
|
122
|
+
core.injectable()
|
|
123
|
+
], exports.AppEventBus);
|
|
4
124
|
|
|
5
125
|
const NONCE_STORE_STORAGE_KEY = "__CHROMA_NONCE_STORE__";
|
|
6
126
|
class NonceService {
|
|
@@ -2202,6 +2322,7 @@ class ApplicationBootstrap {
|
|
|
2202
2322
|
constructor() {
|
|
2203
2323
|
this.serviceDependencies = /* @__PURE__ */ new Map();
|
|
2204
2324
|
this.serviceRegistry = /* @__PURE__ */ new Map();
|
|
2325
|
+
this.jobRegistry = /* @__PURE__ */ new Map();
|
|
2205
2326
|
this.logger = new BootstrapLogger();
|
|
2206
2327
|
this.storeDefinitions = [];
|
|
2207
2328
|
}
|
|
@@ -2233,6 +2354,7 @@ class ApplicationBootstrap {
|
|
|
2233
2354
|
try {
|
|
2234
2355
|
this.logger = new BootstrapLogger(enableLogs);
|
|
2235
2356
|
this.logger.info("Starting Chroma application bootstrap...");
|
|
2357
|
+
this.initializeEventBus();
|
|
2236
2358
|
await this.discoverAndInitializeStores();
|
|
2237
2359
|
await this.discoverServices();
|
|
2238
2360
|
const store = this.storeDefinitions[0].store;
|
|
@@ -2252,6 +2374,7 @@ class ApplicationBootstrap {
|
|
|
2252
2374
|
if (!disableBootMethods) {
|
|
2253
2375
|
await this.bootMessages();
|
|
2254
2376
|
await this.bootServices();
|
|
2377
|
+
this.wireEventSubscriptions();
|
|
2255
2378
|
}
|
|
2256
2379
|
this.logger.success("Chroma application initialization complete");
|
|
2257
2380
|
} catch (error) {
|
|
@@ -2282,6 +2405,62 @@ class ApplicationBootstrap {
|
|
|
2282
2405
|
);
|
|
2283
2406
|
await Promise.all(bootPromises);
|
|
2284
2407
|
}
|
|
2408
|
+
/**
|
|
2409
|
+
* Create and bind the global AppEventBus singleton to the DI container.
|
|
2410
|
+
* Called early in bootstrap so any service can inject it.
|
|
2411
|
+
*/
|
|
2412
|
+
initializeEventBus() {
|
|
2413
|
+
if (!container.isBound(exports.AppEventBus)) {
|
|
2414
|
+
container.bind(exports.AppEventBus).toSelf().inSingletonScope();
|
|
2415
|
+
}
|
|
2416
|
+
if (!container.isBound(EventBusToken)) {
|
|
2417
|
+
container.bind(EventBusToken).toDynamicValue(() => container.get(exports.AppEventBus)).inSingletonScope();
|
|
2418
|
+
}
|
|
2419
|
+
this.logger.debug("AppEventBus bound to DI container");
|
|
2420
|
+
}
|
|
2421
|
+
/**
|
|
2422
|
+
* Scan all registered services and jobs for @Subscribe metadata and
|
|
2423
|
+
* wire the decorated methods to the AppEventBus.
|
|
2424
|
+
*
|
|
2425
|
+
* This runs after bootServices so every singleton is already instantiated.
|
|
2426
|
+
*/
|
|
2427
|
+
wireEventSubscriptions() {
|
|
2428
|
+
this.logger.info("Wiring @Subscribe event subscriptions...");
|
|
2429
|
+
const bus = container.get(exports.AppEventBus);
|
|
2430
|
+
let wiredCount = 0;
|
|
2431
|
+
const scan = (name, Constructor) => {
|
|
2432
|
+
const metadata = getSubscribeMetadata(Constructor);
|
|
2433
|
+
if (metadata.length === 0) {
|
|
2434
|
+
return;
|
|
2435
|
+
}
|
|
2436
|
+
let instance;
|
|
2437
|
+
try {
|
|
2438
|
+
instance = container.get(Constructor);
|
|
2439
|
+
} catch {
|
|
2440
|
+
this.logger.warn(`Could not resolve instance for ${name}, skipping @Subscribe wiring`);
|
|
2441
|
+
return;
|
|
2442
|
+
}
|
|
2443
|
+
for (const { eventName, methodName } of metadata) {
|
|
2444
|
+
const method = instance[methodName];
|
|
2445
|
+
if (typeof method !== "function") {
|
|
2446
|
+
this.logger.warn(
|
|
2447
|
+
`@Subscribe('${eventName}') on ${name}.${methodName} is not a function, skipping`
|
|
2448
|
+
);
|
|
2449
|
+
continue;
|
|
2450
|
+
}
|
|
2451
|
+
bus.on(eventName, method.bind(instance), `${name}.${methodName}`);
|
|
2452
|
+
wiredCount++;
|
|
2453
|
+
this.logger.debug(`Wired @Subscribe('${eventName}') \u2192 ${name}.${methodName}`);
|
|
2454
|
+
}
|
|
2455
|
+
};
|
|
2456
|
+
for (const [name, Constructor] of this.serviceRegistry) {
|
|
2457
|
+
scan(name, Constructor);
|
|
2458
|
+
}
|
|
2459
|
+
for (const [name, Constructor] of this.jobRegistry) {
|
|
2460
|
+
scan(name, Constructor);
|
|
2461
|
+
}
|
|
2462
|
+
this.logger.success(`Wired ${wiredCount} @Subscribe handler(s) to AppEventBus`);
|
|
2463
|
+
}
|
|
2285
2464
|
/**
|
|
2286
2465
|
* Discover all services in the application directory
|
|
2287
2466
|
*/
|
|
@@ -2624,6 +2803,7 @@ class ApplicationBootstrap {
|
|
|
2624
2803
|
container.bind(id).to(JobClass).inSingletonScope();
|
|
2625
2804
|
const options = Reflect.getMetadata("job:options", JobClass) || {};
|
|
2626
2805
|
jobEntries.push({ JobClass, jobName, id, options });
|
|
2806
|
+
this.jobRegistry.set(jobName, JobClass);
|
|
2627
2807
|
this.logger.debug(`Bound job: ${jobName}`);
|
|
2628
2808
|
} catch (error) {
|
|
2629
2809
|
this.logger.error(`Failed to bind job ${JobClass.name}:`, error);
|
|
@@ -2744,11 +2924,14 @@ class BootstrapBuilder {
|
|
|
2744
2924
|
}
|
|
2745
2925
|
}
|
|
2746
2926
|
|
|
2927
|
+
exports.EventBusToken = EventBusToken;
|
|
2747
2928
|
exports.JobRegistry = JobRegistry;
|
|
2748
2929
|
exports.JobState = JobState;
|
|
2749
2930
|
exports.NonceService = NonceService;
|
|
2750
2931
|
exports.PopupVisibilityService = PopupVisibilityService;
|
|
2932
|
+
exports.SUBSCRIBE_METADATA_KEY = SUBSCRIBE_METADATA_KEY;
|
|
2751
2933
|
exports.Scheduler = Scheduler;
|
|
2934
|
+
exports.Subscribe = Subscribe;
|
|
2752
2935
|
exports.arePortsClaimed = arePortsClaimed;
|
|
2753
2936
|
exports.bootstrap = bootstrap;
|
|
2754
2937
|
exports.claimEarlyPorts = claimEarlyPorts;
|
|
@@ -2756,6 +2939,7 @@ exports.container = container;
|
|
|
2756
2939
|
exports.create = create;
|
|
2757
2940
|
exports.getNonceService = getNonceService;
|
|
2758
2941
|
exports.getPopupVisibilityService = getPopupVisibilityService;
|
|
2942
|
+
exports.getSubscribeMetadata = getSubscribeMetadata;
|
|
2759
2943
|
exports.isEarlyListenerSetup = isEarlyListenerSetup;
|
|
2760
2944
|
exports.setupEarlyListener = setupEarlyListener;
|
|
2761
|
-
//# sourceMappingURL=boot-
|
|
2945
|
+
//# sourceMappingURL=boot-DIMyFZvd.js.map
|