@hyperfrontend/network-protocol/topic

Topic

Purpose

The Topic module provides a store for named topics used in message routing. A topic is a name paired with a generated identifier; channels subscribe to topics and receive the messages routed to them.


Key Interfaces

Topic

interface Topic {
  readonly name: string // Human-readable topic name
  readonly id: string // Unique identifier (UUID v4, generated by the store)
}

TopicStore

interface TopicStore {
  readonly create: (...name: string[]) => void // Creates topics by name with generated ids
  readonly add: (...topic: Topic[]) => void // Adds existing topic objects
  readonly existsByName: (name: string) => boolean
  readonly existsById: (id: string) => boolean
  readonly getByName: (name: string) => Topic | null
  readonly getById: (id: string) => Topic | null
  readonly list: readonly Topic[]
  readonly removeByName: (...name: string[]) => void
  readonly removeById: (...id: string[]) => void
  readonly clear: () => void
}

Factory Functions

createTopicStore

Location: @hyperfrontend/network-protocol/topic

function createTopicStore(): TopicStore

Usage Examples

Basic Topic Management

import { createTopicStore } from '@hyperfrontend/network-protocol/topic'

const topicStore = createTopicStore()

topicStore.create('user-events', 'system-events', 'notifications')

const userEvents = topicStore.getByName('user-events')
// => { name: 'user-events', id: '<generated uuid>' }

topicStore.existsByName('user-events') // true
topicStore.list.length // 3

Adding Existing Topics

topicStore.add({ name: 'chat.messages', id: chatTopicId })
topicStore.getById(chatTopicId)

The id is not validated by add, but every routed-packet creator requires a UUID v4 topic id (see routing/), so use one.

Topic Removal

topicStore.removeByName('user-events', 'system-events')
topicStore.removeById(chatTopicId)
topicStore.clear()
topicStore.list.length // 0

Error Handling

topicStore.create('user-events') // twice
// Error: "Cannot create a topic with name 'user-events' as a topic with that name already exists"

topicStore.create('')
// Error: "Invalid topic name ''"

topicStore.add({ name: 'user-events', id })
// Error: "Cannot add a topic with name 'user-events' as it already exists"

topicStore.removeByName('missing')
// Error: "No topic found with name 'missing' to remove"

topicStore.removeById('missing')
// Error: "No topic found with id 'missing' to remove"

Topic Naming Conventions

PatternExampleUse Case
entity-actionuser-createdEntity lifecycle events
domain-eventspayment-eventsDomain-specific events
system-categorysystem-metricsSystem-level notifications
'feature.sub''chat.messages'Hierarchical namespacing

Integration with Routing

import { createTopicStore } from '@hyperfrontend/network-protocol/topic'
import { createChannelStore } from '@hyperfrontend/network-protocol/browser/channel'

const topicStore = createTopicStore()
const channelStore = createChannelStore()

topicStore.create('user-events', 'system-events')

const first = channelStore.create('client-1', {
  send,
  receive,
  protocolProvider,
  session: firstSession,
})

const router: Router = (channels, topics) => {
  const subscriptions = new WeakMap<Channel, Topic[]>()
  const userEvents = topics.find((t) => t.name === 'user-events')
  subscriptions.set(first, userEvents ? [userEvents] : [])
  return { isDynamic: false, subscriptions }
}

const routingOptions = router(
  channelStore.list.map((entry) => entry.channel),
  topicStore.list
)

Validation Helpers

validations/ holds isValidName (a non-empty string), isValidTopicId (a 36-character UUID v4 string), and isValidTopic (both). isValidTopicId is what the routing creators use to check a topic id.


Relationship to Other Modules


See Also

Related Modules

ModuleRelationship
routing/Uses topics for message distribution

API Reference§

ƒ Functions

§function

createTopicStore(): TopicStore

Creates a store for managing topic registrations and lookups. Provides methods to create, retrieve, and list topics by name or ID.
Returns
TopicStore
A TopicStore with methods for managing topics
Example

Creating and using a topic store

const store = createTopicStore()
store.create('notifications')
const topic = store.getByName('notifications')
// => { name: 'notifications', id: '550e8400-...' }

◈ Interfaces

§interface

Topic

Represents a named topic with a unique identifier
Properties
§readonly id:stringUnique identifier for this topic
§readonly name:stringHuman-readable topic name
§interface

TopicStore

Store for managing topics with lookup by name or ID
Properties
§readonly add:(topic: Topic[]) => voidAdds existing topic objects
§readonly clear:() => voidRemoves all topics
§readonly create:(name: string[]) => voidCreates new topics by name
§readonly existsById:(id: string) => booleanChecks if a topic exists by ID
§readonly existsByName:(name: string) => booleanChecks if a topic exists by name
§readonly getById:(id: string) => TopicRetrieves a topic by ID
§readonly getByName:(name: string) => TopicRetrieves a topic by name
§readonly list:unknownList of all registered topics
§readonly removeById:(id: string[]) => voidRemoves topics by ID
§readonly removeByName:(name: string[]) => voidRemoves topics by name