@kumori/aurora-wui-bridge
v1.0.0
Published
connection between the backend and the frontend
Keywords
Readme
WUI Bridge
Table of Contents
Overview
The purpose of this library is to optimize the communication between the frontend and the backend by using an event-driven architecture that decouples event generation from consumption, ensuring that information is propagated efficiently and in real time.
Based on Lit contexts and this robust EDA approach, the solution enables the WUI to automatically react to data changes, delivering a dynamic and highly responsive experience.
Usage
To use this library you need to install it using npm
npm install @aurora/wui-bridge@latestThis library grants a 'globalEventHandler' which the backendHandler and the userContext will need to communicate via events.
Test
Installation
- Install dependencies:
npm installRunning Test
The project uses Jest as the testing framework with TypeScript support via ts-jest. To execute the tests, simply run:
npm run testCoverage
The coverage of the test will be shown on the console where the test have been executed but also in a coverage folder on the repository directory.
Architecture
Core Functionalities
Lit-Based Contexts
The library implements one or more Lit contexts that allow the WUI to subscribe to data streams. This ensures that any change in the data (such as user information or notifications) is immediately reflected in the WUI.
User Data Management
The library handles all necessary backend requests to fetch, update, or create data. A set of helper functions will simplify direct modifications from the WUI, reducing complexity and repetitive code.
By maintaining a centralized context, updates from the backend are automatically propagated to all subscribed components, ensuring consistency across the application.
Periodic and On-Demand Updates
A scheduler is implemented to periodically synchronize the WUI with the backend, making sure that the data remains up to date.
The library also provides a functionality to request specific data updates (such as real-time logs from a running service) which then integrate into the main data context once the request is complete.
Real-Time Notifications and Event Handling
A real-time notification system is integrated to dispatch events to the WUI, enhancing interactivity and providing instant feedback to users.
Event-Driven Architecture
This approach allows the generation of events (such as data changes or notifications) to be decoupled from their consumption, making the system more scalable and maintainable.
The library acts as an intermediary (receiving events from the backend and from user interactions) and then propagating those events to Lit-based contexts for immediate WUI updates.

Key Components
Backend Handler
Receives events from the backend, such as data updates, service logs, or notifications.
Uses WebSocket connections or HTTP requests to listen for changes. Once an event is received, it transforms the data before sending it to the Event Handler, which will update the context causing an update on the WUI.
It also recives events form the WUI (such as updateUserData(userData)) and it makes the request to the API, when it recives a response the backend handler publishes an event (e.g., userDataUpdated(userData)) which is recived by the context subscriber and updates the context causing an update on the WUI.
Event Handler
Acts as the central channel for publishing and subscribing to events.
Producers (Backend Handler / WUI) publish events (e.g., eventHandler.updateUserData(userData);) and the subscribers (Lit contexts / Backend Handler) react to them, executing the function needed for each event (e.g., context.updateUserData(data); / backendHandler.updateUserData(data); ).
My intention is to have a wide variety of events (eventHandler.updateUserData(), eventHandler.deployService(), eventHandler.createOrg()...) describing all the possible cases so I can controll the types of the data as much as I can.
Lit-Based Contexts
Consumes events from the Event Handler to update reactive data sources used by the WUI. For instance, a "User Context" updates its internal state when a "UserUpdated" event is received.
Contexts subscribe to relevant event types from the Event Handler. Upon receiving an event, they update their internal state, triggering Lit’s reactivity to update the WUI.
WUI and Event Handler
Emit events generated by internal application actions (e.g., user requests to refresh data or update logs). Each module can register its own event handlers with the Event Handler. For example, a button click to refresh service logs might emit a "ServiceLogRefreshRequested" event, which then triggers an api request and if everything goes right, the appropriate context update (which triggers the data on the WUI to update).
Use Cases
The user wants to see the logs of a determinate service.

Flow:
- The user makes a log request.
- The UI publishes an event. [RequestLogs(Service)]
- The backend subscriber gets the event and fetches the data. [RequestLogs(Service)]
- The backend publishes a new event with the log data. [updateServiceData(data)]
- The context subscriber gets the event and refreshes the WUI with the data. [updateServiceData(data)]
The user deploys a new service

Flow:
- The user deploys a new servie.
- The WUI publishes en event. [deployService(Service)]
- The backend handler subscriber gets the event and makes the request. [deployService(Service)].
- The context subscriber also gets the event and creates a service with a pending status. [deployService(Service)]
- As the contexts is updated, the WUI automatically refreshes with the new data.
The service deploys without any problems.

Flow:
- The backend handler revices an OK form the API regarding the deployment.
- The backend handler publishes an event. [serviceDeployed(Service)]
- The context subscriber gets the event and changes the deployment status to deployed. [serviceDeployed(Service)]
- As the contexts is updated, the WUI automatically refreshes with the new data.
There is an error on the service deployment.

Flow:
- The backend handler revices an ERROR form the API regarding the deployment.
- The backend handler publishes an event. [deploymentError(Service)]
- The context subscriber gets the event and changes the deployment status to error. [deploymentError(Service)]
- As the contexts is updated, the WUI automatically refreshes with the new data.
Scheduled data update

