Throttling
When you pass the throttle option (in milliseconds) when constructing a Tabus, emit() limits how often messages are actually sent through the transport.
interface TabusOptions { throttle?: number; // minimum ms between emitted messages (default: 0, no throttle) trailing?: boolean; // emit the last pending message when the window expires (default: true)}Leading + trailing edge
Section titled “Leading + trailing edge”- Leading edge: the first call within a “window” is emitted immediately.
- Subsequent calls within the window: aren’t emitted instantly; instead they replace a pending message (only the last one is kept).
- Trailing edge (if
trailing !== false): when the window expires, the saved pending message is emitted automatically. - If
trailing: false, intermediate messages are silently dropped and only the leading edge is honored. destroy()cancels any pending trailing timer and discards the pending message — nothing is emitted after the instance is destroyed.
Example: cursor at ~60fps
Section titled “Example: cursor at ~60fps”const bus = new Tabus("canvas", { throttle: 16 }); // ~60fps
// If called many times in a row (e.g. on mousemove):bus.emit("cursor", { x: 10, y: 20 }); // emitted RIGHT NOW (leading edge)bus.emit("cursor", { x: 11, y: 21 }); // saved as pendingbus.emit("cursor", { x: 12, y: 22 }); // replaces the previous pending one// ...once 16ms have passed since the last leading emit,// the LAST pending payload is emitted automatically: { x: 12, y: 22 }With trailing: false, only { x: 10, y: 20 } would be emitted and the rest would be lost.
When to use trailing: false
Section titled “When to use trailing: false”Use it when the intermediate value doesn’t matter and the only thing that’s relevant is reacting quickly to the first event of a burst — for example, a “something changed” notice where you don’t care about the last state, only that it happened.
Next step
Section titled “Next step”Check out the full real-time cursor example, which uses this same throttle pattern on a mousemove.
