Nexus Architecture

Complete Overview of @hyperfrontend/nexus


Overview

@hyperfrontend/nexus is a cross-window communication library designed for micro-frontend architectures. It implements a TCP-like connection protocol over the browser's postMessage API, providing secure, contract-validated messaging between browser contexts (iframes, windows, and web workers).

Target Use Cases

  1. Micro-frontend communication — Shell applications coordinating multiple micro-apps
  2. Iframe integration — Secure bidirectional messaging with embedded content
  3. Multi-window applications — Communication between browser windows/tabs
  4. Plugin architectures — Host-to-plugin communication with contract enforcement

Table of Contents

  1. Architecture Overview
  2. Design Philosophy
  3. Module Structure
  4. Core Concepts
  5. Protocol Design
  6. Handler Reference
  7. Event System
  8. Logging System
  9. Security Model
  10. Internal Dependencies
  11. Integration Points
  12. Public API Surface

Architecture Overview


Design Philosophy

The library follows functional programming principles with factory-based architecture.

Key Design Decisions

AspectImplementationRationale
State ManagementClosure-based encapsulationTrue information hiding, prevents external mutation
Factory PatterncreateBroker(), createChannel()Testable, composable, no class inheritance complexity
RegistryInstance-based with WeakMap/MapO(1) lookups, memory-efficient, multiple brokers supported
Process TrackingUUID-based ProcessManagerClean lifecycle management for in-flight connections
Router PatternHandler registry keyed by action typeSingle responsibility, extensible protocol
ImmutabilityObject.freeze(), spread patternsPredictable state transitions

Notable Patterns

  • Functional Core, Imperative Shell — Pure logic in core, side effects at boundaries
  • Handler Registry — Extensible protocol handling
  • WeakMap for Window References — Prevents memory leaks
  • Immutable State Updates — Predictable state transitions

Module Organization

The library is organized into logical modules by responsibility:

ModuleResponsibility
BrokerCentral message coordinator, channel management
ChannelBidirectional communication endpoints, lifecycle
SecurityOrigin filtering, protocol negotiation, encryption
FiltersEvent and message filtering utilities
SchemaJSON Schema validation for contracts

Core Concepts

1. Broker (BrokerHandle)

The broker is the central coordinator that:

  • Manages multiple channels
  • Listens for incoming postMessage events
  • Routes messages to appropriate handlers
  • Enforces security policies
interface BrokerHandle {
  readonly id: string
  readonly name: string
  readonly contract: IChannelContract
  readonly channels: ReadonlyArray<ChannelJSON>

  addChannel(name: string, target: Window, settings?: IChannelSettings): ChannelHandle
  getChannel(reference: string | Window): ChannelHandle | null
  removeChannel(reference: string | Window): void
  setSecurityPolicy(policy: SecurityPolicy): BrokerHandle
  extendContract(contract: IChannelContract): BrokerHandle

  // Security protocol management
  registerProtocol(version: 'v1' | 'v2', provider: unknown): BrokerHandle
  unregisterProtocol(version: 'v1' | 'v2'): BrokerHandle
  hasProtocol(version: SecurityProtocolVersion): boolean
  getSupportedProtocols(): SecurityProtocolVersion[]
}

2. Channel (ChannelHandle)

A channel represents a communication endpoint to another window:

interface ChannelHandle {
  readonly id: string
  readonly name: string
  readonly target: Window

  // State queries
  isActive(): boolean
  toJSON(): ChannelJSON

  // Lifecycle
  connect(): void
  disconnect(notify?: boolean): void
  cancel(notify?: boolean): void
  destroy(notify?: boolean): void

  // Communication
  send(type: string, data?: unknown): void

  // Subscriptions
  on(handler: EventHandler): () => void
  on<E extends ChannelEvent>(event: E, handler: EventCallbackMap[E]): () => void
  onMessage(handler: MessageHandler): () => void
}

3. Contract (IChannelContract)

Contracts define the messaging agreement between parties:

interface IChannelContract {
  emitted: IActionDescription[] // Message types this party sends
  accepted: IActionDescription[] // Message types this party receives
}

interface IActionDescription {
  type: string // Message type identifier
  description?: string // Human-readable description
  schema?: object // Optional JSON Schema for validation
}

4. Actions (Protocol Messages)

The protocol defines 11 action types for connection lifecycle:

