---
title: "TeqFW: Event Basics"
description: "How TeqFW models local and cross-boundary events between browser and Node.js, with explicit message contracts and resilient delivery."
date: 2022-01-05
---

JavaScript is well suited to asynchronous programming, where events are
central. This article introduces how Tequila Framework uses events to
coordinate work within the browser or server and across the boundary
between them.

## What is an event?

An event is a meaningful state change, such as “the user has
authenticated”. It carries data — for example, a user identifier —
arises from an action, and can cause further actions such as loading the
user profile.

<zoom-img src="/medium/img/541b01dfbe6b/image-01.png" alt="Event producer, message, and handlers" width="100%"></zoom-img>

In the simplest form there are two functional objects and one data
object: an *Event Producer* changes state and emits an *Event Message*;
one or more *Event Handlers* react. An event has a type, such as
`onClick`, and a message with related data, such as a `MouseEvent`.

Handlers react asynchronously, can change application state, and can
emit further events. This makes an application more flexible than a
chain of synchronous calls, but it also requires discipline and
observability.

## Local and cross-boundary events

A Teq application usually has a frontend in a browser and a Node.js
backend. If producer and handler run in the same process, the event is
local. If they are on opposite sides, it is cross-boundary.

Cross-boundary messages travel over the Internet as JSON. Their data
must therefore be serializable and deserializable without loss. A local
message stays within one process and is not subject to that transport
constraint.

## Event names

Each event type should be unique across the application. Teq namespaces
make an event’s ES module name a natural identifier:

- `Vnd_Plug_Front_Event_Net_Status_Changed`: a local frontend event;
- `Vnd_Plug_Back_Event_Sale_Order_Registered`: a local backend event;
- `Vnd_Plug_Shared_Event_Front_Sale_Order_Confirmed`: a
  browser-originated cross-boundary event;
- `Vnd_Plug_Shared_Event_Back_Sale_Order_Registered`: a
  backend-originated cross-boundary event.

The ES module encapsulates not only the event name but also the DTO
shape of its message. That makes the contract explicit and reusable on
both sides.

## Handling local events

A local producer supports publishing and subscription:

``` js
class EventProducer {
  emit(eventName, message) {}
  subscribe(eventName, handler) {}
  unsubscribe(subscription) {}
}
```

A subscriber tells the producer which event it needs and supplies a
handler. When the state changes, the producer sends the message to that
handler.

<zoom-img src="/medium/img/541b01dfbe6b/image-02.png" alt="Local event subscription and delivery" width="100%"></zoom-img>

Because both parties are on the frontend or both on the backend, this is
comparatively simple.

## Handling cross-boundary events

With a browser producer and server handler — or the reverse — a mobile
application has an unreliable communication channel in between.

<zoom-img src="/medium/img/541b01dfbe6b/image-03.png" alt="Cross-boundary event transfer between frontend and backend" width="100%"></zoom-img>

The producer sends messages to a queue that watches the channel and
delivers when possible. On the other side, a representative or “embassy”
lets local handlers subscribe to events from the remote side. Once it
receives a network message, it routes it to the matching handler. The
same principle works in both directions.

A production design must also define message identity, ordering, retry
and deduplication semantics; a queue alone does not make delivery
exactly-once.

## Summary

Event-driven architecture matches JavaScript’s asynchronous nature and
works well in environments that change unpredictably. Its cost is less
linear control flow. Event-driven applications therefore need purposeful
logging and tracing on both client and server so people can understand
what happened and recover from failures.
