npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kumori/aurora-wui-bridge

v1.0.0

Published

connection between the backend and the frontend

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@latest

This library grants a 'globalEventHandler' which the backendHandler and the userContext will need to communicate via events.

Test

Installation

  1. Install dependencies:
npm install

Running Test

The project uses Jest as the testing framework with TypeScript support via ts-jest. To execute the tests, simply run:

npm run test

Coverage

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.

Archicture of the library

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.

Archicture for a logs request

Flow:

  1. The user makes a log request.
  2. The UI publishes an event. [RequestLogs(Service)]
  3. The backend subscriber gets the event and fetches the data. [RequestLogs(Service)]
  4. The backend publishes a new event with the log data. [updateServiceData(data)]
  5. The context subscriber gets the event and refreshes the WUI with the data. [updateServiceData(data)]

The user deploys a new service

Archicture for a service deployment

Flow:

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

Archicture for a correct service deployment

Flow:

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

Archicture for an error on a service deployment

Flow:

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

Scheduled data update

Archictecture for a data update

Flow:

  1. Every minute the user information is updated by the backend handler. [updateUserInfo()]
  2. The backend hablder publishes an event with the updated data. [updateUserData(data)]
  3. The context subscriber gets the event and updated the context. [updateUserData(data)]
  4. 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

License