Action TypePurpose
REQUEST_CONNECTIONInitiate connection (SYN)
ACCEPT_CONNECTIONAccept connection (SYN-ACK)
OPEN_CONNECTIONConfirm connection (ACK)
DENY_CONNECTIONReject connection (RST)
CANCEL_CONNECTIONCancel pending connection
CANCEL_CONNECTION_ACKNOWLEDGEDAcknowledge cancellation
CLOSE_CONNECTIONGraceful disconnect
CLOSE_CONNECTION_ACKNOWLEDGEDAcknowledge disconnect
DESTROY_CONNECTIONForce disconnect
NEW_MESSAGEUser data transmission
INVALID_REQUESTProtocol violation

Protocol Design

Three-Way Handshake

Nexus implements a TCP-like handshake for reliable connection establishment:

Internal Sequence:

Denial Flow

When a connection is rejected (invalid contract or security policy failure):

Graceful Disconnection

State Transitions


Handler Reference

Each protocol action is processed by a dedicated handler. All handlers receive the broker state, channel registry, process manager, and incoming message.

HandlerResponsibilities
handleRequestValidate contract, apply policy, activate channel, send ACCEPT
handleAcceptValidate contract, apply policy, activate, send OPEN, notify 'open'
handleOpenTerminate process, notify 'open' (responder side)
handleDenyTerminate process, notify 'deny' with error context
handleCancelCancel channel, send CANCEL_ACK, notify 'cancel'
handleCancelAcknowledgedTerminate process, notify 'cancel' (initiator side)
handleCloseDisconnect channel, send CLOSE_ACK, notify 'close'
handleCloseAcknowledgedTerminate process, notify 'close' (initiator side)
handleMessageValidate payload, forward to subscribers via notifyMessage()
handleDestroyForce-destroy connection, clean up resources
handleInvalidLog invalid requests, optionally notify sender — see handle-invalid.ts

Event System

Channels emit lifecycle events to subscribers. Each event has a specific trigger and payload structure.

Lifecycle Events

EventTriggerPayload
'open'Connection successfully established{ origin, contract }
'close'Connection gracefully closed{ notify: boolean }
'cancel'Pending connection cancelled{ notify: boolean }
'deny'Connection request rejected{ error, origin }
'destroy'Connection force-destroyed{}

Security Events

EventPayloadDescription
security-negotiated{ protocol, isPreferred }Protocol negotiation completed
security-ready{ protocol }Security transport is active
security-error{ message, code, cause? }Security operation failed

Event Subscription

// Subscribe to a specific event (recommended)
channel.on('open', (data) => console.log('Opened:', data.origin))
channel.on('close', (data) => console.log('Closed'))
channel.on('security-ready', (data) => console.log(`Secure channel using ${data.protocol}`))

// Subscribe to all events (for generic handling)
channel.on((event, data) => {
  switch (event) {
    case 'open':
      console.log(`Connected to ${data.origin}`)
      break
    case 'close':
      console.log('Connection closed')
      break
  }
})

// Use filter utilities for advanced composition
import { openFilter, closeFilter } from '@hyperfrontend/nexus/filters'

channel.on(openFilter((data) => console.log('Opened:', data.origin)))
channel.on(closeFilter((data) => console.log('Closed')))

Logging System

Nexus provides a configurable logging system that routes all internal output through a Logger interface from @hyperfrontend/logging.

Logger Interface

interface Logger {
  error(...args: unknown[]): void
  warn(...args: unknown[]): void
  log(...args: unknown[]): void
  info(...args: unknown[]): void
  debug(...args: unknown[]): void
  setLogLevel(level: LogLevel): void
  getLogLevel(): LogLevel
}

type LogLevel = 'error' | 'warn' | 'log' | 'info' | 'debug' | 'none'

Logger Flow

  1. Broker initializationcreateBroker() creates or adopts a logger based on settings.logLevel and settings.logger
  2. Channel inheritance — Channels created via broker.addChannel() inherit the broker's logger
  3. RoutingContext — All routing handlers receive the logger via RoutingContext

RoutingContext

All routing handlers receive a RoutingContext object containing shared dependencies:

interface RoutingContext {
  readonly state: BrokerState // Immutable broker state snapshot
  readonly registry: Registry // Channel registry for lookups
  readonly processManager: ProcessManager // Tracks handshake processes
  readonly actions: ActionCreators // Factory functions for protocol actions
  readonly logger: Logger // Logger instance for this broker
}

This pattern:

  • Eliminates parameter proliferation across handlers
  • Makes testing straightforward (mock the context)
  • Provides clean access to logger without prop drilling

