feat: introduce core-events package with event bus, hooks, and a web showcase demo

This commit is contained in:
Firman Ramdhani
2026-05-28 11:20:35 +07:00
parent 3621f837f6
commit 6fde65f04e
21 changed files with 2021 additions and 7 deletions
@@ -0,0 +1,82 @@
// ─── Event Payload Types ────────────────────────────────────────
/**
* Receipt line item for the DEVICE:PRINT_RECEIPT event.
*/
export interface ReceiptItem {
name: string;
qty: number;
price: number;
}
/**
* Payload for the DEVICE:PRINT_RECEIPT event.
*/
export interface PrintReceiptPayload {
receiptId: string;
items: ReceiptItem[];
total: number;
cashierName: string;
timestamp: number;
}
/**
* Payload for the WS:STOCK_UPDATE event.
*/
export interface StockUpdatePayload {
id: string;
price: number;
change: number;
volume: number;
}
/**
* Payload for the AUTH:PROFILE_UPDATED event.
*/
export interface ProfileUpdatedPayload {
id: string;
name: string;
email: string;
avatar: string;
updatedAt: number;
}
// ─── Application Event Registry ────────────────────────────────
/**
* Central event registry for the entire application.
*
* Every event in the system MUST be declared here with its payload
* type. This provides:
*
* 1. **Compile-time safety** — typos in event names are caught by TS.
* 2. **Payload validation** — publishers and subscribers agree on shape.
* 3. **Discoverability** — `Ctrl+Click` any event to find its contract.
*
* **Naming convention**: `DOMAIN:ACTION` in `SCREAMING_SNAKE_CASE`.
*
* **Extensibility**: To add events from feature modules, extend this
* type using intersection:
*
* ```ts
* // In your feature module types:
* type InventoryEvents = {
* 'INVENTORY:LOW_STOCK': { productId: string; currentQty: number };
* };
* // Then merge into AppEvents in this file.
* ```
*/
export type AppEvents = {
// ── Device / Hardware ───────────────────────────────────────────
'DEVICE:PRINT_RECEIPT': PrintReceiptPayload;
// ── WebSocket / Real-Time ───────────────────────────────────────
'WS:STOCK_UPDATE': StockUpdatePayload;
// ── Auth / User ─────────────────────────────────────────────────
'AUTH:PROFILE_UPDATED': ProfileUpdatedPayload;
// ── App Lifecycle ───────────────────────────────────────────────
'APP:INITIALIZED': undefined;
'APP:ERROR': { message: string; code?: string };
};