@xaramoge/shared-events 0.1.0
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/EventBus.d.ts +55 -0
- package/dist/EventBus.d.ts.map +1 -0
- package/dist/__tests__/EventBus.test.d.ts +2 -0
- package/dist/__tests__/EventBus.test.d.ts.map +1 -0
- package/dist/events.d.ts +134 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +163 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
type EventCallback<T = any> = (data: T) => void | Promise<void>;
|
|
2
|
+
interface Subscription {
|
|
3
|
+
unsubscribe: () => void;
|
|
4
|
+
}
|
|
5
|
+
declare class EventBus {
|
|
6
|
+
private events;
|
|
7
|
+
private debugMode;
|
|
8
|
+
/**
|
|
9
|
+
* Enable debug logging
|
|
10
|
+
*/
|
|
11
|
+
enableDebug(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Disable debug logging
|
|
14
|
+
*/
|
|
15
|
+
disableDebug(): void;
|
|
16
|
+
/**
|
|
17
|
+
* Subscribe to an event
|
|
18
|
+
*/
|
|
19
|
+
on<T = any>(event: string, callback: EventCallback<T>): Subscription;
|
|
20
|
+
/**
|
|
21
|
+
* Subscribe to an event (one-time only)
|
|
22
|
+
*/
|
|
23
|
+
once<T = any>(event: string, callback: EventCallback<T>): Subscription;
|
|
24
|
+
/**
|
|
25
|
+
* Unsubscribe from an event
|
|
26
|
+
*/
|
|
27
|
+
off(event: string, callback: EventCallback): void;
|
|
28
|
+
/**
|
|
29
|
+
* Emit an event
|
|
30
|
+
*/
|
|
31
|
+
emit<T = any>(event: string, data?: T): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Emit an event synchronously (doesn't wait for async callbacks)
|
|
34
|
+
*/
|
|
35
|
+
emitSync<T = any>(event: string, data?: T): void;
|
|
36
|
+
/**
|
|
37
|
+
* Remove all listeners for an event, or all events if no event specified
|
|
38
|
+
*/
|
|
39
|
+
clear(event?: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Get list of all events with active listeners
|
|
42
|
+
*/
|
|
43
|
+
getEvents(): string[];
|
|
44
|
+
/**
|
|
45
|
+
* Get number of listeners for an event
|
|
46
|
+
*/
|
|
47
|
+
getListenerCount(event: string): number;
|
|
48
|
+
/**
|
|
49
|
+
* Check if an event has any listeners
|
|
50
|
+
*/
|
|
51
|
+
hasListeners(event: string): boolean;
|
|
52
|
+
}
|
|
53
|
+
export declare const eventBus: EventBus;
|
|
54
|
+
export { EventBus };
|
|
55
|
+
//# sourceMappingURL=EventBus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventBus.d.ts","sourceRoot":"","sources":["../src/EventBus.ts"],"names":[],"mappings":"AAAA,KAAK,aAAa,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;AAE/D,UAAU,YAAY;IACpB,WAAW,EAAE,MAAM,IAAI,CAAA;CACxB;AAED,cAAM,QAAQ;IACZ,OAAO,CAAC,MAAM,CAA6C;IAC3D,OAAO,CAAC,SAAS,CAAiB;IAElC;;OAEG;IACH,WAAW;IAIX;;OAEG;IACH,YAAY;IAIZ;;OAEG;IACH,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,YAAY;IAkBpE;;OAEG;IACH,IAAI,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,YAAY;IAStE;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;IAiBjD;;OAEG;IACG,IAAI,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB3D;;OAEG;IACH,QAAQ,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI;IAqBhD;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAgB3B;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAIrB;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAIvC;;OAEG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAGrC;AAGD,eAAO,MAAM,QAAQ,UAAiB,CAAA;AAGtC,OAAO,EAAE,QAAQ,EAAE,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EventBus.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/EventBus.test.ts"],"names":[],"mappings":""}
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event name constants
|
|
3
|
+
* Use these instead of raw strings to get TypeScript autocomplete
|
|
4
|
+
*/
|
|
5
|
+
export declare const EVENTS: {
|
|
6
|
+
readonly AUTH_USER_LOGGED_IN: "auth:user_logged_in";
|
|
7
|
+
readonly AUTH_USER_LOGGED_OUT: "auth:user_logged_out";
|
|
8
|
+
readonly AUTH_SESSION_EXPIRED: "auth:session_expired";
|
|
9
|
+
readonly AUTH_USER_UPDATED: "auth:user_updated";
|
|
10
|
+
readonly CLIENT_CREATED: "client:created";
|
|
11
|
+
readonly CLIENT_UPDATED: "client:updated";
|
|
12
|
+
readonly CLIENT_DELETED: "client:deleted";
|
|
13
|
+
readonly CLIENT_ARCHIVED: "client:archived";
|
|
14
|
+
readonly APPOINTMENT_CREATED: "appointment:created";
|
|
15
|
+
readonly APPOINTMENT_UPDATED: "appointment:updated";
|
|
16
|
+
readonly APPOINTMENT_CANCELLED: "appointment:cancelled";
|
|
17
|
+
readonly APPOINTMENT_COMPLETED: "appointment:completed";
|
|
18
|
+
readonly APPOINTMENT_NO_SHOW: "appointment:no_show";
|
|
19
|
+
readonly WORKFLOW_STARTED: "workflow:started";
|
|
20
|
+
readonly WORKFLOW_STEP_COMPLETED: "workflow:step_completed";
|
|
21
|
+
readonly WORKFLOW_COMPLETED: "workflow:completed";
|
|
22
|
+
readonly WORKFLOW_FAILED: "workflow:failed";
|
|
23
|
+
readonly INVENTORY_ITEM_CREATED: "inventory:item_created";
|
|
24
|
+
readonly INVENTORY_ITEM_UPDATED: "inventory:item_updated";
|
|
25
|
+
readonly INVENTORY_STOCK_DEDUCTED: "inventory:stock_deducted";
|
|
26
|
+
readonly INVENTORY_STOCK_ADDED: "inventory:stock_added";
|
|
27
|
+
readonly INVENTORY_LOW_STOCK_ALERT: "inventory:low_stock_alert";
|
|
28
|
+
readonly INVENTORY_OUT_OF_STOCK: "inventory:out_of_stock";
|
|
29
|
+
readonly INVOICE_CREATED: "billing:invoice_created";
|
|
30
|
+
readonly INVOICE_UPDATED: "billing:invoice_updated";
|
|
31
|
+
readonly INVOICE_PAID: "billing:invoice_paid";
|
|
32
|
+
readonly INVOICE_CANCELLED: "billing:invoice_cancelled";
|
|
33
|
+
readonly PAYMENT_RECEIVED: "billing:payment_received";
|
|
34
|
+
readonly PAYMENT_FAILED: "billing:payment_failed";
|
|
35
|
+
readonly ASSET_MAINTENANCE_DUE: "asset:maintenance_due";
|
|
36
|
+
readonly ASSET_MAINTENANCE_COMPLETED: "asset:maintenance_completed";
|
|
37
|
+
readonly ASSET_UNAVAILABLE: "asset:unavailable";
|
|
38
|
+
readonly ASSET_AVAILABLE: "asset:available";
|
|
39
|
+
readonly CLAIM_SUBMITTED: "claims:submitted";
|
|
40
|
+
readonly CLAIM_APPROVED: "claims:approved";
|
|
41
|
+
readonly CLAIM_REJECTED: "claims:rejected";
|
|
42
|
+
readonly CLAIM_PAID: "claims:paid";
|
|
43
|
+
readonly NOTIFICATION_CREATED: "notification:created";
|
|
44
|
+
readonly NOTIFICATION_READ: "notification:read";
|
|
45
|
+
readonly SYSTEM_ERROR: "system:error";
|
|
46
|
+
readonly SYSTEM_WARNING: "system:warning";
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Type-safe event data interfaces
|
|
50
|
+
*/
|
|
51
|
+
export interface ClientCreatedEvent {
|
|
52
|
+
clientId: string;
|
|
53
|
+
tenantId: string;
|
|
54
|
+
clientName: string;
|
|
55
|
+
createdBy: string;
|
|
56
|
+
}
|
|
57
|
+
export interface ClientUpdatedEvent {
|
|
58
|
+
clientId: string;
|
|
59
|
+
tenantId: string;
|
|
60
|
+
changes: Record<string, any>;
|
|
61
|
+
updatedBy: string;
|
|
62
|
+
}
|
|
63
|
+
export interface AppointmentCreatedEvent {
|
|
64
|
+
appointmentId: string;
|
|
65
|
+
clientId: string;
|
|
66
|
+
tenantId: string;
|
|
67
|
+
scheduledTime: string;
|
|
68
|
+
serviceType: string;
|
|
69
|
+
createdBy: string;
|
|
70
|
+
}
|
|
71
|
+
export interface InventoryStockDeductedEvent {
|
|
72
|
+
tenantId: string;
|
|
73
|
+
referenceType: 'workflow' | 'appointment' | 'sale' | 'adjustment';
|
|
74
|
+
referenceId: string;
|
|
75
|
+
items: Array<{
|
|
76
|
+
itemId: string;
|
|
77
|
+
itemCode: string;
|
|
78
|
+
itemName: string;
|
|
79
|
+
quantity: number;
|
|
80
|
+
newStockLevel: number;
|
|
81
|
+
}>;
|
|
82
|
+
deductedBy: string;
|
|
83
|
+
timestamp: string;
|
|
84
|
+
}
|
|
85
|
+
export interface InventoryLowStockAlertEvent {
|
|
86
|
+
tenantId: string;
|
|
87
|
+
itemId: string;
|
|
88
|
+
itemCode: string;
|
|
89
|
+
itemName: string;
|
|
90
|
+
currentStock: number;
|
|
91
|
+
minimumStock: number;
|
|
92
|
+
reorderPoint: number;
|
|
93
|
+
}
|
|
94
|
+
export interface InvoiceCreatedEvent {
|
|
95
|
+
invoiceId: string;
|
|
96
|
+
tenantId: string;
|
|
97
|
+
clientId: string;
|
|
98
|
+
amount: number;
|
|
99
|
+
currency: string;
|
|
100
|
+
dueDate: string;
|
|
101
|
+
createdBy: string;
|
|
102
|
+
}
|
|
103
|
+
export interface PaymentReceivedEvent {
|
|
104
|
+
paymentId: string;
|
|
105
|
+
invoiceId: string;
|
|
106
|
+
tenantId: string;
|
|
107
|
+
amount: number;
|
|
108
|
+
paymentMethod: string;
|
|
109
|
+
receivedBy: string;
|
|
110
|
+
timestamp: string;
|
|
111
|
+
}
|
|
112
|
+
export interface WorkflowCompletedEvent {
|
|
113
|
+
workflowId: string;
|
|
114
|
+
workflowType: string;
|
|
115
|
+
tenantId: string;
|
|
116
|
+
referenceType: string;
|
|
117
|
+
referenceId: string;
|
|
118
|
+
completedBy: string;
|
|
119
|
+
duration: number;
|
|
120
|
+
timestamp: string;
|
|
121
|
+
}
|
|
122
|
+
export interface SystemErrorEvent {
|
|
123
|
+
errorId: string;
|
|
124
|
+
errorType: string;
|
|
125
|
+
message: string;
|
|
126
|
+
stackTrace?: string;
|
|
127
|
+
context?: Record<string, any>;
|
|
128
|
+
timestamp: string;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Helper type to extract event data type from event name
|
|
132
|
+
*/
|
|
133
|
+
export type EventData<E extends string> = E extends typeof EVENTS.CLIENT_CREATED ? ClientCreatedEvent : E extends typeof EVENTS.CLIENT_UPDATED ? ClientUpdatedEvent : E extends typeof EVENTS.APPOINTMENT_CREATED ? AppointmentCreatedEvent : E extends typeof EVENTS.INVENTORY_STOCK_DEDUCTED ? InventoryStockDeductedEvent : E extends typeof EVENTS.INVENTORY_LOW_STOCK_ALERT ? InventoryLowStockAlertEvent : E extends typeof EVENTS.INVOICE_CREATED ? InvoiceCreatedEvent : E extends typeof EVENTS.PAYMENT_RECEIVED ? PaymentReceivedEvent : E extends typeof EVENTS.WORKFLOW_COMPLETED ? WorkflowCompletedEvent : E extends typeof EVENTS.SYSTEM_ERROR ? SystemErrorEvent : any;
|
|
134
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { EventBus, eventBus } from './EventBus';
|
|
2
|
+
export { EVENTS } from './events';
|
|
3
|
+
export type { ClientCreatedEvent, ClientUpdatedEvent, AppointmentCreatedEvent, InventoryStockDeductedEvent, InventoryLowStockAlertEvent, InvoiceCreatedEvent, PaymentReceivedEvent, WorkflowCompletedEvent, SystemErrorEvent, EventData, } from './events';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,gBAAgB,EAChB,SAAS,GACV,MAAM,UAAU,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class E{constructor(){this.events=new Map,this.debugMode=!1}enableDebug(){this.debugMode=!0}disableDebug(){this.debugMode=!1}on(e,s){return this.events.has(e)||this.events.set(e,new Set),this.events.get(e).add(s),this.debugMode&&console.log(`[EventBus] Subscribed to "${e}"`,{totalListeners:this.events.get(e).size}),{unsubscribe:()=>this.off(e,s)}}once(e,s){const t=async i=>{await s(i),this.off(e,t)};return this.on(e,t)}off(e,s){const t=this.events.get(e);t&&(t.delete(s),t.size===0&&this.events.delete(e),this.debugMode&&console.log(`[EventBus] Unsubscribed from "${e}"`,{remainingListeners:t.size}))}async emit(e,s){const t=this.events.get(e);if(this.debugMode&&console.log(`[EventBus] Emitting "${e}"`,{data:s,listeners:t?.size||0}),t){const i=Array.from(t).map(n=>{try{return n(s)}catch(o){return console.error(`[EventBus] Error in callback for "${e}":`,o),Promise.reject(o)}});await Promise.all(i)}}emitSync(e,s){const t=this.events.get(e);this.debugMode&&console.log(`[EventBus] Emitting (sync) "${e}"`,{data:s,listeners:t?.size||0}),t&&t.forEach(i=>{try{i(s)}catch(n){console.error(`[EventBus] Error in callback for "${e}":`,n)}})}clear(e){e?(this.events.delete(e),this.debugMode&&console.log(`[EventBus] Cleared all listeners for "${e}"`)):(this.events.clear(),this.debugMode&&console.log("[EventBus] Cleared all listeners for all events"))}getEvents(){return Array.from(this.events.keys())}getListenerCount(e){return this.events.get(e)?.size||0}hasListeners(e){return this.getListenerCount(e)>0}}const r=new E,l={AUTH_USER_LOGGED_IN:"auth:user_logged_in",AUTH_USER_LOGGED_OUT:"auth:user_logged_out",AUTH_SESSION_EXPIRED:"auth:session_expired",AUTH_USER_UPDATED:"auth:user_updated",CLIENT_CREATED:"client:created",CLIENT_UPDATED:"client:updated",CLIENT_DELETED:"client:deleted",CLIENT_ARCHIVED:"client:archived",APPOINTMENT_CREATED:"appointment:created",APPOINTMENT_UPDATED:"appointment:updated",APPOINTMENT_CANCELLED:"appointment:cancelled",APPOINTMENT_COMPLETED:"appointment:completed",APPOINTMENT_NO_SHOW:"appointment:no_show",WORKFLOW_STARTED:"workflow:started",WORKFLOW_STEP_COMPLETED:"workflow:step_completed",WORKFLOW_COMPLETED:"workflow:completed",WORKFLOW_FAILED:"workflow:failed",INVENTORY_ITEM_CREATED:"inventory:item_created",INVENTORY_ITEM_UPDATED:"inventory:item_updated",INVENTORY_STOCK_DEDUCTED:"inventory:stock_deducted",INVENTORY_STOCK_ADDED:"inventory:stock_added",INVENTORY_LOW_STOCK_ALERT:"inventory:low_stock_alert",INVENTORY_OUT_OF_STOCK:"inventory:out_of_stock",INVOICE_CREATED:"billing:invoice_created",INVOICE_UPDATED:"billing:invoice_updated",INVOICE_PAID:"billing:invoice_paid",INVOICE_CANCELLED:"billing:invoice_cancelled",PAYMENT_RECEIVED:"billing:payment_received",PAYMENT_FAILED:"billing:payment_failed",ASSET_MAINTENANCE_DUE:"asset:maintenance_due",ASSET_MAINTENANCE_COMPLETED:"asset:maintenance_completed",ASSET_UNAVAILABLE:"asset:unavailable",ASSET_AVAILABLE:"asset:available",CLAIM_SUBMITTED:"claims:submitted",CLAIM_APPROVED:"claims:approved",CLAIM_REJECTED:"claims:rejected",CLAIM_PAID:"claims:paid",NOTIFICATION_CREATED:"notification:created",NOTIFICATION_READ:"notification:read",SYSTEM_ERROR:"system:error",SYSTEM_WARNING:"system:warning"};exports.EVENTS=l;exports.EventBus=E;exports.eventBus=r;
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/EventBus.ts","../src/events.ts"],"sourcesContent":["type EventCallback<T = any> = (data: T) => void | Promise<void>\n\ninterface Subscription {\n unsubscribe: () => void\n}\n\nclass EventBus {\n private events: Map<string, Set<EventCallback>> = new Map()\n private debugMode: boolean = false\n\n /**\n * Enable debug logging\n */\n enableDebug() {\n this.debugMode = true\n }\n\n /**\n * Disable debug logging\n */\n disableDebug() {\n this.debugMode = false\n }\n\n /**\n * Subscribe to an event\n */\n on<T = any>(event: string, callback: EventCallback<T>): Subscription {\n if (!this.events.has(event)) {\n this.events.set(event, new Set())\n }\n\n this.events.get(event)!.add(callback)\n\n if (this.debugMode) {\n console.log(`[EventBus] Subscribed to \"${event}\"`, {\n totalListeners: this.events.get(event)!.size\n })\n }\n\n return {\n unsubscribe: () => this.off(event, callback)\n }\n }\n\n /**\n * Subscribe to an event (one-time only)\n */\n once<T = any>(event: string, callback: EventCallback<T>): Subscription {\n const wrappedCallback: EventCallback<T> = async (data) => {\n await callback(data)\n this.off(event, wrappedCallback)\n }\n\n return this.on(event, wrappedCallback)\n }\n\n /**\n * Unsubscribe from an event\n */\n off(event: string, callback: EventCallback): void {\n const callbacks = this.events.get(event)\n if (callbacks) {\n callbacks.delete(callback)\n \n if (callbacks.size === 0) {\n this.events.delete(event)\n }\n\n if (this.debugMode) {\n console.log(`[EventBus] Unsubscribed from \"${event}\"`, {\n remainingListeners: callbacks.size\n })\n }\n }\n }\n\n /**\n * Emit an event\n */\n async emit<T = any>(event: string, data?: T): Promise<void> {\n const callbacks = this.events.get(event)\n\n if (this.debugMode) {\n console.log(`[EventBus] Emitting \"${event}\"`, {\n data,\n listeners: callbacks?.size || 0\n })\n }\n\n if (callbacks) {\n const promises = Array.from(callbacks).map(callback => {\n try {\n return callback(data)\n } catch (error) {\n console.error(`[EventBus] Error in callback for \"${event}\":`, error)\n return Promise.reject(error)\n }\n })\n\n await Promise.all(promises)\n }\n }\n\n /**\n * Emit an event synchronously (doesn't wait for async callbacks)\n */\n emitSync<T = any>(event: string, data?: T): void {\n const callbacks = this.events.get(event)\n\n if (this.debugMode) {\n console.log(`[EventBus] Emitting (sync) \"${event}\"`, {\n data,\n listeners: callbacks?.size || 0\n })\n }\n\n if (callbacks) {\n callbacks.forEach(callback => {\n try {\n callback(data)\n } catch (error) {\n console.error(`[EventBus] Error in callback for \"${event}\":`, error)\n }\n })\n }\n }\n\n /**\n * Remove all listeners for an event, or all events if no event specified\n */\n clear(event?: string): void {\n if (event) {\n this.events.delete(event)\n \n if (this.debugMode) {\n console.log(`[EventBus] Cleared all listeners for \"${event}\"`)\n }\n } else {\n this.events.clear()\n \n if (this.debugMode) {\n console.log('[EventBus] Cleared all listeners for all events')\n }\n }\n }\n\n /**\n * Get list of all events with active listeners\n */\n getEvents(): string[] {\n return Array.from(this.events.keys())\n }\n\n /**\n * Get number of listeners for an event\n */\n getListenerCount(event: string): number {\n return this.events.get(event)?.size || 0\n }\n\n /**\n * Check if an event has any listeners\n */\n hasListeners(event: string): boolean {\n return this.getListenerCount(event) > 0\n }\n}\n\n// Create singleton instance\nexport const eventBus = new EventBus()\n\n// Also export class for testing or multiple instances\nexport { EventBus }\n","/**\n * Event name constants\n * Use these instead of raw strings to get TypeScript autocomplete\n */\nexport const EVENTS = {\n // Authentication events\n AUTH_USER_LOGGED_IN: 'auth:user_logged_in',\n AUTH_USER_LOGGED_OUT: 'auth:user_logged_out',\n AUTH_SESSION_EXPIRED: 'auth:session_expired',\n AUTH_USER_UPDATED: 'auth:user_updated',\n\n // Client management events\n CLIENT_CREATED: 'client:created',\n CLIENT_UPDATED: 'client:updated',\n CLIENT_DELETED: 'client:deleted',\n CLIENT_ARCHIVED: 'client:archived',\n\n // Appointment events\n APPOINTMENT_CREATED: 'appointment:created',\n APPOINTMENT_UPDATED: 'appointment:updated',\n APPOINTMENT_CANCELLED: 'appointment:cancelled',\n APPOINTMENT_COMPLETED: 'appointment:completed',\n APPOINTMENT_NO_SHOW: 'appointment:no_show',\n\n // Workflow events\n WORKFLOW_STARTED: 'workflow:started',\n WORKFLOW_STEP_COMPLETED: 'workflow:step_completed',\n WORKFLOW_COMPLETED: 'workflow:completed',\n WORKFLOW_FAILED: 'workflow:failed',\n\n // Inventory events\n INVENTORY_ITEM_CREATED: 'inventory:item_created',\n INVENTORY_ITEM_UPDATED: 'inventory:item_updated',\n INVENTORY_STOCK_DEDUCTED: 'inventory:stock_deducted',\n INVENTORY_STOCK_ADDED: 'inventory:stock_added',\n INVENTORY_LOW_STOCK_ALERT: 'inventory:low_stock_alert',\n INVENTORY_OUT_OF_STOCK: 'inventory:out_of_stock',\n\n // Billing events\n INVOICE_CREATED: 'billing:invoice_created',\n INVOICE_UPDATED: 'billing:invoice_updated',\n INVOICE_PAID: 'billing:invoice_paid',\n INVOICE_CANCELLED: 'billing:invoice_cancelled',\n PAYMENT_RECEIVED: 'billing:payment_received',\n PAYMENT_FAILED: 'billing:payment_failed',\n\n // Asset events\n ASSET_MAINTENANCE_DUE: 'asset:maintenance_due',\n ASSET_MAINTENANCE_COMPLETED: 'asset:maintenance_completed',\n ASSET_UNAVAILABLE: 'asset:unavailable',\n ASSET_AVAILABLE: 'asset:available',\n\n // Claims events\n CLAIM_SUBMITTED: 'claims:submitted',\n CLAIM_APPROVED: 'claims:approved',\n CLAIM_REJECTED: 'claims:rejected',\n CLAIM_PAID: 'claims:paid',\n\n // Notification events\n NOTIFICATION_CREATED: 'notification:created',\n NOTIFICATION_READ: 'notification:read',\n\n // System events\n SYSTEM_ERROR: 'system:error',\n SYSTEM_WARNING: 'system:warning',\n} as const\n\n/**\n * Type-safe event data interfaces\n */\n\nexport interface ClientCreatedEvent {\n clientId: string\n tenantId: string\n clientName: string\n createdBy: string\n}\n\nexport interface ClientUpdatedEvent {\n clientId: string\n tenantId: string\n changes: Record<string, any>\n updatedBy: string\n}\n\nexport interface AppointmentCreatedEvent {\n appointmentId: string\n clientId: string\n tenantId: string\n scheduledTime: string\n serviceType: string\n createdBy: string\n}\n\nexport interface InventoryStockDeductedEvent {\n tenantId: string\n referenceType: 'workflow' | 'appointment' | 'sale' | 'adjustment'\n referenceId: string\n items: Array<{\n itemId: string\n itemCode: string\n itemName: string\n quantity: number\n newStockLevel: number\n }>\n deductedBy: string\n timestamp: string\n}\n\nexport interface InventoryLowStockAlertEvent {\n tenantId: string\n itemId: string\n itemCode: string\n itemName: string\n currentStock: number\n minimumStock: number\n reorderPoint: number\n}\n\nexport interface InvoiceCreatedEvent {\n invoiceId: string\n tenantId: string\n clientId: string\n amount: number\n currency: string\n dueDate: string\n createdBy: string\n}\n\nexport interface PaymentReceivedEvent {\n paymentId: string\n invoiceId: string\n tenantId: string\n amount: number\n paymentMethod: string\n receivedBy: string\n timestamp: string\n}\n\nexport interface WorkflowCompletedEvent {\n workflowId: string\n workflowType: string\n tenantId: string\n referenceType: string\n referenceId: string\n completedBy: string\n duration: number // milliseconds\n timestamp: string\n}\n\nexport interface SystemErrorEvent {\n errorId: string\n errorType: string\n message: string\n stackTrace?: string\n context?: Record<string, any>\n timestamp: string\n}\n\n/**\n * Helper type to extract event data type from event name\n */\nexport type EventData<E extends string> = \n E extends typeof EVENTS.CLIENT_CREATED ? ClientCreatedEvent :\n E extends typeof EVENTS.CLIENT_UPDATED ? ClientUpdatedEvent :\n E extends typeof EVENTS.APPOINTMENT_CREATED ? AppointmentCreatedEvent :\n E extends typeof EVENTS.INVENTORY_STOCK_DEDUCTED ? InventoryStockDeductedEvent :\n E extends typeof EVENTS.INVENTORY_LOW_STOCK_ALERT ? InventoryLowStockAlertEvent :\n E extends typeof EVENTS.INVOICE_CREATED ? InvoiceCreatedEvent :\n E extends typeof EVENTS.PAYMENT_RECEIVED ? PaymentReceivedEvent :\n E extends typeof EVENTS.WORKFLOW_COMPLETED ? WorkflowCompletedEvent :\n E extends typeof EVENTS.SYSTEM_ERROR ? SystemErrorEvent :\n any\n"],"names":["EventBus","event","callback","wrappedCallback","data","callbacks","promises","error","eventBus","EVENTS"],"mappings":"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"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
class E {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.events = /* @__PURE__ */ new Map(), this.debugMode = !1;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Enable debug logging
|
|
7
|
+
*/
|
|
8
|
+
enableDebug() {
|
|
9
|
+
this.debugMode = !0;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Disable debug logging
|
|
13
|
+
*/
|
|
14
|
+
disableDebug() {
|
|
15
|
+
this.debugMode = !1;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Subscribe to an event
|
|
19
|
+
*/
|
|
20
|
+
on(e, s) {
|
|
21
|
+
return this.events.has(e) || this.events.set(e, /* @__PURE__ */ new Set()), this.events.get(e).add(s), this.debugMode && console.log(`[EventBus] Subscribed to "${e}"`, {
|
|
22
|
+
totalListeners: this.events.get(e).size
|
|
23
|
+
}), {
|
|
24
|
+
unsubscribe: () => this.off(e, s)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Subscribe to an event (one-time only)
|
|
29
|
+
*/
|
|
30
|
+
once(e, s) {
|
|
31
|
+
const t = async (i) => {
|
|
32
|
+
await s(i), this.off(e, t);
|
|
33
|
+
};
|
|
34
|
+
return this.on(e, t);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Unsubscribe from an event
|
|
38
|
+
*/
|
|
39
|
+
off(e, s) {
|
|
40
|
+
const t = this.events.get(e);
|
|
41
|
+
t && (t.delete(s), t.size === 0 && this.events.delete(e), this.debugMode && console.log(`[EventBus] Unsubscribed from "${e}"`, {
|
|
42
|
+
remainingListeners: t.size
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Emit an event
|
|
47
|
+
*/
|
|
48
|
+
async emit(e, s) {
|
|
49
|
+
const t = this.events.get(e);
|
|
50
|
+
if (this.debugMode && console.log(`[EventBus] Emitting "${e}"`, {
|
|
51
|
+
data: s,
|
|
52
|
+
listeners: t?.size || 0
|
|
53
|
+
}), t) {
|
|
54
|
+
const i = Array.from(t).map((n) => {
|
|
55
|
+
try {
|
|
56
|
+
return n(s);
|
|
57
|
+
} catch (o) {
|
|
58
|
+
return console.error(`[EventBus] Error in callback for "${e}":`, o), Promise.reject(o);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
await Promise.all(i);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Emit an event synchronously (doesn't wait for async callbacks)
|
|
66
|
+
*/
|
|
67
|
+
emitSync(e, s) {
|
|
68
|
+
const t = this.events.get(e);
|
|
69
|
+
this.debugMode && console.log(`[EventBus] Emitting (sync) "${e}"`, {
|
|
70
|
+
data: s,
|
|
71
|
+
listeners: t?.size || 0
|
|
72
|
+
}), t && t.forEach((i) => {
|
|
73
|
+
try {
|
|
74
|
+
i(s);
|
|
75
|
+
} catch (n) {
|
|
76
|
+
console.error(`[EventBus] Error in callback for "${e}":`, n);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Remove all listeners for an event, or all events if no event specified
|
|
82
|
+
*/
|
|
83
|
+
clear(e) {
|
|
84
|
+
e ? (this.events.delete(e), this.debugMode && console.log(`[EventBus] Cleared all listeners for "${e}"`)) : (this.events.clear(), this.debugMode && console.log("[EventBus] Cleared all listeners for all events"));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get list of all events with active listeners
|
|
88
|
+
*/
|
|
89
|
+
getEvents() {
|
|
90
|
+
return Array.from(this.events.keys());
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get number of listeners for an event
|
|
94
|
+
*/
|
|
95
|
+
getListenerCount(e) {
|
|
96
|
+
return this.events.get(e)?.size || 0;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check if an event has any listeners
|
|
100
|
+
*/
|
|
101
|
+
hasListeners(e) {
|
|
102
|
+
return this.getListenerCount(e) > 0;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const l = new E(), a = {
|
|
106
|
+
// Authentication events
|
|
107
|
+
AUTH_USER_LOGGED_IN: "auth:user_logged_in",
|
|
108
|
+
AUTH_USER_LOGGED_OUT: "auth:user_logged_out",
|
|
109
|
+
AUTH_SESSION_EXPIRED: "auth:session_expired",
|
|
110
|
+
AUTH_USER_UPDATED: "auth:user_updated",
|
|
111
|
+
// Client management events
|
|
112
|
+
CLIENT_CREATED: "client:created",
|
|
113
|
+
CLIENT_UPDATED: "client:updated",
|
|
114
|
+
CLIENT_DELETED: "client:deleted",
|
|
115
|
+
CLIENT_ARCHIVED: "client:archived",
|
|
116
|
+
// Appointment events
|
|
117
|
+
APPOINTMENT_CREATED: "appointment:created",
|
|
118
|
+
APPOINTMENT_UPDATED: "appointment:updated",
|
|
119
|
+
APPOINTMENT_CANCELLED: "appointment:cancelled",
|
|
120
|
+
APPOINTMENT_COMPLETED: "appointment:completed",
|
|
121
|
+
APPOINTMENT_NO_SHOW: "appointment:no_show",
|
|
122
|
+
// Workflow events
|
|
123
|
+
WORKFLOW_STARTED: "workflow:started",
|
|
124
|
+
WORKFLOW_STEP_COMPLETED: "workflow:step_completed",
|
|
125
|
+
WORKFLOW_COMPLETED: "workflow:completed",
|
|
126
|
+
WORKFLOW_FAILED: "workflow:failed",
|
|
127
|
+
// Inventory events
|
|
128
|
+
INVENTORY_ITEM_CREATED: "inventory:item_created",
|
|
129
|
+
INVENTORY_ITEM_UPDATED: "inventory:item_updated",
|
|
130
|
+
INVENTORY_STOCK_DEDUCTED: "inventory:stock_deducted",
|
|
131
|
+
INVENTORY_STOCK_ADDED: "inventory:stock_added",
|
|
132
|
+
INVENTORY_LOW_STOCK_ALERT: "inventory:low_stock_alert",
|
|
133
|
+
INVENTORY_OUT_OF_STOCK: "inventory:out_of_stock",
|
|
134
|
+
// Billing events
|
|
135
|
+
INVOICE_CREATED: "billing:invoice_created",
|
|
136
|
+
INVOICE_UPDATED: "billing:invoice_updated",
|
|
137
|
+
INVOICE_PAID: "billing:invoice_paid",
|
|
138
|
+
INVOICE_CANCELLED: "billing:invoice_cancelled",
|
|
139
|
+
PAYMENT_RECEIVED: "billing:payment_received",
|
|
140
|
+
PAYMENT_FAILED: "billing:payment_failed",
|
|
141
|
+
// Asset events
|
|
142
|
+
ASSET_MAINTENANCE_DUE: "asset:maintenance_due",
|
|
143
|
+
ASSET_MAINTENANCE_COMPLETED: "asset:maintenance_completed",
|
|
144
|
+
ASSET_UNAVAILABLE: "asset:unavailable",
|
|
145
|
+
ASSET_AVAILABLE: "asset:available",
|
|
146
|
+
// Claims events
|
|
147
|
+
CLAIM_SUBMITTED: "claims:submitted",
|
|
148
|
+
CLAIM_APPROVED: "claims:approved",
|
|
149
|
+
CLAIM_REJECTED: "claims:rejected",
|
|
150
|
+
CLAIM_PAID: "claims:paid",
|
|
151
|
+
// Notification events
|
|
152
|
+
NOTIFICATION_CREATED: "notification:created",
|
|
153
|
+
NOTIFICATION_READ: "notification:read",
|
|
154
|
+
// System events
|
|
155
|
+
SYSTEM_ERROR: "system:error",
|
|
156
|
+
SYSTEM_WARNING: "system:warning"
|
|
157
|
+
};
|
|
158
|
+
export {
|
|
159
|
+
a as EVENTS,
|
|
160
|
+
E as EventBus,
|
|
161
|
+
l as eventBus
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/EventBus.ts","../src/events.ts"],"sourcesContent":["type EventCallback<T = any> = (data: T) => void | Promise<void>\n\ninterface Subscription {\n unsubscribe: () => void\n}\n\nclass EventBus {\n private events: Map<string, Set<EventCallback>> = new Map()\n private debugMode: boolean = false\n\n /**\n * Enable debug logging\n */\n enableDebug() {\n this.debugMode = true\n }\n\n /**\n * Disable debug logging\n */\n disableDebug() {\n this.debugMode = false\n }\n\n /**\n * Subscribe to an event\n */\n on<T = any>(event: string, callback: EventCallback<T>): Subscription {\n if (!this.events.has(event)) {\n this.events.set(event, new Set())\n }\n\n this.events.get(event)!.add(callback)\n\n if (this.debugMode) {\n console.log(`[EventBus] Subscribed to \"${event}\"`, {\n totalListeners: this.events.get(event)!.size\n })\n }\n\n return {\n unsubscribe: () => this.off(event, callback)\n }\n }\n\n /**\n * Subscribe to an event (one-time only)\n */\n once<T = any>(event: string, callback: EventCallback<T>): Subscription {\n const wrappedCallback: EventCallback<T> = async (data) => {\n await callback(data)\n this.off(event, wrappedCallback)\n }\n\n return this.on(event, wrappedCallback)\n }\n\n /**\n * Unsubscribe from an event\n */\n off(event: string, callback: EventCallback): void {\n const callbacks = this.events.get(event)\n if (callbacks) {\n callbacks.delete(callback)\n \n if (callbacks.size === 0) {\n this.events.delete(event)\n }\n\n if (this.debugMode) {\n console.log(`[EventBus] Unsubscribed from \"${event}\"`, {\n remainingListeners: callbacks.size\n })\n }\n }\n }\n\n /**\n * Emit an event\n */\n async emit<T = any>(event: string, data?: T): Promise<void> {\n const callbacks = this.events.get(event)\n\n if (this.debugMode) {\n console.log(`[EventBus] Emitting \"${event}\"`, {\n data,\n listeners: callbacks?.size || 0\n })\n }\n\n if (callbacks) {\n const promises = Array.from(callbacks).map(callback => {\n try {\n return callback(data)\n } catch (error) {\n console.error(`[EventBus] Error in callback for \"${event}\":`, error)\n return Promise.reject(error)\n }\n })\n\n await Promise.all(promises)\n }\n }\n\n /**\n * Emit an event synchronously (doesn't wait for async callbacks)\n */\n emitSync<T = any>(event: string, data?: T): void {\n const callbacks = this.events.get(event)\n\n if (this.debugMode) {\n console.log(`[EventBus] Emitting (sync) \"${event}\"`, {\n data,\n listeners: callbacks?.size || 0\n })\n }\n\n if (callbacks) {\n callbacks.forEach(callback => {\n try {\n callback(data)\n } catch (error) {\n console.error(`[EventBus] Error in callback for \"${event}\":`, error)\n }\n })\n }\n }\n\n /**\n * Remove all listeners for an event, or all events if no event specified\n */\n clear(event?: string): void {\n if (event) {\n this.events.delete(event)\n \n if (this.debugMode) {\n console.log(`[EventBus] Cleared all listeners for \"${event}\"`)\n }\n } else {\n this.events.clear()\n \n if (this.debugMode) {\n console.log('[EventBus] Cleared all listeners for all events')\n }\n }\n }\n\n /**\n * Get list of all events with active listeners\n */\n getEvents(): string[] {\n return Array.from(this.events.keys())\n }\n\n /**\n * Get number of listeners for an event\n */\n getListenerCount(event: string): number {\n return this.events.get(event)?.size || 0\n }\n\n /**\n * Check if an event has any listeners\n */\n hasListeners(event: string): boolean {\n return this.getListenerCount(event) > 0\n }\n}\n\n// Create singleton instance\nexport const eventBus = new EventBus()\n\n// Also export class for testing or multiple instances\nexport { EventBus }\n","/**\n * Event name constants\n * Use these instead of raw strings to get TypeScript autocomplete\n */\nexport const EVENTS = {\n // Authentication events\n AUTH_USER_LOGGED_IN: 'auth:user_logged_in',\n AUTH_USER_LOGGED_OUT: 'auth:user_logged_out',\n AUTH_SESSION_EXPIRED: 'auth:session_expired',\n AUTH_USER_UPDATED: 'auth:user_updated',\n\n // Client management events\n CLIENT_CREATED: 'client:created',\n CLIENT_UPDATED: 'client:updated',\n CLIENT_DELETED: 'client:deleted',\n CLIENT_ARCHIVED: 'client:archived',\n\n // Appointment events\n APPOINTMENT_CREATED: 'appointment:created',\n APPOINTMENT_UPDATED: 'appointment:updated',\n APPOINTMENT_CANCELLED: 'appointment:cancelled',\n APPOINTMENT_COMPLETED: 'appointment:completed',\n APPOINTMENT_NO_SHOW: 'appointment:no_show',\n\n // Workflow events\n WORKFLOW_STARTED: 'workflow:started',\n WORKFLOW_STEP_COMPLETED: 'workflow:step_completed',\n WORKFLOW_COMPLETED: 'workflow:completed',\n WORKFLOW_FAILED: 'workflow:failed',\n\n // Inventory events\n INVENTORY_ITEM_CREATED: 'inventory:item_created',\n INVENTORY_ITEM_UPDATED: 'inventory:item_updated',\n INVENTORY_STOCK_DEDUCTED: 'inventory:stock_deducted',\n INVENTORY_STOCK_ADDED: 'inventory:stock_added',\n INVENTORY_LOW_STOCK_ALERT: 'inventory:low_stock_alert',\n INVENTORY_OUT_OF_STOCK: 'inventory:out_of_stock',\n\n // Billing events\n INVOICE_CREATED: 'billing:invoice_created',\n INVOICE_UPDATED: 'billing:invoice_updated',\n INVOICE_PAID: 'billing:invoice_paid',\n INVOICE_CANCELLED: 'billing:invoice_cancelled',\n PAYMENT_RECEIVED: 'billing:payment_received',\n PAYMENT_FAILED: 'billing:payment_failed',\n\n // Asset events\n ASSET_MAINTENANCE_DUE: 'asset:maintenance_due',\n ASSET_MAINTENANCE_COMPLETED: 'asset:maintenance_completed',\n ASSET_UNAVAILABLE: 'asset:unavailable',\n ASSET_AVAILABLE: 'asset:available',\n\n // Claims events\n CLAIM_SUBMITTED: 'claims:submitted',\n CLAIM_APPROVED: 'claims:approved',\n CLAIM_REJECTED: 'claims:rejected',\n CLAIM_PAID: 'claims:paid',\n\n // Notification events\n NOTIFICATION_CREATED: 'notification:created',\n NOTIFICATION_READ: 'notification:read',\n\n // System events\n SYSTEM_ERROR: 'system:error',\n SYSTEM_WARNING: 'system:warning',\n} as const\n\n/**\n * Type-safe event data interfaces\n */\n\nexport interface ClientCreatedEvent {\n clientId: string\n tenantId: string\n clientName: string\n createdBy: string\n}\n\nexport interface ClientUpdatedEvent {\n clientId: string\n tenantId: string\n changes: Record<string, any>\n updatedBy: string\n}\n\nexport interface AppointmentCreatedEvent {\n appointmentId: string\n clientId: string\n tenantId: string\n scheduledTime: string\n serviceType: string\n createdBy: string\n}\n\nexport interface InventoryStockDeductedEvent {\n tenantId: string\n referenceType: 'workflow' | 'appointment' | 'sale' | 'adjustment'\n referenceId: string\n items: Array<{\n itemId: string\n itemCode: string\n itemName: string\n quantity: number\n newStockLevel: number\n }>\n deductedBy: string\n timestamp: string\n}\n\nexport interface InventoryLowStockAlertEvent {\n tenantId: string\n itemId: string\n itemCode: string\n itemName: string\n currentStock: number\n minimumStock: number\n reorderPoint: number\n}\n\nexport interface InvoiceCreatedEvent {\n invoiceId: string\n tenantId: string\n clientId: string\n amount: number\n currency: string\n dueDate: string\n createdBy: string\n}\n\nexport interface PaymentReceivedEvent {\n paymentId: string\n invoiceId: string\n tenantId: string\n amount: number\n paymentMethod: string\n receivedBy: string\n timestamp: string\n}\n\nexport interface WorkflowCompletedEvent {\n workflowId: string\n workflowType: string\n tenantId: string\n referenceType: string\n referenceId: string\n completedBy: string\n duration: number // milliseconds\n timestamp: string\n}\n\nexport interface SystemErrorEvent {\n errorId: string\n errorType: string\n message: string\n stackTrace?: string\n context?: Record<string, any>\n timestamp: string\n}\n\n/**\n * Helper type to extract event data type from event name\n */\nexport type EventData<E extends string> = \n E extends typeof EVENTS.CLIENT_CREATED ? ClientCreatedEvent :\n E extends typeof EVENTS.CLIENT_UPDATED ? ClientUpdatedEvent :\n E extends typeof EVENTS.APPOINTMENT_CREATED ? AppointmentCreatedEvent :\n E extends typeof EVENTS.INVENTORY_STOCK_DEDUCTED ? InventoryStockDeductedEvent :\n E extends typeof EVENTS.INVENTORY_LOW_STOCK_ALERT ? InventoryLowStockAlertEvent :\n E extends typeof EVENTS.INVOICE_CREATED ? InvoiceCreatedEvent :\n E extends typeof EVENTS.PAYMENT_RECEIVED ? PaymentReceivedEvent :\n E extends typeof EVENTS.WORKFLOW_COMPLETED ? WorkflowCompletedEvent :\n E extends typeof EVENTS.SYSTEM_ERROR ? SystemErrorEvent :\n any\n"],"names":["EventBus","event","callback","wrappedCallback","data","callbacks","promises","error","eventBus","EVENTS"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xaramoge/shared-events",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Event bus for cross-module communication in Xaramoge",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.mjs",
|
|
11
|
+
"require": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc && vite build",
|
|
19
|
+
"test": "vitest",
|
|
20
|
+
"prepublishOnly": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"typescript": "^5.3.3",
|
|
24
|
+
"vite": "^5.0.0",
|
|
25
|
+
"vite-plugin-dts": "^3.7.0",
|
|
26
|
+
"vitest": "^1.1.0"
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/xaramoge/shared-events.git"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"event-bus",
|
|
34
|
+
"pubsub",
|
|
35
|
+
"events",
|
|
36
|
+
"xaramoge"
|
|
37
|
+
],
|
|
38
|
+
"author": "xaramoge Team",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
}
|
|
43
|
+
}
|