Structured Logging Utilities

UtilityPurposeOutput Format
logActionProtocol action tracing[nexus] Action <direction>: <type> <action>
logEventChannel lifecycle event logging[nexus] Channel event: <event> <data>

createLogger Factory

import { createLogger, type NexusLoggerOptions } from '@hyperfrontend/nexus'

interface NexusLoggerOptions {
  level?: LogLevel // Default: 'error'
  prefix?: string // Default: '[nexus]'
  customLogger?: Logger // Use this logger directly if provided
}

const logger = createLogger({ level: 'debug', prefix: '[app]' })

Security Model

Nexus provides a multi-layered security approach:

Layer 1: Origin Filtering

Basic origin-based access control:

const broker = createBroker({
  settings: {
    whitelist: ['https://trusted.com'],
    blacklist: ['https://malicious.com'],
  },
})

Layer 2: Security Policy

Custom programmatic validation:

broker.setSecurityPolicy((event: MessageEvent) => {
  return event.origin.endsWith('.mycompany.com')
})

Layer 3: Contract Validation

Schema-based message validation:

const contract: IChannelContract = {
  emitted: [
    {
      type: 'USER_DATA',
      schema: {
        type: 'object',
        properties: {
          userId: { type: 'string' },
          email: { type: 'string', format: 'email' },
        },
        required: ['userId'],
      },
    },
  ],
  accepted: [{ type: 'ACK' }],
}

Layer 4: Transport Security (Optional)

End-to-end encryption via @hyperfrontend/network-protocol:

ProtocolDescriptionUse Case
nonePassthrough, no encryptionTrusted environments
v1Obfuscation-first with dynamic key exchangeBasic protection
v2Pre-shared key with dynamic key rotationHigh security

Security Negotiation Flow

During connection handshake, parties negotiate the security protocol:

Security Transport Architecture

Configuration Examples

// Register protocol at broker level
broker.registerProtocol('v2', createProtocol(logger, 'shared-key', 60))

// Override per-channel
const channel = broker.addChannel('secure', targetWindow, {
  security: {
    protocol: 'v2',
    sharedKey: 'channel-specific-key',
    refreshRate: 30,
  },
})

// Protocol registry API
broker.hasProtocol('v2') // true
broker.getSupportedProtocols() // ['v2', 'none']
broker.unregisterProtocol('v2') // Remove provider

Internal Dependencies

Hyperfrontend Libraries

{
  "@hyperfrontend/function-utils": "0.0.0",
  "@hyperfrontend/logging": "0.0.0",
  "@hyperfrontend/random-generator-utils": "0.0.0"
}

External Dependencies

{
  "jsonschema": "1.5.0"
}

Optional Integration

  • @hyperfrontend/network-protocol — For transport-level security (v1/v2 protocols)

Integration Points

With Other Hyperfrontend Libraries

LibraryIntegration
@hyperfrontend/network-protocolOptional transport security
@hyperfrontend/loggingLogging infrastructure
@hyperfrontend/random-generator-utilsUUID generation
@hyperfrontend/function-utilsUtility functions
@hyperfrontend/state-machinePotential state management enhancement

With External Systems

  • Micro-frontend frameworks — Module federation, single-spa
  • Web workers — Worker-to-main thread communication
  • Service workers — Offline-capable messaging
  • Electron — Main-renderer process communication

Public API Surface

Exports from @hyperfrontend/nexus

// Core factories
export { createBroker } from './broker'
export { createChannel } from './channel'
export { mergeContracts } from './setup'
export { broker as defaultBroker, DEFAULT_CONTRACT } from './singleton'

// Broker types
export type { BrokerHandle, BrokerConfig, BrokerSettings, BrokerState, SecurityPolicy }

// Channel types
export type { ChannelHandle, ChannelJSON, IChannelSettings, IChannelConfig }

// Contract types
export type { IChannelContract, IActionDescription }

// Message types
export type { IMessage, MessageEnvelope }

// Event types
export type { ChannelEvent, EventData, OpenEventData, CloseEventData, ... }

// Action types
export type { IAction, ActionType }

// Filter utilities
export { openFilter, closeFilter, cancelFilter, denyFilter, invalidFilter, createEventFilter }
export { byType, compose, createMessageFilter }
export type { MessageFilter, MessagePredicate, MessageHandler, EventHandler }

// Logging
export { createLogger, logAction, logEvent } from './utils/logging'
export type { Logger, LogLevel, NexusLoggerOptions }