Flow:
- Every minute the user information is updated by the backend handler. [updateUserInfo()]
- The backend hablder publishes an event with the updated data. [updateUserData(data)]
- The context subscriber gets the event and updated the context. [updateUserData(data)]
- As the contexts is updated, the WUI automatically refreshes with the new data.
Benefits of the Event-Driven Approach
Separates event generation from consumption, making the system more scalable and easier to maintain.
Immediate propagation of data changes to the WUI thanks to Lit contexts.
Adding new event types or contexts is simple, as each component subscribes only to events it cares about.
Combines periodic updates with specific event-triggered refreshes, reducing unnecessary backend traffic.
Proposed Data Models
export class User {
id: string;
name: string;
surname: string;
email: string;
password: string;
notificationsEnabled: string;
organizations: Organization[];
tokens: Token[];
tenants: Tenant[];
axebowPlan: "freemium" | "premium";
companyName: string;
rol: string;
}
interface Organization {
id: string,
name: string,
usersIds: string[],
tenantsIds: string[],
billingInformation: {
legalName: string,
CIFNIF: string,
email: string,
language: string,
country: string,
region: string,
city: string,
address: string,
zipcode: string,
}
invoices: {
id: string,
name: string,
customer: string,
customerCIF: string,
cost: number,
date: string,
invoiceFile: string,
}[],
status?: string,
}
interface Token {
name: string;
tenant: string;
desciprion: string;
lastUsed: string;
expiration: string;
token: string;
}
interface Tenant {
id: string,
name: string,
organizationsIds: string[],
services: Service[],
accounts: Account[],
environments: Environment[],
marketplaceItems: MarketplaceItem[],
resources: Resource[],
role: string,
status: string,
users: number;
}
interface Service {
id: string;
tenant: string;
account: string;
environment: string;
name: string;
logo: string;
description: string;
revisions: string[];
status: string;
role: { name: string; instances: Instance[]; logo?: string, category?: string, version?: string, description?: string, resource?: Resource[] }[];
links: Link[];
resources: Resource[];
usage: Usage;
minReplicas?: number;
maxReplicas?: number;
lastDeployed?: string;
project: string;
registry: string;
imageName: string;
entrypoint: string;
cmd: string;
serverChannels: Channel[];
clientChannels: Channel[];
duplexChannels: Channel[];
cloudProvider: string;
currentRevision?: string;
startedAt?: string;
}
interface Instance {
id: string;
name: string;
status: string;
usage: Usage;
logs: string[];
conatiners: Container[];
}
interface Container {
name: string;
ready: boolean;
reestartCount: number;
metrics: {
cpu: number;
memory: number;
}
states: any;
}
interface Channel {
name: string;
from: string;
to: string;
protocol?: "http" | "tcp" | "https";
port?: number;
portNum?: number;
}
interface Account {
id: string;
name: string;
tenant: string;
cloudProvider: {
name: string;
region?: string;
interface?: string;
apiVersion?: string;
authType?: string;
authUrl?: string;
credentialId?: string;
credentialSecret?: string;
};
logo: string;
environments: string[];
services: string[];
domains: string[];
status: string;
usage: Usage;
flavors?: {
small: string;
medium: string;
large: string;
volatile: string;
nonReplicated: string;
persistent: string;
};
organization?: string;
}
interface Usage {
current: {
cpu: number;
memory: number;
storage: number;
volatileStorage: number;
nonReplicatedStorage: number;
persistentStorage: number;
};
limit: {
cpu: {
max: number;
min: number;
}
memory: {
max: number;
min: number;
}
storage: {
max: number;
min: number;
}
volatileStorage: {
max: number;
min: number;
}
nonReplicatedStorage: {
max: number;
min: number;
}
persistentStorage:{
max: number;
min: number;
}
};
cost: number;
}
interface Environment {
id: string;
name: string;
account: string;
tenant: string;
logo: string;
services: string[];
domains: string[];
status: string;
usage: Usage;
organization?: string;
cloudProvider?: string;
labels?: string[];
}
interface MarketplaceItem {
tenant: string,
name: string,
logo: string,
description: string,
version: string,
requirements: {
cpu: number,
memory: number,
}
status: string,
instances: Instance[],
links: Link[],
resources: Resource[],
domain?: string,
type?: string,
}
interface Resource {
type: 'clientChannel' | 'secret' | 'volume' | 'file' | 'string' | 'number' | 'boolean',
name: string,
value: string,
kind?: 'volatile' | 'nonReplicated' | 'persistent',
maxItems?: number,
}
interface Link {
name: string,
origin: string,
target: string,
}
Keep in mind that this data structure represents what I have considered relevant information for the WUI from the dessigns of the dessign team. I know that the backend will provide more information but the idea is to transform this data on the backend handler so only relevant information reaches the WUI.
Benefits of the Overall Proposal
Centralized data management and scheduled synchronization reduce redundant network calls, lower latency, and improve overall performance.
Lit’s reactive contexts ensure that the WUI adapts instantly to data changes.
Real-time notifications and event-driven updates create a dynamic and engaging user environment.
Repository Tree
.
├── README.md
├── event-handler-singleton.ts
├── event-handler.ts
├── event-handler.test.ts
├── event-helper.ts
├── event-names.ts
├── jest.config.ts
├── package.lock.json
├── package.json
├── tsconfig.json
├── img
│ ├── diagram.png
│ ├── use-case-logs.png
│ ├── use-case-new-deployment.png
│ ├── use-case-deployment-ok.png
│ ├── use-case-deployment-error.png
│ └── user-case-update-data.png
│
├── interfaces
│ ├── account-interface.ts
│ ├── channel-interface.ts
│ ├── container-interface.ts
│ ├── environment-interface.ts
│ ├── instance-interface.ts
│ ├── link-interface.ts
│ ├── marketplaceItem-interface.ts
│ ├── organization-interface.ts
│ ├── resource-interface.ts
│ ├── service-interface.ts
│ ├── tenant-interface.ts
│ ├── token-interface.ts
│ ├── usage-interface.ts
│ └── user-interface.ts
│
├── coverage
│ └── coverage data...
│
└── LICENSE
