StringTune/Docs

Custom Modules

Events

Safe event bus patterns for subscribing, emitting, and naming custom-module channels.

Events

this.events is the shared event bus available to custom modules. Use it to subscribe to runtime signals and to publish your own channels without tightly coupling modules together.

Typical Uses

  • subscribe to global lifecycle events in onSubscribe(...)
  • emit object-scoped output channels
  • bridge one runtime signal into a more useful custom-module event

Subscribe Safely

The usual pattern is:

TypeScript
override onSubscribe(): void {
  this.events.on('scroll:start', this.onScrollStartEvent);
}

override onUnsubscribe(): void {
  this.events.off('scroll:start', this.onScrollStartEvent);
}

Keep subscription and unsubscription symmetrical.

Emit Object-Scoped Events

When publishing per-object channels, prefer getObjectEventName(...) over manual string building.

TypeScript
this.events.emit(this.getObjectEventName(object, 'object:rotate-progress'), { progress, rotation });

That keeps naming consistent and avoids repeated string work in hot paths.

What To Emit

Good custom-module events usually represent one of these:

  • computed output state
  • phase change
  • object-scoped interaction data

Examples:

  • object:rotate-progress:<id>
  • object:mask-shift:<id>
  • module:ready

What Not To Do

  • do not emit noisy per-frame payloads unless consumers really need them
  • do not invent unclear names that overlap with existing built-in channels
  • do not rely on undocumented internal channels unless you explicitly control both sides

Naming Guidance

Prefer names that make scope obvious:

  • global channel: feature:ready
  • object-scoped channel: object:feature:<id>

If your custom module mirrors built-in module style, consumers will understand it faster.

Cross-Module Communication

The event bus is useful when:

  • direct imports would create tighter coupling
  • one module should react to another module's output
  • DOM wiring would be noisier than one scoped event

But if two modules are effectively one feature, keep the design honest. Sometimes one module is cleaner than an event-driven split.