@wolfstar/plugin-broker publishes and consumes messages over Redis Streams
with consumer-group semantics. One gateway process, or several sharded ones with
@wolfstar/plugin-sharder, publishes dispatches. Any number of worker
processes consume them and share the load, so a worker can restart, crash, or deploy without dropping the gateway
connection.Unlike Redis Pub/Sub, entries survive a worker being down (XADD and XREADGROUP instead of PUBLISH). Unlike a
plain XREAD, workers share the load through a consumer group instead of each receiving every message.
Import the register entry point before you create your Client, then configure broker on it. The consumer starts
automatically once the client starts listening:
On framework 6.1 and later, list the ./module entry in modules in stars.config instead of importing register.
It needs the optional @wolfstar/kit peer dependency, at ^0.2.0 || ^0.3.0.
The module reads its options from the broker key of stars.config. The [specifier, options] tuple of modules
still works. Its options are merged over the broker key, so they win.The optional @wolfstar/schema peer dependency types the broker key in defineConfig.
TypeScript only loads that type once the module is imported, so import @wolfstar/plugin-broker/module in stars.config.ts.Module options must be JSON-serialisable. redis is a client instance and consumer is per process, so neither goes under the broker key of stars.config. Set both through ClientOptions.broker, which is shallowly merged over the module options. ClientOptions.broker is currently typed as the full BrokerConsumerOptions, so it must still include stream and group.Without the stars CLI, pass the ./plugindefinePlugin factory to the
plugins client option:
import brokerPlugin from '@wolfstar/plugin-broker/plugin';const client = new Client({ plugins: [brokerPlugin({ redis, stream: 'wolfstar:events', group: 'workers', consumer: 'w1' })]});
Use only one of the module, the ./plugin factory, and register. Combining them installs the plugin’s hooks twice.
An entry is acknowledged once every listener for its event has resolved. A listener that throws leaves the entry
pending. A restarted consumer of the same name receives it again. With claimIdle set, whichever consumer claims the
entry after it has been idle that long receives it instead.
Idle time counts from an entry’s last delivery. Set claimIdle well above your slowest listener’s run time, or another consumer can claim and
handle an entry that is still running.
With maxDeliveries set, an entry delivered more than that many times moves to the dead-letter stream. The dead-letter
entry keeps its event and payload fields plus the original id, stream, group, consumer, and deliveries. Without it, a
failing entry is retried forever.
container.broker.stop() stops reading and waits for the in-flight entry. Anything left unacknowledged stays pending
for the next consumer. With shutdownSignals, the consumer does this on its own when the process receives one of
those signals.
forwardGatewayDispatches publishes every dispatch a @wolfstar/plugin-gatewayGatewayClient receives, once it is written to the client’s cache. Workers that share a
@wolfstar/plugin-cache Redis cache see the state each dispatch left.
import { createBroker, forwardGatewayDispatches } from '@wolfstar/plugin-broker';import { GatewayDispatchEvents } from 'discord-api-types/v10';const broker = createBroker({ redis, stream: 'wolfstar:events', maxLength: 100_000 });const stopForwarding = forwardGatewayDispatches(gatewayClient, broker, { events: [GatewayDispatchEvents.MessageCreate], // omit to forward every dispatch onError: (error, payload) => console.error(`Failed to forward ${payload.t}`, error)});
For a GatewayClient, each entry also carries the previous state of the dispatch’s entity (for example, the cached
message a MESSAGE_UPDATE replaces), the shard that received the dispatch, and its gateway sequence number.Forwarding includes the GUILD_DELETE the client emits on dispatch for a cached guild that a READY no longer lists,
such as one the bot left while offline. Workers clean up those guilds too.
A bot that loads the same pieces on the gateway process and on the workers would handle each dispatch twice.
forwardGatewayDispatches marks a GatewayClient as forwarding (client.forwardsDispatches returns true) until you
call its stop function. RegisterAsDispatchListener from @wolfstar/plugin-gateway
reads that flag on every emit. It runs the listener on the workers while the gateway forwards, and on the gateway client
when nothing is forwarded, with no environment variable to read:
import { EventGatewayListener, RegisterAsDispatchListener, type Message } from '@wolfstar/plugin-gateway';@RegisterAsDispatchListener('messageCreate')export class ModerationListener extends EventGatewayListener<'messageCreate'> { public override run(message: Message) { // Runs once per dispatch, on whichever process handles it }}
The decorator throws for the events a worker never receives, such as clientReady and shardReady. With events set,
a listener of an event built from a dispatch that is not forwarded runs nowhere. Delivery is at-least-once, so keep these
listeners idempotent.
replayGatewayDispatches(consumer, client) replays the dispatches forwardGatewayDispatches publishes on a worker’s own
GatewayClient, which never connects to Discord. The worker’s EventGatewayListener pieces receive the same events,
with the same structures and old arguments, as if the dispatch happened in-process. Use it when you want to run
gateway listeners on workers instead of on the process connected to Discord.Both clients must use the same @wolfstar/plugin-cache Redis cache.
import { BrokerConsumer, createBroker, forwardGatewayDispatches, replayGatewayDispatches } from '@wolfstar/plugin-broker';import { GatewayClient } from '@wolfstar/plugin-gateway';import { GatewayDispatchEvents } from 'discord-api-types/v10';// Gateway processconst gatewayClient = new GatewayClient({ ...options, cache: redisCache });const broker = createBroker({ redis, stream: 'wolfstar:events' });forwardGatewayDispatches(gatewayClient, broker);await gatewayClient.start();// Worker: same cache, never connectedconst worker = new GatewayClient({ ...options, cache: redisCache });const consumer = new BrokerConsumer({ redis, stream: 'wolfstar:events', group: 'workers', consumer: 'worker-1'});const stopReplaying = replayGatewayDispatches(consumer, worker, { events: [GatewayDispatchEvents.MessageUpdate] // omit to replay every type the client handles});await consumer.start();
A worker’s messageUpdate listener receives the message as it was before the edit. The gateway process ships that
previous state with the dispatch as raw API data, and the worker rebuilds it. Relations of the previous state (author,
guild, and so on) resolve from the cache when the worker handles the entry, so they can be newer than the dispatch.
raw listeners receive the same payload (op, s, t, d) on both sides.replayGatewayDispatches does not replay READY, INTERACTION_CREATE, or shard lifecycle events (shardReady,
shardClose, and so on). A worker’s client.user stays null.
An entry is acknowledged once its listeners have resolved, async ones included. A worker listener that throws or
rejects leaves the entry pending for redelivery.A failure applies to the whole entry, not to a single listener. When one of several listeners of an event throws, the
redelivery runs the listeners that already succeeded again. A connected GatewayClient would not do this.
Keep worker listeners idempotent, and enqueue slow work instead of awaiting it. A consumer handles one entry at a time, and another worker can
claim an entry pending for longer than claimIdle while it still runs.
Ordering holds per consumer, not across the consumer group. Workers in one group take different entries and run them
concurrently, so two events of the same guild can replay out of order across workers. The cached relations a listener
resolves can also differ from the gateway process’s. The previous state shipped with each entry is a snapshot, so old
stays correct.
Stream entries can carry optional state, shard, and sequence fields next to event and payload. Pass them to
broker.publish as a third options argument. state is encoded with the configured codec, like the payload.
Listeners read them from BrokerMessage.state, BrokerMessage.shard, and BrokerMessage.sequence. Entries without
these fields, and consumers that ignore them, work as before.
A BrokerListener piece, typed by event name, is loaded from the listeners directory. Augment BrokerEvents in your
application to type the events you publish and consume:
import { BrokerListener, RegisterAsBrokerListener, type BrokerMessage } from '@wolfstar/plugin-broker';declare module '@wolfstar/plugin-broker' { interface BrokerEvents { messageCreate: { content: string }; }}@RegisterAsBrokerListener('messageCreate')export class LogMessagesListener extends BrokerListener<'messageCreate'> { public override run(payload: { content: string }, message: BrokerMessage) { console.log(`[${message.id}] ${payload.content}`); }}
Payloads use a CacheCodec from @wolfstar/plugin-cache: jsonCodec() by default, or msgpackCodec() from
@wolfstar/plugin-cache/msgpack for a denser format.
Every producer and consumer of a stream must use the same codec.
{"docsConfig":{"theme":"palm","$schema":"https://mintlify.com/docs.json","name":"Stars Components","description":"Build own star network","colors":{"primary":"#5865f2","light":"#798df9","dark":"#5865f2"},"logo":{"light":"https://mintcdn.com/stars-components/--4czZiBBaYdvjl9/logo/light.svg?fit=max\u0026auto=format\u0026n=--4czZiBBaYdvjl9\u0026q=85\u0026s=5ca337b4b9216e27fb233eae6ad549d5","dark":"https://mintcdn.com/stars-components/--4czZiBBaYdvjl9/logo/dark.svg?fit=max\u0026auto=format\u0026n=--4czZiBBaYdvjl9\u0026q=85\u0026s=00acd9a5b3afb9a16ba49e1a503f02bb"},"favicon":"https://mintcdn.com/stars-components/xpSLFU01aQXYAILx/favicon.svg?fit=max\u0026auto=format\u0026n=xpSLFU01aQXYAILx\u0026q=85\u0026s=96ec68a0920748ffe785b6d680e64327","appearance":{"default":"dark"},"background":{"decoration":"gradient","color":{"light":"#ffffff","dark":"#202024"}},"navbar":{"links":[{"href":"https://join.wolfstar.rocks","label":"Community","type":"discord"}],"primary":{"type":"github","href":"https://github.com/wolfstar-project/stars-components"}},"styling":{"eyebrows":"breadcrumbs","codeblocks":"system","latex":false},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"navigation":{"global":{"anchors":[{"anchor":"Documentation","icon":"book-open-cover","href":"/documentation/guide"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"stars-components","hasAudioNarration":false,"actualSubdomain":"stars-components","customDomains":["stars-components.js.org"],"gitSource":{"type":"github","owner":"wolfstar-project","repo":"stars-components-docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"chroma":{"latestBuiltDeploymentHistoryId":"6ae9b91405f836676fdde73f","collectionId":"599809ff-2f46-4ed4-be07-e99a518e5dec","liveDeploymentHistoryId":"6ae9b91405f836676fdde73f","schemaVersion":"v3"},"feedback":{"edits":true},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ae9b91405f836676fdde73f","clientVersion":"0.0.4074","searchFilterCounts":[{"language":"default","tag":"Changelog","count":38},{"language":"default","tag":"Core framework","count":32},{"language":"default","tag":"Library","count":31},{"language":"default","tag":"Stars Components","count":27},{"language":"default","tag":"Plugins","count":23},{"language":"default","tag":"API Reference","count":22},{"language":"default","tag":"Platform helpers","count":15},{"language":"default","tag":"Infrastructure","count":9},{"language":"default","tag":"Guides","count":9},{"language":"default","tag":"Shared pieces","count":6}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":":root{--ws-bg: #242426;--ws-surface: #29292e;--ws-surface-hover: #303038;--ws-border: #40404c;--ws-heading: #e5e5df;--ws-muted: #a7a3ad;--ws-violet: #7357f6;--ws-purple: #a445dc;--ws-coral: #ff7a6a}body:has(.ws-home),body:has(.ws-home) #background-color{background:var(--ws-bg)!important}body:has(.ws-home) #content-area,body:has(.ws-home) #content{max-width:none!important;padding:0!important}body:has(.ws-home) #navbar{border-bottom:1px solid #111113;background:color-mix(in srgb, var(--ws-bg) 94%, transparent);backdrop-filter:blur(14px)}@media (min-width: 1024px){body:has(.ws-home) header#navbar:not(.hidden) a.select-none::after{content:'Stars Components';color:var(--ws-heading);font-size:1rem;font-weight:700;white-space:nowrap}body:has(.ws-home) header#navbar:not(.hidden) a.select-none{display:inline-flex;align-items:center;gap:0.75rem}}.ws-home{min-height:100vh;overflow:hidden;background:radial-gradient(circle at 68% 18%, rgb(115 87 246 / 8%), transparent 28rem), var(--ws-bg);color:var(--ws-heading)}.ws-shell{width:min(calc(100% - 3rem), 1440px);margin-inline:auto}.ws-hero{padding:5.75rem 0 8.5rem}.ws-hero-grid{display:grid;grid-template-columns:minmax(0, 1.42fr) minmax(20rem, 0.58fr);align-items:center;gap:4rem}.ws-hero-copy{width:100%;min-width:0;max-width:880px}.ws-hero-title{margin:0;color:var(--ws-heading);font-size:clamp(3.55rem, 4.5vw, 4.65rem);font-weight:750;letter-spacing:-0.055em;line-height:0.98}.ws-hero-title span{display:block;width:max-content;max-width:100%;margin-bottom:0.8rem;background:linear-gradient(100deg, var(--ws-violet) 3%, var(--ws-purple) 54%, var(--ws-coral) 98%);background-clip:text;color:transparent}.ws-hero-description{width:100%;max-width:720px;margin:1.8rem 0 0;color:var(--ws-muted);font-size:clamp(1.2rem, 1.6vw, 1.55rem);font-weight:450;letter-spacing:-0.015em;line-height:1.5;overflow-wrap:break-word}.ws-actions{display:flex;flex-wrap:wrap;gap:0.75rem;margin-top:2.2rem}.ws-button{display:inline-flex;min-height:3rem;align-items:center;justify-content:center;border:1px solid transparent;border-radius:999px;background:#36363e;color:#f1f1ed!important;font-size:0.98rem;font-weight:700;line-height:1;padding:0.85rem 1.45rem;text-decoration:none!important;background-image:none!important;box-shadow:none;transition:transform 160ms ease,\n\t\tbackground-color 160ms ease,\n\t\tborder-color 160ms ease}.ws-button:hover{border-color:#545461;background:#42424b;transform:translateY(-2px)}.ws-button-primary{background:linear-gradient(105deg, #674af1, #805cff);background-image:linear-gradient(105deg, #674af1, #805cff)!important;box-shadow:0 10px 28px rgb(99 73 240 / 24%)!important}.ws-button-primary:hover{border-color:transparent;background:linear-gradient(105deg, #7659f7, #8c6aff)}.ws-star-stage{position:relative;display:grid;min-height:360px;place-items:center;transform:translateX(-8rem)}.ws-star-orbit{position:absolute;width:24rem;height:24rem;border:1px solid rgb(117 88 246 / 10%);border-radius:50%;background:radial-gradient(circle, rgb(116 82 245 / 24%) 0%, rgb(92 67 186 / 8%) 38%, transparent 70%);filter:blur(2px)}.ws-star{position:relative;width:min(72%, 19rem);height:auto;filter:drop-shadow(0 18px 42px rgb(108 76 241 / 34%));animation:ws-star-float 6s ease-in-out infinite}.ws-features{padding:0 0 4.5rem}.ws-feature-grid{display:grid;grid-template-columns:repeat(3, minmax(0, 1fr));gap:1.2rem}.ws-feature-card{display:block;min-height:276px;border:1px solid var(--ws-border)!important;border-radius:0.9rem;background:linear-gradient(145deg, rgb(47 47 53 / 92%), rgb(41 41 46 / 92%));color:inherit!important;padding:1.9rem;text-decoration:none!important;background-image:linear-gradient(145deg, rgb(47 47 53 / 92%), rgb(41 41 46 / 92%))!important;transition:transform 180ms ease,\n\t\tborder-color 180ms ease,\n\t\tbackground-color 180ms ease,\n\t\tbox-shadow 180ms ease}.ws-feature-card:hover{border-color:#5a536f;background:var(--ws-surface-hover);box-shadow:0 18px 48px rgb(0 0 0 / 15%);transform:translateY(-4px)}.ws-feature-icon{display:grid;width:3.65rem;height:3.65rem;place-items:center;border:1px solid rgb(255 255 255 / 2%);border-radius:0.55rem;background:#33333b;font-size:1.65rem;font-family:'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;line-height:1}.ws-feature-card h2{margin:1.55rem 0 0;color:var(--ws-heading);font-size:1.15rem;font-weight:700;letter-spacing:-0.015em;line-height:1.3}.ws-feature-card p{margin:0.85rem 0 0;color:var(--ws-muted);font-size:1rem;line-height:1.65}.ws-start{border-top:1px solid var(--ws-border);padding:2.75rem 0 4rem}.ws-start-inner{display:grid;grid-template-columns:1fr auto auto;align-items:center;gap:1.5rem}.ws-start-label{margin:0 0 0.35rem;color:#9a85ff;font-size:0.78rem;font-weight:750;letter-spacing:0.1em;text-transform:uppercase}.ws-start h2{margin:0;color:var(--ws-heading);font-size:1.35rem;font-weight:700}.ws-start code{border:1px solid var(--ws-border);border-radius:0.55rem;background:#1d1d20;color:#d8d7df;font-size:0.86rem;padding:0.8rem 1rem}.ws-start a{color:#c8bfff!important;font-weight:700;text-decoration:none!important}@keyframes ws-star-float{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-12px) rotate(1deg)}}@media (max-width: 960px){.ws-hero{padding:7.5rem 0 4rem}.ws-hero-grid{grid-template-columns:1fr}.ws-star-stage{display:none;transform:none}.ws-feature-grid{grid-template-columns:repeat(2, minmax(0, 1fr))}.ws-start-inner{grid-template-columns:1fr}.ws-start code{width:fit-content;max-width:100%;overflow-x:auto}}@media (max-width: 640px){.ws-shell{width:min(calc(100% - 2rem), 1440px)}.ws-hero{padding:7.5rem 0 3.25rem}.ws-hero-title{font-size:clamp(2.65rem, 13vw, 3.8rem);line-height:1.02}.ws-hero-title span{margin-bottom:0.55rem}.ws-hero-description{font-size:1.08rem;line-height:1.55}.ws-actions{gap:0.6rem;margin-top:1.8rem}.ws-button{min-height:2.75rem;padding:0.75rem 1.1rem}.ws-feature-grid{grid-template-columns:1fr}.ws-feature-card{min-height:auto;padding:1.5rem}}@media (prefers-reduced-motion: reduce){.ws-star{animation:none}.ws-button,.ws-feature-card{transition:none}}.ws-install{position:relative;display:flex;align-items:center;justify-content:space-between;gap:0.75rem;margin:1rem 0;padding:0.75rem 1rem;border:1px solid rgb(128 128 128 / 0.3);border-radius:0.75rem;background:rgb(128 128 128 / 0.06)}.ws-install-body{display:flex;flex:1;min-width:0;align-items:center;justify-content:space-between;gap:0.75rem}.ws-install-command{overflow-x:auto;white-space:nowrap;font-size:0.875rem;background:none!important}.ws-install-prompt{opacity:0.5;user-select:none}.ws-install-copy,.ws-install-trigger{flex:none;border:1px solid rgb(128 128 128 / 0.3);border-radius:0.5rem;background:none;color:inherit;cursor:pointer}.ws-install-copy{padding:0.125rem 0.5rem;font-size:0.75rem}.ws-install-trigger{display:inline-flex;align-items:center;gap:0.5rem;padding:0.25rem 0.625rem;font-size:0.8125rem;font-weight:500}.ws-install-copy:hover,.ws-install-trigger:hover,.ws-install-trigger[aria-expanded=\"true\"]{background:rgb(128 128 128 / 0.15)}.ws-install-select{flex:none}.ws-install-chevron{font-size:0.75rem;transition:transform 0.15s}.ws-install-chevron-open{transform:rotate(180deg)}.ws-install-menu{position:absolute;top:calc(100% + 0.25rem);right:0;z-index:20;min-width:10rem;margin:0;padding:0.25rem;list-style:none;border:1px solid rgb(128 128 128 / 0.3);border-radius:0.625rem;background:var(--ws-surface, #29292e);color:var(--ws-heading, #e5e5df);box-shadow:0 8px 24px rgb(0 0 0 / 0.35)}.ws-install-option{display:flex;width:100%;align-items:center;gap:0.5rem;padding:0.375rem 0.5rem;border-radius:0.375rem;background:none;color:inherit;font-size:0.8125rem;text-align:left;cursor:pointer}.ws-install-option:hover,.ws-install-menu [aria-selected=\"true\"] .ws-install-option{background:rgb(128 128 128 / 0.2)}.ws-install-check{margin-left:auto;color:#ff7a6a}.ws-install-icon{width:1.125rem;height:1.125rem;flex:none}.ws-api-kind,.ws-api-badge{--ws-api-c: #94a3b8;display:inline-flex;align-items:center;padding:0.0625rem 0.5rem;border:1px solid color-mix(in srgb, var(--ws-api-c) 40%, transparent);border-radius:999px;background:color-mix(in srgb, var(--ws-api-c) 14%, transparent);color:color-mix(in srgb, var(--ws-api-c) 72%, currentColor);font-size:0.6875rem;font-weight:600;line-height:1.4;letter-spacing:0.02em;white-space:nowrap}.ws-api-kind-class{--ws-api-c: #7357f6}.ws-api-kind-interface{--ws-api-c: #14b8a6}.ws-api-kind-enum{--ws-api-c: #f59e0b}.ws-api-kind-type-alias{--ws-api-c: #ec4899}.ws-api-kind-function,.ws-api-kind-method,.ws-api-kind-constructor{--ws-api-c: #22c55e}.ws-api-kind-variable,.ws-api-kind-property{--ws-api-c: #0ea5e9}.ws-api-kind-accessor{--ws-api-c: #a445dc}.ws-api-kind-package{--ws-api-c: #ff7a6a}.ws-api-badge-deprecated{--ws-api-c: #ef4444}.ws-api-badge-abstract,.ws-api-badge-protected{--ws-api-c: #f97316}.ws-api-badge-static,.ws-api-badge-readonly{--ws-api-c: #6366f1}.ws-api-badge-optional{--ws-api-c: #64748b}.ws-api-badge-since{--ws-api-c: #10b981}.ws-api-badges{display:inline-flex;flex-wrap:wrap;gap:0.375rem}.ws-api-header,.ws-api-member-meta{display:flex;flex-wrap:wrap;align-items:center;gap:0.5rem;margin:0.5rem 0 1rem;font-size:0.8125rem}.ws-api-member-meta{margin:0 0 0.75rem}.ws-api-package,.ws-api-source,.ws-api-inherited,.ws-api-version{display:inline-flex;align-items:center;gap:0.25rem;border-bottom:none!important;color:rgb(128 128 128);font-size:0.75rem;text-decoration:none}.ws-api-package:hover,.ws-api-source:hover{color:var(--ws-violet, #7357f6)}.ws-api-source{margin-left:auto}.ws-api-package-name{font-size:0.9375rem;font-weight:600}.ws-api-type-link{border-bottom:none!important;color:var(--ws-violet, #7357f6);text-decoration:none}.ws-api-type-link:hover{text-decoration:underline}.ws-api-hierarchy{display:flex;flex-direction:column;gap:0.5rem;margin:1rem 0}.ws-api-hierarchy:empty{display:none}.ws-api-hierarchy-row{display:flex;flex-wrap:wrap;align-items:baseline;gap:0.5rem}.ws-api-hierarchy-label{min-width:6.5rem;color:rgb(128 128 128);font-size:0.75rem;font-weight:600;letter-spacing:0.04em;text-transform:uppercase}.ws-api-hierarchy-items{display:inline-flex;flex-wrap:wrap;gap:0.375rem}.ws-api-chip{padding:0.125rem 0.5rem;border:1px solid rgb(128 128 128 / 0.3);border-radius:0.5rem;background:rgb(128 128 128 / 0.08);font-size:0.8125rem}.ws-api-signature{position:relative;margin:0.75rem 0;border:1px solid rgb(128 128 128 / 0.3);border-radius:0.75rem;background:rgb(128 128 128 / 0.06)}.ws-api-signature-code{margin:0;padding:0.75rem 4rem 0.75rem 1rem;overflow-x:auto;background:none!important;font-size:0.8125rem;line-height:1.6;white-space:pre}.ws-api-signature-code code{background:none!important}.ws-api-copy{position:absolute;top:0.5rem;right:0.5rem;padding:0.125rem 0.5rem;border:1px solid rgb(128 128 128 / 0.3);border-radius:0.5rem;background:none;color:inherit;font-size:0.75rem;cursor:pointer;opacity:0;transition:opacity 0.15s}.ws-api-signature:hover .ws-api-copy,.ws-api-copy:focus-visible{opacity:1}.ws-api-copy:hover{background:rgb(128 128 128 / 0.15)}.ws-api-member{margin:0.5rem 0 1.5rem;padding:1rem 1.125rem;border:1px solid rgb(128 128 128 / 0.3);border-left:3px solid var(--ws-violet, #7357f6);border-radius:0.75rem;background:rgb(128 128 128 / 0.04)}.ws-api-member-property{border-left-color:#0ea5e9}.ws-api-member-method,.ws-api-member-constructor{border-left-color:#22c55e}.ws-api-member-accessor{border-left-color:#a445dc}.ws-api-member-body>:first-child,.ws-api-param-body>:first-child{margin-top:0}.ws-api-member-body>:last-child,.ws-api-param-body>:last-child{margin-bottom:0}.ws-api-params{margin:1rem 0}.ws-api-params-title{margin-bottom:0.375rem;color:rgb(128 128 128);font-size:0.75rem;font-weight:600;letter-spacing:0.04em;text-transform:uppercase}.ws-api-params-list{overflow:hidden;border:1px solid rgb(128 128 128 / 0.3);border-radius:0.625rem}.ws-api-param{padding:0.625rem 0.875rem}.ws-api-param+.ws-api-param{border-top:1px solid rgb(128 128 128 / 0.2)}.ws-api-param-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:0.5rem}.ws-api-param-name{font-weight:600}.ws-api-param-type{background:none!important;font-size:0.8125rem;white-space:pre-wrap}.ws-api-param-default{color:rgb(128 128 128);font-size:0.75rem}.ws-api-param-body{margin-top:0.25rem;font-size:0.875rem}.ws-api-enum{margin:1rem 0;overflow-x:auto}.ws-api-enum-table{width:100%;border-collapse:collapse;font-size:0.875rem}.ws-api-enum-table th,.ws-api-enum-table td{padding:0.5rem 0.75rem;border-bottom:1px solid rgb(128 128 128 / 0.2);text-align:left;vertical-align:top}.ws-api-enum-table th{color:rgb(128 128 128);font-size:0.75rem;letter-spacing:0.04em;text-transform:uppercase}.ws-api-deprecated{opacity:0.7;text-decoration:line-through}.ws-api-symbols{margin:1rem 0}.ws-api-filter{width:100%;padding:0.5rem 0.875rem;border:1px solid rgb(128 128 128 / 0.3);border-radius:0.625rem;background:rgb(128 128 128 / 0.06);color:inherit;font-size:0.875rem}.ws-api-filter:focus{outline:2px solid var(--ws-violet, #7357f6);outline-offset:1px}.ws-api-empty{margin:1.5rem 0;color:rgb(128 128 128)}.ws-api-symbol-group-title{display:flex;align-items:center;gap:0.5rem;margin:1.75rem 0 0.75rem;font-size:1rem}.ws-api-count{padding:0 0.5rem;border-radius:999px;background:rgb(128 128 128 / 0.18);font-size:0.6875rem;font-weight:600}.ws-api-symbol-grid{display:grid;grid-template-columns:repeat(auto-fill, minmax(17rem, 1fr));gap:0.625rem;margin:0;padding:0;list-style:none}.ws-api-symbol-grid>li{margin:0;padding:0}.ws-api-symbol{display:flex;flex-direction:column;gap:0.375rem;height:100%;padding:0.75rem 0.875rem;border:1px solid rgb(128 128 128 / 0.3);border-radius:0.75rem;color:inherit;text-decoration:none;transition:border-color 0.15s,\n\t\tbackground 0.15s}.ws-api-symbol:hover{border-color:var(--ws-violet, #7357f6);background:rgb(115 87 246 / 0.07)}.ws-api-symbol-head{display:flex;align-items:center;gap:0.5rem;min-width:0}.ws-api-symbol-name{overflow:hidden;font-family:ui-monospace, SFMono-Regular, Menlo, monospace;font-size:0.875rem;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.ws-api-symbol-summary{display:-webkit-box;overflow:hidden;color:rgb(128 128 128);font-size:0.8125rem;-webkit-line-clamp:2;-webkit-box-orient:vertical}"}],"page":{"pagePath":"documentation/packages/plugin-broker","slug":"/documentation/packages/plugin-broker","pageMetadata":{"title":"@wolfstar/plugin-broker","description":"Distribute gateway events across processes over Redis Streams with at-least-once delivery.","href":"/documentation/packages/plugin-broker"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Distribute gateway events across processes over Redis Streams with at-least-once delivery.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,img:`img`,p:`p`,pre:`pre`,span:`span`,..._provideComponents(),...props.components},{Card,CardGroup,CodeBlock,CodeGroup,Heading,Tip,Warning}=_components;if(!Card)_missingMdxReference(`Card`,true);if(!CardGroup)_missingMdxReference(`CardGroup`,true);if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!CodeGroup)_missingMdxReference(`CodeGroup`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Tip)_missingMdxReference(`Tip`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(CodeGroup,{children:[_jsx(CodeBlock,{filename:`npm`,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`npm`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` install`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` @wolfstar/plugin-broker`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ioredis`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`pnpm`,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`pnpm`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` @wolfstar/plugin-broker`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ioredis`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`yarn`,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`yarn`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` @wolfstar/plugin-broker`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ioredis`})]}),`\n`]})})}),_jsx(CodeBlock,{filename:`bun`,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`bun`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` add`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` @wolfstar/plugin-broker`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ioredis`})]}),`\n`]})})})]}),`\n`,_jsxs(CardGroup,{cols:2,children:[_jsx(Card,{title:`npm`,icon:`npm`,horizontal:true,href:`https://npmx.dev/package/@wolfstar/plugin-broker`}),_jsx(Card,{title:`Source`,icon:`github`,horizontal:true,href:`https://github.com/wolfstar-project/plugins/tree/main/packages/plugin-broker`})]}),`\n`,_jsxs(Tip,{children:[`See the `,_jsx(_components.a,{href:`/documentation/guide/plugins`,children:`Plugins guide`}),` for how plugins from wolfstar-project/plugins fit alongside the core framework.`]}),`\n`,_jsx(Heading,{level:`2`,id:`description`,children:`Description`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`@wolfstar/plugin-broker`}),` publishes and consumes messages over `,_jsx(_components.a,{href:`https://redis.io/docs/latest/develop/data-types/streams/`,children:`Redis Streams`}),`\nwith consumer-group semantics. One gateway process, or several sharded ones with\n`,_jsx(_components.a,{href:`/documentation/packages/plugin-sharder`,children:_jsx(_components.code,{children:`@wolfstar/plugin-sharder`})}),`, publishes dispatches. Any number of worker\nprocesses consume them and share the load, so a worker can restart, crash, or deploy without dropping the gateway\nconnection.`]}),`\n`,_jsxs(_components.p,{children:[`Unlike Redis Pub/Sub, entries survive a worker being down (`,_jsx(_components.code,{children:`XADD`}),` and `,_jsx(_components.code,{children:`XREADGROUP`}),` instead of `,_jsx(_components.code,{children:`PUBLISH`}),`). Unlike a\nplain `,_jsx(_components.code,{children:`XREAD`}),`, workers share the load through a consumer group instead of each receiving every message.`]}),`\n`,_jsx(Heading,{level:`2`,id:`producer`,children:`Producer`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`10`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`10`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`createBroker`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/plugin-broker'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Redis`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'ioredis'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` broker`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` createBroker`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tredis:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` Redis`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`process`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`env`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`REDIS_URL`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tstream:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'wolfstar:events'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tmaxLength:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 100_000`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` // XADD MAXLEN ~, omit for no trimming`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` broker`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`publish`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'messageCreate'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`payload`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`consumer`,children:`Consumer`}),`\n`,_jsxs(_components.p,{children:[`Import the `,_jsx(_components.code,{children:`register`}),` entry point before you create your `,_jsx(_components.code,{children:`Client`}),`, then configure `,_jsx(_components.code,{children:`broker`}),` on it. The consumer starts\nautomatically once the client starts listening:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`18`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`18`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/plugin-broker/register'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/http-framework'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`Redis`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'ioredis'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` client`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` Client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tbroker:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tredis:`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` Redis`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`process`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`env`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:`REDIS_URL`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`!`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`),`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tstream:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'wolfstar:events'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tgroup:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'workers'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tconsumer:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\" `worker-\"}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:\"${\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`process`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`pid`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"`\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tbatchSize:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 10`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tblock:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 5_000`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tclaimIdle:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 60_000`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tmaxDeliveries:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 5`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tdeadLetterStream:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'wolfstar:events:dead'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tshutdownSignals:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'SIGTERM'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'SIGINT'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t}`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`2`,id:`activating-with-modules`,children:[`Activating with `,_jsx(_components.code,{children:`modules`})]}),`\n`,_jsxs(_components.p,{children:[`On framework 6.1 and later, list the `,_jsx(_components.code,{children:`./module`}),` entry in `,_jsx(_components.code,{children:`modules`}),` in `,_jsx(_components.code,{children:`stars.config`}),` instead of importing `,_jsx(_components.code,{children:`register`}),`.\nIt needs the optional `,_jsx(_components.a,{href:`/documentation/packages/kit`,children:_jsx(_components.code,{children:`@wolfstar/kit`})}),` peer dependency, at `,_jsx(_components.code,{children:`^0.2.0 || ^0.3.0`}),`.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`8`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// stars.config.ts`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`defineConfig`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/http-framework/config'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/plugin-broker/module'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`export`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` default`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` defineConfig`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#D4D4D4`},children:`({`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tmodules:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'@wolfstar/plugin-broker/module'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tbroker:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`stream:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'wolfstar:events'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`group:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'workers'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#D4D4D4`},children:`})`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The module reads its options from the `,_jsx(_components.code,{children:`broker`}),` key of `,_jsx(_components.code,{children:`stars.config`}),`. The `,_jsx(_components.code,{children:`[specifier, options]`}),` tuple of `,_jsx(_components.code,{children:`modules`}),`\nstill works. Its options are merged over the `,_jsx(_components.code,{children:`broker`}),` key, so they win.`]}),`\n`,_jsxs(_components.p,{children:[`The optional `,_jsx(_components.a,{href:`/documentation/packages/schema`,children:_jsx(_components.code,{children:`@wolfstar/schema`})}),` peer dependency types the `,_jsx(_components.code,{children:`broker`}),` key in `,_jsx(_components.code,{children:`defineConfig`}),`.\nTypeScript only loads that type once the module is imported, so import `,_jsx(_components.code,{children:`@wolfstar/plugin-broker/module`}),` in `,_jsx(_components.code,{children:`stars.config.ts`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Module options must be JSON-serialisable. `,_jsx(_components.code,{children:`redis`}),` is a client instance and `,_jsx(_components.code,{children:`consumer`}),` is per process, so neither goes under the `,_jsx(_components.code,{children:`broker`}),` key of `,_jsx(_components.code,{children:`stars.config`}),`. Set both through `,_jsx(_components.code,{children:`ClientOptions.broker`}),`, which is shallowly merged over the module options. `,_jsx(_components.code,{children:`ClientOptions.broker`}),` is currently typed as the full `,_jsx(_components.code,{children:`BrokerConsumerOptions`}),`, so it must still include `,_jsx(_components.code,{children:`stream`}),` and `,_jsx(_components.code,{children:`group`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Without the `,_jsx(_components.code,{children:`stars`}),` CLI, pass the `,_jsx(_components.code,{children:`./plugin`}),` `,_jsx(_components.a,{href:`/documentation/packages/http-framework#plugins`,children:_jsx(_components.code,{children:`definePlugin`})}),` factory to the\n`,_jsx(_components.code,{children:`plugins`}),` client option:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`5`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`5`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` brokerPlugin`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:` from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/plugin-broker/plugin'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` client`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` Client`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tplugins:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`brokerPlugin`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({ `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`redis`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`stream:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'wolfstar:events'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`group:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'workers'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`consumer:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'w1'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` })]`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Use only one of the module, the `,_jsx(_components.code,{children:`./plugin`}),` factory, and `,_jsx(_components.code,{children:`register`}),`. Combining them installs the plugin’s hooks twice.`]}),`\n`,_jsx(Heading,{level:`2`,id:`delivery-guarantees`,children:`Delivery guarantees`}),`\n`,_jsxs(_components.p,{children:[`An entry is acknowledged once every listener for its event has resolved. A listener that throws leaves the entry\npending. A restarted consumer of the same name receives it again. With `,_jsx(_components.code,{children:`claimIdle`}),` set, whichever consumer claims the\nentry after it has been idle that long receives it instead.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Idle time counts from an entry’s last delivery. Set `,_jsx(_components.code,{children:`claimIdle`}),` well above your slowest listener’s run time, or another consumer can claim and\nhandle an entry that is still running.`]})}),`\n`,_jsxs(_components.p,{children:[`With `,_jsx(_components.code,{children:`maxDeliveries`}),` set, an entry delivered more than that many times moves to the dead-letter stream. The dead-letter\nentry keeps its `,_jsx(_components.code,{children:`event`}),` and `,_jsx(_components.code,{children:`payload`}),` fields plus the original `,_jsx(_components.code,{children:`id`}),`, `,_jsx(_components.code,{children:`stream`}),`, `,_jsx(_components.code,{children:`group`}),`, `,_jsx(_components.code,{children:`consumer`}),`, and `,_jsx(_components.code,{children:`deliveries`}),`. Without it, a\nfailing entry is retried forever.`]}),`\n`,_jsx(Heading,{level:`2`,id:`graceful-shutdown`,children:`Graceful shutdown`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`container.broker.stop()`}),` stops reading and waits for the in-flight entry. Anything left unacknowledged stays pending\nfor the next consumer. With `,_jsx(_components.code,{children:`shutdownSignals`}),`, the consumer does this on its own when the process receives one of\nthose signals.`]}),`\n`,_jsx(Heading,{level:`2`,id:`forwarding-gateway-dispatches`,children:`Forwarding gateway dispatches`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`forwardGatewayDispatches`}),` publishes every dispatch a `,_jsx(_components.a,{href:`/documentation/packages/plugin-gateway`,children:_jsx(_components.code,{children:`@wolfstar/plugin-gateway`})}),`\n`,_jsx(_components.code,{children:`GatewayClient`}),` receives, once it is written to the client’s cache. Workers that share a\n`,_jsx(_components.a,{href:`/documentation/packages/plugin-cache`,children:_jsx(_components.code,{children:`@wolfstar/plugin-cache`})}),` Redis cache see the state each dispatch left.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`8`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`createBroker`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`forwardGatewayDispatches`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/plugin-broker'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`GatewayDispatchEvents`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'discord-api-types/v10'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` broker`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` createBroker`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({ `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`redis`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`stream:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'wolfstar:events'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`maxLength:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 100_000`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` stopForwarding`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` forwardGatewayDispatches`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`gatewayClient`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`broker`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tevents:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`GatewayDispatchEvents`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`MessageCreate`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`], `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// omit to forward every dispatch`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`\tonError`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` (`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`error`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`payload`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`=>`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` console`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`error`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"`Failed to forward \"}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:\"${\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`payload`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`t`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"`\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`error`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`For a `,_jsx(_components.code,{children:`GatewayClient`}),`, each entry also carries the previous state of the dispatch’s entity (for example, the cached\nmessage a `,_jsx(_components.code,{children:`MESSAGE_UPDATE`}),` replaces), the shard that received the dispatch, and its gateway sequence number.`]}),`\n`,_jsxs(_components.p,{children:[`Forwarding includes the `,_jsx(_components.code,{children:`GUILD_DELETE`}),` the client emits on `,_jsx(_components.code,{children:`dispatch`}),` for a cached guild that a `,_jsx(_components.code,{children:`READY`}),` no longer lists,\nsuch as one the bot left while offline. Workers clean up those guilds too.`]}),`\n`,_jsx(Heading,{level:`3`,id:`run-listeners-on-the-workers-only`,children:`Run listeners on the workers only`}),`\n`,_jsxs(_components.p,{children:[`A bot that loads the same pieces on the gateway process and on the workers would handle each dispatch twice.\n`,_jsx(_components.code,{children:`forwardGatewayDispatches`}),` marks a `,_jsx(_components.code,{children:`GatewayClient`}),` as forwarding (`,_jsx(_components.code,{children:`client.forwardsDispatches`}),` returns `,_jsx(_components.code,{children:`true`}),`) until you\ncall its stop function. `,_jsx(_components.code,{children:`RegisterAsDispatchListener`}),` from `,_jsx(_components.a,{href:`/documentation/packages/plugin-gateway#run-a-listener-on-one-process`,children:_jsx(_components.code,{children:`@wolfstar/plugin-gateway`})}),`\nreads that flag on every emit. It runs the listener on the workers while the gateway forwards, and on the gateway client\nwhen nothing is forwarded, with no environment variable to read:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`8`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`8`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`EventGatewayListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RegisterAsDispatchListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`type`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` Message`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/plugin-gateway'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`@`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`RegisterAsDispatchListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'messageCreate'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`export`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` class`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` ModerationListener`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` extends`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` EventGatewayListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'messageCreate'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tpublic`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` override`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` run`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`message`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` Message`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`\t\t// Runs once per dispatch, on whichever process handles it`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t}`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The decorator throws for the events a worker never receives, such as `,_jsx(_components.code,{children:`clientReady`}),` and `,_jsx(_components.code,{children:`shardReady`}),`. With `,_jsx(_components.code,{children:`events`}),` set,\na listener of an event built from a dispatch that is not forwarded runs nowhere. Delivery is at-least-once, so keep these\nlisteners idempotent.`]}),`\n`,_jsx(Heading,{level:`2`,id:`replaying-gateway-dispatches-on-workers`,children:`Replaying gateway dispatches on workers`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`replayGatewayDispatches(consumer, client)`}),` replays the dispatches `,_jsx(_components.code,{children:`forwardGatewayDispatches`}),` publishes on a worker’s own\n`,_jsx(_components.code,{children:`GatewayClient`}),`, which never connects to Discord. The worker’s `,_jsx(_components.code,{children:`EventGatewayListener`}),` pieces receive the same events,\nwith the same structures and `,_jsx(_components.code,{children:`old`}),` arguments, as if the dispatch happened in-process. Use it when you want to run\ngateway listeners on workers instead of on the process connected to Discord.`]}),`\n`,_jsxs(_components.p,{children:[`Both clients must use the same `,_jsx(_components.a,{href:`/documentation/packages/plugin-cache`,children:_jsx(_components.code,{children:`@wolfstar/plugin-cache`})}),` Redis cache.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`22`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`22`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`BrokerConsumer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`createBroker`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`forwardGatewayDispatches`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`replayGatewayDispatches`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/plugin-broker'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`GatewayClient`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/plugin-gateway'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`GatewayDispatchEvents`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'discord-api-types/v10'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Gateway process`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` gatewayClient`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` GatewayClient`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({ `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`...`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`options`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`cache:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` redisCache`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` broker`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` createBroker`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({ `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`redis`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`stream:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'wolfstar:events'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`forwardGatewayDispatches`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`gatewayClient`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`broker`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` gatewayClient`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`start`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`();`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// Worker: same cache, never connected`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` worker`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` GatewayClient`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({ `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`...`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`options`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`cache:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` redisCache`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` consumer`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` new`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` BrokerConsumer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`({`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tredis`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tstream:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'wolfstar:events'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tgroup:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'workers'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tconsumer:`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` 'worker-1'`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`const`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4FC1FF`},children:` stopReplaying`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:` =`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` replayGatewayDispatches`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`consumer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`worker`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\tevents:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` [`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`GatewayDispatchEvents`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`MessageUpdate`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`] `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`// omit to replay every type the client handles`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`});`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` consumer`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`start`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`();`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`A worker’s `,_jsx(_components.code,{children:`messageUpdate`}),` listener receives the message as it was before the edit. The gateway process ships that\nprevious state with the dispatch as raw API data, and the worker rebuilds it. Relations of the previous state (author,\nguild, and so on) resolve from the cache when the worker handles the entry, so they can be newer than the dispatch.\n`,_jsx(_components.code,{children:`raw`}),` listeners receive the same payload (`,_jsx(_components.code,{children:`op`}),`, `,_jsx(_components.code,{children:`s`}),`, `,_jsx(_components.code,{children:`t`}),`, `,_jsx(_components.code,{children:`d`}),`) on both sides.`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`replayGatewayDispatches`}),` does not replay `,_jsx(_components.code,{children:`READY`}),`, `,_jsx(_components.code,{children:`INTERACTION_CREATE`}),`, or shard lifecycle events (`,_jsx(_components.code,{children:`shardReady`}),`,\n`,_jsx(_components.code,{children:`shardClose`}),`, and so on). A worker’s `,_jsx(_components.code,{children:`client.user`}),` stays `,_jsx(_components.code,{children:`null`}),`.`]}),`\n`,_jsx(Heading,{level:`3`,id:`acknowledgement-and-ordering`,children:`Acknowledgement and ordering`}),`\n`,_jsx(_components.p,{children:`An entry is acknowledged once its listeners have resolved, async ones included. A worker listener that throws or\nrejects leaves the entry pending for redelivery.`}),`\n`,_jsxs(_components.p,{children:[`A failure applies to the whole entry, not to a single listener. When one of several listeners of an event throws, the\nredelivery runs the listeners that already succeeded again. A connected `,_jsx(_components.code,{children:`GatewayClient`}),` would not do this.`]}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Keep worker listeners idempotent, and enqueue slow work instead of awaiting it. A consumer handles one entry at a time, and another worker can\nclaim an entry pending for longer than `,_jsx(_components.code,{children:`claimIdle`}),` while it still runs.`]})}),`\n`,_jsxs(_components.p,{children:[`Ordering holds per consumer, not across the consumer group. Workers in one group take different entries and run them\nconcurrently, so two events of the same guild can replay out of order across workers. The cached relations a listener\nresolves can also differ from the gateway process’s. The previous state shipped with each entry is a snapshot, so `,_jsx(_components.code,{children:`old`}),`\nstays correct.`]}),`\n`,_jsx(Heading,{level:`3`,id:`entry-fields`,children:`Entry fields`}),`\n`,_jsxs(_components.p,{children:[`Stream entries can carry optional `,_jsx(_components.code,{children:`state`}),`, `,_jsx(_components.code,{children:`shard`}),`, and `,_jsx(_components.code,{children:`sequence`}),` fields next to `,_jsx(_components.code,{children:`event`}),` and `,_jsx(_components.code,{children:`payload`}),`. Pass them to\n`,_jsx(_components.code,{children:`broker.publish`}),` as a third `,_jsx(_components.code,{children:`options`}),` argument. `,_jsx(_components.code,{children:`state`}),` is encoded with the configured codec, like the payload.\nListeners read them from `,_jsx(_components.code,{children:`BrokerMessage.state`}),`, `,_jsx(_components.code,{children:`BrokerMessage.shard`}),`, and `,_jsx(_components.code,{children:`BrokerMessage.sequence`}),`. Entries without\nthese fields, and consumers that ignore them, work as before.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`await`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` broker`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`publish`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'MESSAGE_UPDATE'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`payload`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`state:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` previousMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`shard:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 0`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`sequence:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:` 42`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` });`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`brokerlistener-piece`,children:`BrokerListener piece`}),`\n`,_jsxs(_components.p,{children:[`A `,_jsx(_components.code,{children:`BrokerListener`}),` piece, typed by event name, is loaded from the `,_jsx(_components.code,{children:`listeners`}),` directory. Augment `,_jsx(_components.code,{children:`BrokerEvents`}),` in your\napplication to type the events you publish and consume:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`14`,language:`typescript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`typescript`,children:_jsxs(_components.code,{language:`typescript`,numberOfLines:`14`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`import`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`BrokerListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`RegisterAsBrokerListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`type`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:` BrokerMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` } `}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`from`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/plugin-broker'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`;`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`declare`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` module`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '@wolfstar/plugin-broker'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tinterface`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` BrokerEvents`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tmessageCreate`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`content`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` string`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` };`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t}`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`@`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`RegisterAsBrokerListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'messageCreate'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#C586C0`},children:`export`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` class`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` LogMessagesListener`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` extends`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` BrokerListener`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'messageCreate'`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`> {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:`\tpublic`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#569CD6`},children:` override`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:` run`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`payload`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`content`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#4EC9B0`},children:` string`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }, `}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#9CDCFE`},children:`message`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`:`}),_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#4EC9B0`},children:` BrokerMessage`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`) {`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`\t\tconsole`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#8250DF`,\"--shiki-dark\":`#DCDCAA`},children:`log`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`(`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"`[\"}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:\"${\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`message`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`id`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`] `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:\"${\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`payload`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#D4D4D4`},children:`.`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#9CDCFE`},children:`content`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#569CD6`},children:`}`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:\"`\"}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`);`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`\t}`})}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`codec`,children:`Codec`}),`\n`,_jsxs(_components.p,{children:[`Payloads use a `,_jsx(_components.code,{children:`CacheCodec`}),` from `,_jsx(_components.code,{children:`@wolfstar/plugin-cache`}),`: `,_jsx(_components.code,{children:`jsonCodec()`}),` by default, or `,_jsx(_components.code,{children:`msgpackCodec()`}),` from\n`,_jsx(_components.code,{children:`@wolfstar/plugin-cache/msgpack`}),` for a denser format.`]}),`\n`,_jsx(Warning,{children:`Every producer and consumer of a stream must use the same codec.`}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.a,{href:`https://npmx.dev/package/@wolfstar/plugin-broker`,children:_jsx(_components.img,{src:`https://npmx.dev/api/registry/badge/version/@wolfstar/plugin-broker`,alt:`version`})}),`\n`,_jsx(_components.a,{href:`https://npmx.dev/package/@wolfstar/plugin-broker`,children:_jsx(_components.img,{src:`https://npmx.dev/api/registry/badge/downloads/@wolfstar/plugin-broker`,alt:`downloads`})}),`\n`,_jsx(_components.a,{href:`https://github.com/wolfstar-project/plugins/blob/main/LICENSE`,children:_jsx(_components.img,{src:`https://img.shields.io/github/license/wolfstar-project/plugins?style=flat-square\u0026color=informational`,alt:`license`})})]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":"system","config":{},"pageMetadata":{"title":"@wolfstar/plugin-broker","description":"Distribute gateway events across processes over Redis Streams with at-least-once delivery.","href":"/documentation/packages/plugin-broker"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Description","slug":"description","depth":2,"children":[]},{"title":"Producer","slug":"producer","depth":2,"children":[]},{"title":"Consumer","slug":"consumer","depth":2,"children":[]},{"title":"Activating with modules","slug":"activating-with-modules","depth":2,"children":[]},{"title":"Delivery guarantees","slug":"delivery-guarantees","depth":2,"children":[]},{"title":"Graceful shutdown","slug":"graceful-shutdown","depth":2,"children":[]},{"title":"Forwarding gateway dispatches","slug":"forwarding-gateway-dispatches","depth":2,"children":[{"title":"Run listeners on the workers only","slug":"run-listeners-on-the-workers-only","depth":3,"children":[]}]},{"title":"Replaying gateway dispatches on workers","slug":"replaying-gateway-dispatches-on-workers","depth":2,"children":[{"title":"Acknowledgement and ordering","slug":"acknowledgement-and-ordering","depth":3,"children":[]},{"title":"Entry fields","slug":"entry-fields","depth":3,"children":[]}]},{"title":"BrokerListener piece","slug":"brokerlistener-piece","depth":2,"children":[]},{"title":"Codec","slug":"codec","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"stars-components","siteName":"Stars Components","title":"@wolfstar/plugin-broker - Stars Components","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-03T10:36:17.849Z","originalFileLocation":"documentation/packages/plugin-broker.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"dark\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Distribute gateway events across processes over Redis Streams with at-least-once delivery.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Stars Components\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/stars-components/hyZKnH7hsbqdjHty/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/stars-components/hyZKnH7hsbqdjHty/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/stars-components/hyZKnH7hsbqdjHty/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/stars-components/hyZKnH7hsbqdjHty/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/stars-components/hyZKnH7hsbqdjHty/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/stars-components/hyZKnH7hsbqdjHty/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/stars-components/hyZKnH7hsbqdjHty/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/stars-components/hyZKnH7hsbqdjHty/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/stars-components/hyZKnH7hsbqdjHty/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"@wolfstar/plugin-broker - Stars Components\">\u003cmeta data-mint-head property=\"og:description\" content=\"Distribute gateway events across processes over Redis Streams with at-least-once delivery.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Stars Components\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://stars-components.js.org/documentation/packages/plugin-broker\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://stars-components.mintlify.site/_mintlify/api/og/v2?division=Plugins\u0026amp;title=%40wolfstar%2Fplugin-broker\u0026amp;description=Distribute+gateway+events+across+processes+over+Redis+Streams+with+at-least-once+delivery.\u0026amp;theme=a387e884ccbff4213256fc9f\u0026amp;signature=78b8153a43aa595defcb4f75e98d6bec6ef153777be37aa88e1bbd93d20f44fc\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"@wolfstar/plugin-broker - Stars Components\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Distribute gateway events across processes over Redis Streams with at-least-once delivery.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://stars-components.mintlify.site/_mintlify/api/og/v2?division=Plugins\u0026amp;title=%40wolfstar%2Fplugin-broker\u0026amp;description=Distribute+gateway+events+across+processes+over+Redis+Streams+with+at-least-once+delivery.\u0026amp;theme=a387e884ccbff4213256fc9f\u0026amp;signature=78b8153a43aa595defcb4f75e98d6bec6ef153777be37aa88e1bbd93d20f44fc\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/stars-components/hyZKnH7hsbqdjHty/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Stars Components\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#5865f2\">\u003clink data-mint-head rel=\"canonical\" href=\"https://stars-components.js.org/documentation/packages/plugin-broker\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/documentation/packages/plugin-broker.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://stars-components.js.org/#organization\",\"name\":\"Stars Components\",\"url\":\"https://stars-components.js.org\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/stars-components/--4czZiBBaYdvjl9/logo/light.svg?fit=max\u0026auto=format\u0026n=--4czZiBBaYdvjl9\u0026q=85\u0026s=5ca337b4b9216e27fb233eae6ad549d5\"}},{\"@type\":\"WebSite\",\"@id\":\"https://stars-components.js.org#website\",\"name\":\"Stars Components\",\"url\":\"https://stars-components.js.org\",\"publisher\":{\"@id\":\"https://stars-components.js.org/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://stars-components.js.org/documentation/packages/plugin-broker#webpage\",\"url\":\"https://stars-components.js.org/documentation/packages/plugin-broker\",\"name\":\"@wolfstar/plugin-broker\",\"description\":\"Distribute gateway events across processes over Redis Streams with at-least-once delivery.\",\"dateModified\":\"2026-11-03T10:36:17.849Z\",\"isPartOf\":{\"@id\":\"https://stars-components.js.org#website\"},\"breadcrumb\":{\"@id\":\"https://stars-components.js.org/documentation/packages/plugin-broker#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://stars-components.js.org/documentation/packages/plugin-broker#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Plugins\",\"item\":\"https://stars-components.js.org/documentation/packages/plugin-api\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"@wolfstar/plugin-broker\",\"item\":\"https://stars-components.js.org/documentation/packages/plugin-broker\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://stars-components.js.org/documentation/packages/plugin-broker#article\",\"headline\":\"@wolfstar/plugin-broker\",\"name\":\"@wolfstar/plugin-broker\",\"description\":\"Distribute gateway events across processes over Redis Streams with at-least-once delivery.\",\"url\":\"https://stars-components.js.org/documentation/packages/plugin-broker\",\"mainEntityOfPage\":{\"@id\":\"https://stars-components.js.org/documentation/packages/plugin-broker#webpage\"},\"dateModified\":\"2026-11-03T10:36:17.849Z\",\"publisher\":{\"@id\":\"https://stars-components.js.org/#organization\"},\"isPartOf\":{\"@id\":\"https://stars-components.js.org#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Stars Components\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Stars Components","nav":{"global":{"anchors":[{"anchor":"Documentation","icon":"book-open-cover","href":"/documentation/guide"}]},"tabs":[{"tab":"Guides","icon":"book-open","pages":[{"title":"Guides","href":"/documentation/guide"}]},{"tab":"Errors","icon":"triangle-exclamation","pages":[{"title":"Errors","href":"/documentation/errors/cli"}]},{"tab":"Changelog","icon":"list","pages":[{"title":"Changelog","href":"/documentation/changelog"}]},{"tab":"API Reference","icon":"code","pages":[{"title":"API Reference","href":"/documentation/api"}]},{"tab":"Library","icon":"boxes-stacked","groups":[{"group":"Core framework","root":{"title":"Packages","href":"/documentation/packages"},"pages":[{"title":"@wolfstar/http-framework","href":"/documentation/packages/http-framework"},{"title":"@wolfstar/decorators","href":"/documentation/packages/decorators"},{"title":"@wolfstar/kit","href":"/documentation/packages/kit"},{"title":"@wolfstar/cli","href":"/documentation/packages/cli"},{"title":"@wolfstar/schema","href":"/documentation/packages/schema"},{"title":"@wolfstar/vite-server","href":"/documentation/packages/vite-server"},{"title":"@wolfstar/nitro-server","href":"/documentation/packages/nitro-server"},{"title":"@wolfstar/create-http-framework","href":"/documentation/packages/create-http-framework"},{"title":"@wolfstar/i18next-backend","href":"/documentation/packages/i18next-backend"},{"title":"@wolfstar/http-framework-test-utils","href":"/documentation/packages/http-framework-test-utils"},{"title":"@wolfstar/http-framework-utilities","href":"/documentation/packages/http-framework-utilities"}]},{"group":"Infrastructure","pages":[{"title":"@wolfstar/env-utilities","href":"/documentation/packages/env-utilities"},{"title":"@wolfstar/safe-fetch","href":"/documentation/packages/safe-fetch"},{"title":"@wolfstar/start-banner","href":"/documentation/packages/start-banner"}]},{"group":"Shared pieces","pages":[{"title":"@wolfstar/shared-http-pieces","href":"/documentation/packages/shared-http-pieces"},{"title":"@wolfstar/shared-influx-pieces","href":"/documentation/packages/shared-influx-pieces"}]},{"group":"Platform helpers","pages":[{"title":"@wolfstar/discord-utilities","href":"/documentation/packages/discord-utilities"},{"title":"@wolfstar/influx-utilities","href":"/documentation/packages/influx-utilities"},{"title":"@wolfstar/reddit-helpers","href":"/documentation/packages/reddit-helpers"},{"title":"@wolfstar/twitch-helpers","href":"/documentation/packages/twitch-helpers"},{"title":"@wolfstar/weather-helpers","href":"/documentation/packages/weather-helpers"}]},{"group":"Plugins","pages":[{"title":"@wolfstar/plugin-api","description":"Expose a standalone REST API server alongside HTTP Framework interactions.","href":"/documentation/packages/plugin-api"},{"title":"@wolfstar/plugin-broker","href":"/documentation/packages/plugin-broker"},{"title":"@wolfstar/plugin-cache","description":"A storage-agnostic Discord entity cache for plugin-gateway, backed by in-memory Maps with LRU bounds or by Redis with per-entity TTL and compression.","href":"/documentation/packages/plugin-cache"},{"title":"@wolfstar/plugin-gateway","href":"/documentation/packages/plugin-gateway"},{"title":"@wolfstar/plugin-i18next","href":"/documentation/packages/plugin-i18next"},{"title":"@wolfstar/plugin-logger","href":"/documentation/packages/plugin-logger"},{"title":"@wolfstar/plugin-opentelemetry","href":"/documentation/packages/plugin-opentelemetry"},{"title":"@wolfstar/plugin-scheduled-tasks","href":"/documentation/packages/plugin-scheduled-tasks"},{"title":"@wolfstar/plugin-sharder","href":"/documentation/packages/plugin-sharder"},{"title":"@wolfstar/plugin-subcommands-advanced","href":"/documentation/packages/plugin-subcommands-advanced"}]}]}]},"basePath":"","title":"@wolfstar/plugin-broker - Stars Components","buildId":"dpl_BLQvU86QFwq3AhPofSTw6q8dGWKm","deploymentId":"dpl_BLQvU86QFwq3AhPofSTw6q8dGWKm","dynamics":["a74be98ba7"],"chunks":["zoom-image-lightbox-CLQdF-Ar.js","lightbox-handle-r17bVUz3.js"]}