@neontechspace/fluxerly 1000.0.0-nightly.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +833 -0
- package/LICENSE +201 -0
- package/README.md +129 -0
- package/agents/AGENTS.md +195 -0
- package/dist/api/default/application.d.ts +34 -0
- package/dist/api/default/application.d.ts.map +1 -0
- package/dist/api/default/application.js +2 -0
- package/dist/api/default/application.js.map +1 -0
- package/dist/api/default/attachments.d.ts +89 -0
- package/dist/api/default/attachments.d.ts.map +1 -0
- package/dist/api/default/attachments.js +2 -0
- package/dist/api/default/attachments.js.map +1 -0
- package/dist/api/default/audit-logs.d.ts +48 -0
- package/dist/api/default/audit-logs.d.ts.map +1 -0
- package/dist/api/default/audit-logs.js +2 -0
- package/dist/api/default/audit-logs.js.map +1 -0
- package/dist/api/default/bot.d.ts +200 -0
- package/dist/api/default/bot.d.ts.map +1 -0
- package/dist/api/default/bot.js +309 -0
- package/dist/api/default/bot.js.map +1 -0
- package/dist/api/default/cache.d.ts +105 -0
- package/dist/api/default/cache.d.ts.map +1 -0
- package/dist/api/default/cache.js +2 -0
- package/dist/api/default/cache.js.map +1 -0
- package/dist/api/default/channels.d.ts +249 -0
- package/dist/api/default/channels.d.ts.map +1 -0
- package/dist/api/default/channels.js +2 -0
- package/dist/api/default/channels.js.map +1 -0
- package/dist/api/default/client.d.ts +528 -0
- package/dist/api/default/client.d.ts.map +1 -0
- package/dist/api/default/client.js +301 -0
- package/dist/api/default/client.js.map +1 -0
- package/dist/api/default/collectors.d.ts +76 -0
- package/dist/api/default/collectors.d.ts.map +1 -0
- package/dist/api/default/collectors.js +2 -0
- package/dist/api/default/collectors.js.map +1 -0
- package/dist/api/default/commands.d.ts +91 -0
- package/dist/api/default/commands.d.ts.map +1 -0
- package/dist/api/default/commands.js +92 -0
- package/dist/api/default/commands.js.map +1 -0
- package/dist/api/default/direct-messages.d.ts +111 -0
- package/dist/api/default/direct-messages.d.ts.map +1 -0
- package/dist/api/default/direct-messages.js +2 -0
- package/dist/api/default/direct-messages.js.map +1 -0
- package/dist/api/default/discovery.d.ts +76 -0
- package/dist/api/default/discovery.d.ts.map +1 -0
- package/dist/api/default/discovery.js +2 -0
- package/dist/api/default/discovery.js.map +1 -0
- package/dist/api/default/emojis.d.ts +88 -0
- package/dist/api/default/emojis.d.ts.map +1 -0
- package/dist/api/default/emojis.js +2 -0
- package/dist/api/default/emojis.js.map +1 -0
- package/dist/api/default/events.d.ts +127 -0
- package/dist/api/default/events.d.ts.map +1 -0
- package/dist/api/default/events.js +2 -0
- package/dist/api/default/events.js.map +1 -0
- package/dist/api/default/gateway.d.ts +62 -0
- package/dist/api/default/gateway.d.ts.map +1 -0
- package/dist/api/default/gateway.js +2 -0
- package/dist/api/default/gateway.js.map +1 -0
- package/dist/api/default/guards.d.ts +87 -0
- package/dist/api/default/guards.d.ts.map +1 -0
- package/dist/api/default/guards.js +78 -0
- package/dist/api/default/guards.js.map +1 -0
- package/dist/api/default/guilds.d.ts +230 -0
- package/dist/api/default/guilds.d.ts.map +1 -0
- package/dist/api/default/guilds.js +2 -0
- package/dist/api/default/guilds.js.map +1 -0
- package/dist/api/default/helpers.d.ts +79 -0
- package/dist/api/default/helpers.d.ts.map +1 -0
- package/dist/api/default/helpers.js +79 -0
- package/dist/api/default/helpers.js.map +1 -0
- package/dist/api/default/instance.d.ts +47 -0
- package/dist/api/default/instance.d.ts.map +1 -0
- package/dist/api/default/instance.js +2 -0
- package/dist/api/default/instance.js.map +1 -0
- package/dist/api/default/invites.d.ts +57 -0
- package/dist/api/default/invites.d.ts.map +1 -0
- package/dist/api/default/invites.js +2 -0
- package/dist/api/default/invites.js.map +1 -0
- package/dist/api/default/logging.d.ts +37 -0
- package/dist/api/default/logging.d.ts.map +1 -0
- package/dist/api/default/logging.js +2 -0
- package/dist/api/default/logging.js.map +1 -0
- package/dist/api/default/members.d.ts +442 -0
- package/dist/api/default/members.d.ts.map +1 -0
- package/dist/api/default/members.js +2 -0
- package/dist/api/default/members.js.map +1 -0
- package/dist/api/default/messages.d.ts +898 -0
- package/dist/api/default/messages.d.ts.map +1 -0
- package/dist/api/default/messages.js +2 -0
- package/dist/api/default/messages.js.map +1 -0
- package/dist/api/default/oauth.d.ts +168 -0
- package/dist/api/default/oauth.d.ts.map +1 -0
- package/dist/api/default/oauth.js +84 -0
- package/dist/api/default/oauth.js.map +1 -0
- package/dist/api/default/permissions.d.ts +44 -0
- package/dist/api/default/permissions.d.ts.map +1 -0
- package/dist/api/default/permissions.js +2 -0
- package/dist/api/default/permissions.js.map +1 -0
- package/dist/api/default/presence.d.ts +88 -0
- package/dist/api/default/presence.d.ts.map +1 -0
- package/dist/api/default/presence.js +2 -0
- package/dist/api/default/presence.js.map +1 -0
- package/dist/api/default/rest.d.ts +28 -0
- package/dist/api/default/rest.d.ts.map +1 -0
- package/dist/api/default/rest.js +2 -0
- package/dist/api/default/rest.js.map +1 -0
- package/dist/api/default/results.d.ts +31 -0
- package/dist/api/default/results.d.ts.map +1 -0
- package/dist/api/default/results.js +14 -0
- package/dist/api/default/results.js.map +1 -0
- package/dist/api/default/roles.d.ts +119 -0
- package/dist/api/default/roles.d.ts.map +1 -0
- package/dist/api/default/roles.js +2 -0
- package/dist/api/default/roles.js.map +1 -0
- package/dist/api/default/stickers.d.ts +92 -0
- package/dist/api/default/stickers.d.ts.map +1 -0
- package/dist/api/default/stickers.js +2 -0
- package/dist/api/default/stickers.js.map +1 -0
- package/dist/api/default/supervisor.d.ts +51 -0
- package/dist/api/default/supervisor.d.ts.map +1 -0
- package/dist/api/default/supervisor.js +53 -0
- package/dist/api/default/supervisor.js.map +1 -0
- package/dist/api/default/threads.d.ts +158 -0
- package/dist/api/default/threads.d.ts.map +1 -0
- package/dist/api/default/threads.js +2 -0
- package/dist/api/default/threads.js.map +1 -0
- package/dist/api/default/users.d.ts +73 -0
- package/dist/api/default/users.d.ts.map +1 -0
- package/dist/api/default/users.js +2 -0
- package/dist/api/default/users.js.map +1 -0
- package/dist/api/default/webhook-client.d.ts +149 -0
- package/dist/api/default/webhook-client.d.ts.map +1 -0
- package/dist/api/default/webhook-client.js +69 -0
- package/dist/api/default/webhook-client.js.map +1 -0
- package/dist/api/default/webhooks.d.ts +62 -0
- package/dist/api/default/webhooks.d.ts.map +1 -0
- package/dist/api/default/webhooks.js +2 -0
- package/dist/api/default/webhooks.js.map +1 -0
- package/dist/api/effect/application.d.ts +29 -0
- package/dist/api/effect/application.d.ts.map +1 -0
- package/dist/api/effect/application.js +2 -0
- package/dist/api/effect/application.js.map +1 -0
- package/dist/api/effect/attachments.d.ts +84 -0
- package/dist/api/effect/attachments.d.ts.map +1 -0
- package/dist/api/effect/attachments.js +2 -0
- package/dist/api/effect/attachments.js.map +1 -0
- package/dist/api/effect/audit-logs.d.ts +42 -0
- package/dist/api/effect/audit-logs.d.ts.map +1 -0
- package/dist/api/effect/audit-logs.js +2 -0
- package/dist/api/effect/audit-logs.js.map +1 -0
- package/dist/api/effect/bot.d.ts +233 -0
- package/dist/api/effect/bot.d.ts.map +1 -0
- package/dist/api/effect/bot.js +230 -0
- package/dist/api/effect/bot.js.map +1 -0
- package/dist/api/effect/cache.d.ts +103 -0
- package/dist/api/effect/cache.d.ts.map +1 -0
- package/dist/api/effect/cache.js +2 -0
- package/dist/api/effect/cache.js.map +1 -0
- package/dist/api/effect/channels.d.ts +231 -0
- package/dist/api/effect/channels.d.ts.map +1 -0
- package/dist/api/effect/channels.js +2 -0
- package/dist/api/effect/channels.js.map +1 -0
- package/dist/api/effect/client.d.ts +622 -0
- package/dist/api/effect/client.d.ts.map +1 -0
- package/dist/api/effect/client.js +191 -0
- package/dist/api/effect/client.js.map +1 -0
- package/dist/api/effect/collectors.d.ts +90 -0
- package/dist/api/effect/collectors.d.ts.map +1 -0
- package/dist/api/effect/collectors.js +2 -0
- package/dist/api/effect/collectors.js.map +1 -0
- package/dist/api/effect/commands.d.ts +86 -0
- package/dist/api/effect/commands.d.ts.map +1 -0
- package/dist/api/effect/commands.js +87 -0
- package/dist/api/effect/commands.js.map +1 -0
- package/dist/api/effect/direct-messages.d.ts +102 -0
- package/dist/api/effect/direct-messages.d.ts.map +1 -0
- package/dist/api/effect/direct-messages.js +2 -0
- package/dist/api/effect/direct-messages.js.map +1 -0
- package/dist/api/effect/discovery.d.ts +68 -0
- package/dist/api/effect/discovery.d.ts.map +1 -0
- package/dist/api/effect/discovery.js +2 -0
- package/dist/api/effect/discovery.js.map +1 -0
- package/dist/api/effect/emojis.d.ts +77 -0
- package/dist/api/effect/emojis.d.ts.map +1 -0
- package/dist/api/effect/emojis.js +2 -0
- package/dist/api/effect/emojis.js.map +1 -0
- package/dist/api/effect/events.d.ts +78 -0
- package/dist/api/effect/events.d.ts.map +1 -0
- package/dist/api/effect/events.js +12 -0
- package/dist/api/effect/events.js.map +1 -0
- package/dist/api/effect/failures.d.ts +14 -0
- package/dist/api/effect/failures.d.ts.map +1 -0
- package/dist/api/effect/failures.js +2 -0
- package/dist/api/effect/failures.js.map +1 -0
- package/dist/api/effect/gateway.d.ts +63 -0
- package/dist/api/effect/gateway.d.ts.map +1 -0
- package/dist/api/effect/gateway.js +2 -0
- package/dist/api/effect/gateway.js.map +1 -0
- package/dist/api/effect/guards.d.ts +91 -0
- package/dist/api/effect/guards.d.ts.map +1 -0
- package/dist/api/effect/guards.js +94 -0
- package/dist/api/effect/guards.js.map +1 -0
- package/dist/api/effect/guilds.d.ts +221 -0
- package/dist/api/effect/guilds.d.ts.map +1 -0
- package/dist/api/effect/guilds.js +2 -0
- package/dist/api/effect/guilds.js.map +1 -0
- package/dist/api/effect/helpers.d.ts +300 -0
- package/dist/api/effect/helpers.d.ts.map +1 -0
- package/dist/api/effect/helpers.js +156 -0
- package/dist/api/effect/helpers.js.map +1 -0
- package/dist/api/effect/hierarchy.d.ts +26 -0
- package/dist/api/effect/hierarchy.d.ts.map +1 -0
- package/dist/api/effect/hierarchy.js +26 -0
- package/dist/api/effect/hierarchy.js.map +1 -0
- package/dist/api/effect/instance.d.ts +46 -0
- package/dist/api/effect/instance.d.ts.map +1 -0
- package/dist/api/effect/instance.js +8 -0
- package/dist/api/effect/instance.js.map +1 -0
- package/dist/api/effect/invites.d.ts +49 -0
- package/dist/api/effect/invites.d.ts.map +1 -0
- package/dist/api/effect/invites.js +2 -0
- package/dist/api/effect/invites.js.map +1 -0
- package/dist/api/effect/logging.d.ts +37 -0
- package/dist/api/effect/logging.d.ts.map +1 -0
- package/dist/api/effect/logging.js +2 -0
- package/dist/api/effect/logging.js.map +1 -0
- package/dist/api/effect/members.d.ts +433 -0
- package/dist/api/effect/members.d.ts.map +1 -0
- package/dist/api/effect/members.js +2 -0
- package/dist/api/effect/members.js.map +1 -0
- package/dist/api/effect/messages.d.ts +877 -0
- package/dist/api/effect/messages.d.ts.map +1 -0
- package/dist/api/effect/messages.js +2 -0
- package/dist/api/effect/messages.js.map +1 -0
- package/dist/api/effect/oauth.d.ts +148 -0
- package/dist/api/effect/oauth.d.ts.map +1 -0
- package/dist/api/effect/oauth.js +51 -0
- package/dist/api/effect/oauth.js.map +1 -0
- package/dist/api/effect/permissions.d.ts +41 -0
- package/dist/api/effect/permissions.d.ts.map +1 -0
- package/dist/api/effect/permissions.js +2 -0
- package/dist/api/effect/permissions.js.map +1 -0
- package/dist/api/effect/presence.d.ts +83 -0
- package/dist/api/effect/presence.d.ts.map +1 -0
- package/dist/api/effect/presence.js +2 -0
- package/dist/api/effect/presence.js.map +1 -0
- package/dist/api/effect/rest.d.ts +27 -0
- package/dist/api/effect/rest.d.ts.map +1 -0
- package/dist/api/effect/rest.js +2 -0
- package/dist/api/effect/rest.js.map +1 -0
- package/dist/api/effect/roles.d.ts +104 -0
- package/dist/api/effect/roles.d.ts.map +1 -0
- package/dist/api/effect/roles.js +2 -0
- package/dist/api/effect/roles.js.map +1 -0
- package/dist/api/effect/service.d.ts +76 -0
- package/dist/api/effect/service.d.ts.map +1 -0
- package/dist/api/effect/service.js +79 -0
- package/dist/api/effect/service.js.map +1 -0
- package/dist/api/effect/stickers.d.ts +81 -0
- package/dist/api/effect/stickers.d.ts.map +1 -0
- package/dist/api/effect/stickers.js +2 -0
- package/dist/api/effect/stickers.js.map +1 -0
- package/dist/api/effect/supervisor.d.ts +56 -0
- package/dist/api/effect/supervisor.d.ts.map +1 -0
- package/dist/api/effect/supervisor.js +58 -0
- package/dist/api/effect/supervisor.js.map +1 -0
- package/dist/api/effect/threads.d.ts +154 -0
- package/dist/api/effect/threads.d.ts.map +1 -0
- package/dist/api/effect/threads.js +2 -0
- package/dist/api/effect/threads.js.map +1 -0
- package/dist/api/effect/users.d.ts +62 -0
- package/dist/api/effect/users.d.ts.map +1 -0
- package/dist/api/effect/users.js +2 -0
- package/dist/api/effect/users.js.map +1 -0
- package/dist/api/effect/webhook-client.d.ts +140 -0
- package/dist/api/effect/webhook-client.d.ts.map +1 -0
- package/dist/api/effect/webhook-client.js +50 -0
- package/dist/api/effect/webhook-client.js.map +1 -0
- package/dist/api/effect/webhooks.d.ts +54 -0
- package/dist/api/effect/webhooks.d.ts.map +1 -0
- package/dist/api/effect/webhooks.js +2 -0
- package/dist/api/effect/webhooks.js.map +1 -0
- package/dist/api-errors.d.ts +609 -0
- package/dist/api-errors.d.ts.map +1 -0
- package/dist/api-errors.js +589 -0
- package/dist/api-errors.js.map +1 -0
- package/dist/application.d.ts +85 -0
- package/dist/application.d.ts.map +1 -0
- package/dist/application.js +44 -0
- package/dist/application.js.map +1 -0
- package/dist/assets.d.ts +197 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.js +419 -0
- package/dist/assets.js.map +1 -0
- package/dist/attachments.d.ts +400 -0
- package/dist/attachments.d.ts.map +1 -0
- package/dist/attachments.js +88 -0
- package/dist/attachments.js.map +1 -0
- package/dist/audit-logs.d.ts +292 -0
- package/dist/audit-logs.d.ts.map +1 -0
- package/dist/audit-logs.js +46 -0
- package/dist/audit-logs.js.map +1 -0
- package/dist/bot-runner.d.ts +69 -0
- package/dist/bot-runner.d.ts.map +1 -0
- package/dist/bot-runner.js +41 -0
- package/dist/bot-runner.js.map +1 -0
- package/dist/builders.d.ts +153 -0
- package/dist/builders.d.ts.map +1 -0
- package/dist/builders.js +326 -0
- package/dist/builders.js.map +1 -0
- package/dist/cache.d.ts +187 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +2 -0
- package/dist/cache.js.map +1 -0
- package/dist/channels.d.ts +903 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +125 -0
- package/dist/channels.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +65 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +645 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -0
- package/dist/collectors.d.ts +205 -0
- package/dist/collectors.d.ts.map +1 -0
- package/dist/collectors.js +71 -0
- package/dist/collectors.js.map +1 -0
- package/dist/colors.d.ts +55 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +40 -0
- package/dist/colors.js.map +1 -0
- package/dist/command-arguments.d.ts +353 -0
- package/dist/command-arguments.d.ts.map +1 -0
- package/dist/command-arguments.js +2 -0
- package/dist/command-arguments.js.map +1 -0
- package/dist/command-help.d.ts +54 -0
- package/dist/command-help.d.ts.map +1 -0
- package/dist/command-help.js +2 -0
- package/dist/command-help.js.map +1 -0
- package/dist/commands.d.ts +328 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +62 -0
- package/dist/commands.js.map +1 -0
- package/dist/counts.d.ts +124 -0
- package/dist/counts.d.ts.map +1 -0
- package/dist/counts.js +52 -0
- package/dist/counts.js.map +1 -0
- package/dist/default-commands.d.ts +400 -0
- package/dist/default-commands.d.ts.map +1 -0
- package/dist/default-commands.js +488 -0
- package/dist/default-commands.js.map +1 -0
- package/dist/default-supervisor.d.ts +111 -0
- package/dist/default-supervisor.d.ts.map +1 -0
- package/dist/default-supervisor.js +277 -0
- package/dist/default-supervisor.js.map +1 -0
- package/dist/discovery.d.ts +223 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +18 -0
- package/dist/discovery.js.map +1 -0
- package/dist/effect-testing.d.ts +388 -0
- package/dist/effect-testing.d.ts.map +1 -0
- package/dist/effect-testing.js +261 -0
- package/dist/effect-testing.js.map +1 -0
- package/dist/effect.d.ts +220 -0
- package/dist/effect.d.ts.map +1 -0
- package/dist/effect.js +101 -0
- package/dist/effect.js.map +1 -0
- package/dist/embeds.d.ts +243 -0
- package/dist/embeds.d.ts.map +1 -0
- package/dist/embeds.js +2 -0
- package/dist/embeds.js.map +1 -0
- package/dist/error-tools.d.ts +101 -0
- package/dist/error-tools.d.ts.map +1 -0
- package/dist/error-tools.js +125 -0
- package/dist/error-tools.js.map +1 -0
- package/dist/errors.d.ts +386 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +440 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +798 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +2 -0
- package/dist/events.js.map +1 -0
- package/dist/expressions.d.ts +188 -0
- package/dist/expressions.d.ts.map +1 -0
- package/dist/expressions.js +2 -0
- package/dist/expressions.js.map +1 -0
- package/dist/failures.d.ts +53 -0
- package/dist/failures.d.ts.map +1 -0
- package/dist/failures.js +2 -0
- package/dist/failures.js.map +1 -0
- package/dist/gateway.d.ts +48 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +60 -0
- package/dist/gateway.js.map +1 -0
- package/dist/guilds.d.ts +923 -0
- package/dist/guilds.d.ts.map +1 -0
- package/dist/guilds.js +204 -0
- package/dist/guilds.js.map +1 -0
- package/dist/helpers.d.ts +423 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +434 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +228 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +109 -0
- package/dist/index.js.map +1 -0
- package/dist/input-validation.d.ts +51 -0
- package/dist/input-validation.d.ts.map +1 -0
- package/dist/input-validation.js +34 -0
- package/dist/input-validation.js.map +1 -0
- package/dist/instance.d.ts +101 -0
- package/dist/instance.d.ts.map +1 -0
- package/dist/instance.js +2 -0
- package/dist/instance.js.map +1 -0
- package/dist/internal/agents-section.d.ts +22 -0
- package/dist/internal/agents-section.d.ts.map +1 -0
- package/dist/internal/agents-section.js +101 -0
- package/dist/internal/agents-section.js.map +1 -0
- package/dist/internal/application.d.ts +16 -0
- package/dist/internal/application.d.ts.map +1 -0
- package/dist/internal/application.js +33 -0
- package/dist/internal/application.js.map +1 -0
- package/dist/internal/attachment-refresh.d.ts +18 -0
- package/dist/internal/attachment-refresh.d.ts.map +1 -0
- package/dist/internal/attachment-refresh.js +39 -0
- package/dist/internal/attachment-refresh.js.map +1 -0
- package/dist/internal/attachments.d.ts +45 -0
- package/dist/internal/attachments.d.ts.map +1 -0
- package/dist/internal/attachments.js +230 -0
- package/dist/internal/attachments.js.map +1 -0
- package/dist/internal/audit-logs.d.ts +13 -0
- package/dist/internal/audit-logs.d.ts.map +1 -0
- package/dist/internal/audit-logs.js +295 -0
- package/dist/internal/audit-logs.js.map +1 -0
- package/dist/internal/audit.d.ts +12 -0
- package/dist/internal/audit.d.ts.map +1 -0
- package/dist/internal/audit.js +22 -0
- package/dist/internal/audit.js.map +1 -0
- package/dist/internal/binding/default-adapters.d.ts +22 -0
- package/dist/internal/binding/default-adapters.d.ts.map +1 -0
- package/dist/internal/binding/default-adapters.js +304 -0
- package/dist/internal/binding/default-adapters.js.map +1 -0
- package/dist/internal/binding/default.d.ts +45 -0
- package/dist/internal/binding/default.d.ts.map +1 -0
- package/dist/internal/binding/default.js +86 -0
- package/dist/internal/binding/default.js.map +1 -0
- package/dist/internal/binding/execute.d.ts +51 -0
- package/dist/internal/binding/execute.d.ts.map +1 -0
- package/dist/internal/binding/execute.js +123 -0
- package/dist/internal/binding/execute.js.map +1 -0
- package/dist/internal/binding/native-adapters.d.ts +23 -0
- package/dist/internal/binding/native-adapters.d.ts.map +1 -0
- package/dist/internal/binding/native-adapters.js +90 -0
- package/dist/internal/binding/native-adapters.js.map +1 -0
- package/dist/internal/binding/native.d.ts +41 -0
- package/dist/internal/binding/native.d.ts.map +1 -0
- package/dist/internal/binding/native.js +34 -0
- package/dist/internal/binding/native.js.map +1 -0
- package/dist/internal/binding/operations.d.ts +361 -0
- package/dist/internal/binding/operations.d.ts.map +1 -0
- package/dist/internal/binding/operations.js +272 -0
- package/dist/internal/binding/operations.js.map +1 -0
- package/dist/internal/bot-runner.d.ts +65 -0
- package/dist/internal/bot-runner.d.ts.map +1 -0
- package/dist/internal/bot-runner.js +363 -0
- package/dist/internal/bot-runner.js.map +1 -0
- package/dist/internal/cache-changes.d.ts +43 -0
- package/dist/internal/cache-changes.d.ts.map +1 -0
- package/dist/internal/cache-changes.js +320 -0
- package/dist/internal/cache-changes.js.map +1 -0
- package/dist/internal/cache.d.ts +57 -0
- package/dist/internal/cache.d.ts.map +1 -0
- package/dist/internal/cache.js +318 -0
- package/dist/internal/cache.js.map +1 -0
- package/dist/internal/calls.d.ts +16 -0
- package/dist/internal/calls.d.ts.map +1 -0
- package/dist/internal/calls.js +108 -0
- package/dist/internal/calls.js.map +1 -0
- package/dist/internal/channel-cache.d.ts +69 -0
- package/dist/internal/channel-cache.d.ts.map +1 -0
- package/dist/internal/channel-cache.js +413 -0
- package/dist/internal/channel-cache.js.map +1 -0
- package/dist/internal/channel-decode.d.ts +44 -0
- package/dist/internal/channel-decode.d.ts.map +1 -0
- package/dist/internal/channel-decode.js +377 -0
- package/dist/internal/channel-decode.js.map +1 -0
- package/dist/internal/channels.d.ts +60 -0
- package/dist/internal/channels.d.ts.map +1 -0
- package/dist/internal/channels.js +605 -0
- package/dist/internal/channels.js.map +1 -0
- package/dist/internal/client/backoff.d.ts +42 -0
- package/dist/internal/client/backoff.d.ts.map +1 -0
- package/dist/internal/client/backoff.js +36 -0
- package/dist/internal/client/backoff.js.map +1 -0
- package/dist/internal/client/configuration-fields.d.ts +14 -0
- package/dist/internal/client/configuration-fields.d.ts.map +1 -0
- package/dist/internal/client/configuration-fields.js +11 -0
- package/dist/internal/client/configuration-fields.js.map +1 -0
- package/dist/internal/client/drain.d.ts +33 -0
- package/dist/internal/client/drain.d.ts.map +1 -0
- package/dist/internal/client/drain.js +109 -0
- package/dist/internal/client/drain.js.map +1 -0
- package/dist/internal/client/intake.d.ts +27 -0
- package/dist/internal/client/intake.d.ts.map +1 -0
- package/dist/internal/client/intake.js +198 -0
- package/dist/internal/client/intake.js.map +1 -0
- package/dist/internal/client/lifetime.d.ts +35 -0
- package/dist/internal/client/lifetime.d.ts.map +1 -0
- package/dist/internal/client/lifetime.js +109 -0
- package/dist/internal/client/lifetime.js.map +1 -0
- package/dist/internal/client/shard-loop.d.ts +93 -0
- package/dist/internal/client/shard-loop.d.ts.map +1 -0
- package/dist/internal/client/shard-loop.js +452 -0
- package/dist/internal/client/shard-loop.js.map +1 -0
- package/dist/internal/client-registry.d.ts +26 -0
- package/dist/internal/client-registry.d.ts.map +1 -0
- package/dist/internal/client-registry.js +11 -0
- package/dist/internal/client-registry.js.map +1 -0
- package/dist/internal/client.d.ts +189 -0
- package/dist/internal/client.d.ts.map +1 -0
- package/dist/internal/client.js +1935 -0
- package/dist/internal/client.js.map +1 -0
- package/dist/internal/clock.d.ts +9 -0
- package/dist/internal/clock.d.ts.map +1 -0
- package/dist/internal/clock.js +5 -0
- package/dist/internal/clock.js.map +1 -0
- package/dist/internal/code-catalogue.d.ts +712 -0
- package/dist/internal/code-catalogue.d.ts.map +1 -0
- package/dist/internal/code-catalogue.js +655 -0
- package/dist/internal/code-catalogue.js.map +1 -0
- package/dist/internal/collector.d.ts +34 -0
- package/dist/internal/collector.d.ts.map +1 -0
- package/dist/internal/collector.js +400 -0
- package/dist/internal/collector.js.map +1 -0
- package/dist/internal/command-arguments.d.ts +29 -0
- package/dist/internal/command-arguments.d.ts.map +1 -0
- package/dist/internal/command-arguments.js +484 -0
- package/dist/internal/command-arguments.js.map +1 -0
- package/dist/internal/command-guards.d.ts +57 -0
- package/dist/internal/command-guards.d.ts.map +1 -0
- package/dist/internal/command-guards.js +81 -0
- package/dist/internal/command-guards.js.map +1 -0
- package/dist/internal/command-help.d.ts +15 -0
- package/dist/internal/command-help.d.ts.map +1 -0
- package/dist/internal/command-help.js +121 -0
- package/dist/internal/command-help.js.map +1 -0
- package/dist/internal/commands.d.ts +212 -0
- package/dist/internal/commands.d.ts.map +1 -0
- package/dist/internal/commands.js +1004 -0
- package/dist/internal/commands.js.map +1 -0
- package/dist/internal/configuration.d.ts +86 -0
- package/dist/internal/configuration.d.ts.map +1 -0
- package/dist/internal/configuration.js +401 -0
- package/dist/internal/configuration.js.map +1 -0
- package/dist/internal/counts.d.ts +33 -0
- package/dist/internal/counts.d.ts.map +1 -0
- package/dist/internal/counts.js +348 -0
- package/dist/internal/counts.js.map +1 -0
- package/dist/internal/decode/primitives.d.ts +30 -0
- package/dist/internal/decode/primitives.d.ts.map +1 -0
- package/dist/internal/decode/primitives.js +56 -0
- package/dist/internal/decode/primitives.js.map +1 -0
- package/dist/internal/decode/timestamp.d.ts +13 -0
- package/dist/internal/decode/timestamp.d.ts.map +1 -0
- package/dist/internal/decode/timestamp.js +27 -0
- package/dist/internal/decode/timestamp.js.map +1 -0
- package/dist/internal/decode/trace.d.ts +11 -0
- package/dist/internal/decode/trace.d.ts.map +1 -0
- package/dist/internal/decode/trace.js +69 -0
- package/dist/internal/decode/trace.js.map +1 -0
- package/dist/internal/defects.d.ts +48 -0
- package/dist/internal/defects.d.ts.map +1 -0
- package/dist/internal/defects.js +100 -0
- package/dist/internal/defects.js.map +1 -0
- package/dist/internal/effect-failures.d.ts +12 -0
- package/dist/internal/effect-failures.d.ts.map +1 -0
- package/dist/internal/effect-failures.js +45 -0
- package/dist/internal/effect-failures.js.map +1 -0
- package/dist/internal/embeds.d.ts +12 -0
- package/dist/internal/embeds.d.ts.map +1 -0
- package/dist/internal/embeds.js +308 -0
- package/dist/internal/embeds.js.map +1 -0
- package/dist/internal/events.d.ts +156 -0
- package/dist/internal/events.d.ts.map +1 -0
- package/dist/internal/events.js +1071 -0
- package/dist/internal/events.js.map +1 -0
- package/dist/internal/expiry-queue.d.ts +42 -0
- package/dist/internal/expiry-queue.d.ts.map +1 -0
- package/dist/internal/expiry-queue.js +138 -0
- package/dist/internal/expiry-queue.js.map +1 -0
- package/dist/internal/expressions.d.ts +35 -0
- package/dist/internal/expressions.d.ts.map +1 -0
- package/dist/internal/expressions.js +311 -0
- package/dist/internal/expressions.js.map +1 -0
- package/dist/internal/failures.d.ts +107 -0
- package/dist/internal/failures.d.ts.map +1 -0
- package/dist/internal/failures.js +416 -0
- package/dist/internal/failures.js.map +1 -0
- package/dist/internal/field-text.d.ts +10 -0
- package/dist/internal/field-text.d.ts.map +1 -0
- package/dist/internal/field-text.js +37 -0
- package/dist/internal/field-text.js.map +1 -0
- package/dist/internal/gateway/commands.d.ts +92 -0
- package/dist/internal/gateway/commands.d.ts.map +1 -0
- package/dist/internal/gateway/commands.js +223 -0
- package/dist/internal/gateway/commands.js.map +1 -0
- package/dist/internal/gateway/dispatch-table.d.ts +42 -0
- package/dist/internal/gateway/dispatch-table.d.ts.map +1 -0
- package/dist/internal/gateway/dispatch-table.js +288 -0
- package/dist/internal/gateway/dispatch-table.js.map +1 -0
- package/dist/internal/gateway/event-dispatches.d.ts +97 -0
- package/dist/internal/gateway/event-dispatches.d.ts.map +1 -0
- package/dist/internal/gateway/event-dispatches.js +172 -0
- package/dist/internal/gateway/event-dispatches.js.map +1 -0
- package/dist/internal/gateway/frames.d.ts +45 -0
- package/dist/internal/gateway/frames.d.ts.map +1 -0
- package/dist/internal/gateway/frames.js +121 -0
- package/dist/internal/gateway/frames.js.map +1 -0
- package/dist/internal/gateway/options.d.ts +24 -0
- package/dist/internal/gateway/options.d.ts.map +1 -0
- package/dist/internal/gateway/options.js +103 -0
- package/dist/internal/gateway/options.js.map +1 -0
- package/dist/internal/gateway/session.d.ts +104 -0
- package/dist/internal/gateway/session.d.ts.map +1 -0
- package/dist/internal/gateway/session.js +420 -0
- package/dist/internal/gateway/session.js.map +1 -0
- package/dist/internal/gateway-requests.d.ts +10 -0
- package/dist/internal/gateway-requests.d.ts.map +1 -0
- package/dist/internal/gateway-requests.js +26 -0
- package/dist/internal/gateway-requests.js.map +1 -0
- package/dist/internal/gateway.d.ts +19 -0
- package/dist/internal/gateway.d.ts.map +1 -0
- package/dist/internal/gateway.js +11 -0
- package/dist/internal/gateway.js.map +1 -0
- package/dist/internal/guild-cache.d.ts +69 -0
- package/dist/internal/guild-cache.d.ts.map +1 -0
- package/dist/internal/guild-cache.js +402 -0
- package/dist/internal/guild-cache.js.map +1 -0
- package/dist/internal/guild-discovery.d.ts +15 -0
- package/dist/internal/guild-discovery.d.ts.map +1 -0
- package/dist/internal/guild-discovery.js +258 -0
- package/dist/internal/guild-discovery.js.map +1 -0
- package/dist/internal/guild-lifecycle.d.ts +18 -0
- package/dist/internal/guild-lifecycle.d.ts.map +1 -0
- package/dist/internal/guild-lifecycle.js +119 -0
- package/dist/internal/guild-lifecycle.js.map +1 -0
- package/dist/internal/guild-settings.d.ts +11 -0
- package/dist/internal/guild-settings.d.ts.map +1 -0
- package/dist/internal/guild-settings.js +150 -0
- package/dist/internal/guild-settings.js.map +1 -0
- package/dist/internal/guilds.d.ts +94 -0
- package/dist/internal/guilds.d.ts.map +1 -0
- package/dist/internal/guilds.js +785 -0
- package/dist/internal/guilds.js.map +1 -0
- package/dist/internal/init-command.d.ts +54 -0
- package/dist/internal/init-command.d.ts.map +1 -0
- package/dist/internal/init-command.js +248 -0
- package/dist/internal/init-command.js.map +1 -0
- package/dist/internal/instance.d.ts +69 -0
- package/dist/internal/instance.d.ts.map +1 -0
- package/dist/internal/instance.js +455 -0
- package/dist/internal/instance.js.map +1 -0
- package/dist/internal/invalid-callback-return.d.ts +3 -0
- package/dist/internal/invalid-callback-return.d.ts.map +1 -0
- package/dist/internal/invalid-callback-return.js +26 -0
- package/dist/internal/invalid-callback-return.js.map +1 -0
- package/dist/internal/invites.d.ts +19 -0
- package/dist/internal/invites.d.ts.map +1 -0
- package/dist/internal/invites.js +182 -0
- package/dist/internal/invites.js.map +1 -0
- package/dist/internal/logging.d.ts +129 -0
- package/dist/internal/logging.d.ts.map +1 -0
- package/dist/internal/logging.js +868 -0
- package/dist/internal/logging.js.map +1 -0
- package/dist/internal/logical-scheduler.d.ts +27 -0
- package/dist/internal/logical-scheduler.d.ts.map +1 -0
- package/dist/internal/logical-scheduler.js +102 -0
- package/dist/internal/logical-scheduler.js.map +1 -0
- package/dist/internal/masking.d.ts +13 -0
- package/dist/internal/masking.d.ts.map +1 -0
- package/dist/internal/masking.js +235 -0
- package/dist/internal/masking.js.map +1 -0
- package/dist/internal/member-chunks.d.ts +96 -0
- package/dist/internal/member-chunks.d.ts.map +1 -0
- package/dist/internal/member-chunks.js +557 -0
- package/dist/internal/member-chunks.js.map +1 -0
- package/dist/internal/member-search-workflow.d.ts +19 -0
- package/dist/internal/member-search-workflow.d.ts.map +1 -0
- package/dist/internal/member-search-workflow.js +143 -0
- package/dist/internal/member-search-workflow.js.map +1 -0
- package/dist/internal/member-search.d.ts +20 -0
- package/dist/internal/member-search.d.ts.map +1 -0
- package/dist/internal/member-search.js +201 -0
- package/dist/internal/member-search.js.map +1 -0
- package/dist/internal/message-cleanup.d.ts +9 -0
- package/dist/internal/message-cleanup.d.ts.map +1 -0
- package/dist/internal/message-cleanup.js +368 -0
- package/dist/internal/message-cleanup.js.map +1 -0
- package/dist/internal/message-fields.d.ts +9 -0
- package/dist/internal/message-fields.d.ts.map +1 -0
- package/dist/internal/message-fields.js +55 -0
- package/dist/internal/message-fields.js.map +1 -0
- package/dist/internal/message-search-workflow.d.ts +14 -0
- package/dist/internal/message-search-workflow.d.ts.map +1 -0
- package/dist/internal/message-search-workflow.js +101 -0
- package/dist/internal/message-search-workflow.js.map +1 -0
- package/dist/internal/message-search.d.ts +19 -0
- package/dist/internal/message-search.d.ts.map +1 -0
- package/dist/internal/message-search.js +317 -0
- package/dist/internal/message-search.js.map +1 -0
- package/dist/internal/message.d.ts +34 -0
- package/dist/internal/message.d.ts.map +1 -0
- package/dist/internal/message.js +723 -0
- package/dist/internal/message.js.map +1 -0
- package/dist/internal/metrics.d.ts +16 -0
- package/dist/internal/metrics.d.ts.map +1 -0
- package/dist/internal/metrics.js +49 -0
- package/dist/internal/metrics.js.map +1 -0
- package/dist/internal/moderation.d.ts +20 -0
- package/dist/internal/moderation.d.ts.map +1 -0
- package/dist/internal/moderation.js +219 -0
- package/dist/internal/moderation.js.map +1 -0
- package/dist/internal/multipart.d.ts +10 -0
- package/dist/internal/multipart.d.ts.map +1 -0
- package/dist/internal/multipart.js +156 -0
- package/dist/internal/multipart.js.map +1 -0
- package/dist/internal/node-version.d.ts +10 -0
- package/dist/internal/node-version.d.ts.map +1 -0
- package/dist/internal/node-version.js +21 -0
- package/dist/internal/node-version.js.map +1 -0
- package/dist/internal/oauth.d.ts +29 -0
- package/dist/internal/oauth.d.ts.map +1 -0
- package/dist/internal/oauth.js +721 -0
- package/dist/internal/oauth.js.map +1 -0
- package/dist/internal/observer.d.ts +21 -0
- package/dist/internal/observer.d.ts.map +1 -0
- package/dist/internal/observer.js +48 -0
- package/dist/internal/observer.js.map +1 -0
- package/dist/internal/operation-signal.d.ts +9 -0
- package/dist/internal/operation-signal.d.ts.map +1 -0
- package/dist/internal/operation-signal.js +19 -0
- package/dist/internal/operation-signal.js.map +1 -0
- package/dist/internal/pagination.d.ts +67 -0
- package/dist/internal/pagination.d.ts.map +1 -0
- package/dist/internal/pagination.js +306 -0
- package/dist/internal/pagination.js.map +1 -0
- package/dist/internal/permission-requirements.d.ts +34 -0
- package/dist/internal/permission-requirements.d.ts.map +1 -0
- package/dist/internal/permission-requirements.js +204 -0
- package/dist/internal/permission-requirements.js.map +1 -0
- package/dist/internal/permissions.d.ts +28 -0
- package/dist/internal/permissions.d.ts.map +1 -0
- package/dist/internal/permissions.js +314 -0
- package/dist/internal/permissions.js.map +1 -0
- package/dist/internal/pins.d.ts +24 -0
- package/dist/internal/pins.d.ts.map +1 -0
- package/dist/internal/pins.js +83 -0
- package/dist/internal/pins.js.map +1 -0
- package/dist/internal/presence.d.ts +101 -0
- package/dist/internal/presence.d.ts.map +1 -0
- package/dist/internal/presence.js +581 -0
- package/dist/internal/presence.js.map +1 -0
- package/dist/internal/protocol/gateway.d.ts +116 -0
- package/dist/internal/protocol/gateway.d.ts.map +1 -0
- package/dist/internal/protocol/gateway.js +258 -0
- package/dist/internal/protocol/gateway.js.map +1 -0
- package/dist/internal/rate-limit-templates.d.ts +2 -0
- package/dist/internal/rate-limit-templates.d.ts.map +1 -0
- package/dist/internal/rate-limit-templates.js +132 -0
- package/dist/internal/rate-limit-templates.js.map +1 -0
- package/dist/internal/rate-limits.d.ts +32 -0
- package/dist/internal/rate-limits.d.ts.map +1 -0
- package/dist/internal/rate-limits.js +306 -0
- package/dist/internal/rate-limits.js.map +1 -0
- package/dist/internal/reaction-collector.d.ts +39 -0
- package/dist/internal/reaction-collector.d.ts.map +1 -0
- package/dist/internal/reaction-collector.js +441 -0
- package/dist/internal/reaction-collector.js.map +1 -0
- package/dist/internal/reaction-pages.d.ts +18 -0
- package/dist/internal/reaction-pages.d.ts.map +1 -0
- package/dist/internal/reaction-pages.js +213 -0
- package/dist/internal/reaction-pages.js.map +1 -0
- package/dist/internal/reactions.d.ts +30 -0
- package/dist/internal/reactions.d.ts.map +1 -0
- package/dist/internal/reactions.js +160 -0
- package/dist/internal/reactions.js.map +1 -0
- package/dist/internal/rejection-scope.d.ts +25 -0
- package/dist/internal/rejection-scope.d.ts.map +1 -0
- package/dist/internal/rejection-scope.js +103 -0
- package/dist/internal/rejection-scope.js.map +1 -0
- package/dist/internal/response-json.d.ts +12 -0
- package/dist/internal/response-json.d.ts.map +1 -0
- package/dist/internal/response-json.js +74 -0
- package/dist/internal/response-json.js.map +1 -0
- package/dist/internal/rest/admission.d.ts +77 -0
- package/dist/internal/rest/admission.d.ts.map +1 -0
- package/dist/internal/rest/admission.js +178 -0
- package/dist/internal/rest/admission.js.map +1 -0
- package/dist/internal/rest/attempt.d.ts +124 -0
- package/dist/internal/rest/attempt.d.ts.map +1 -0
- package/dist/internal/rest/attempt.js +410 -0
- package/dist/internal/rest/attempt.js.map +1 -0
- package/dist/internal/rest/classify.d.ts +93 -0
- package/dist/internal/rest/classify.d.ts.map +1 -0
- package/dist/internal/rest/classify.js +304 -0
- package/dist/internal/rest/classify.js.map +1 -0
- package/dist/internal/rest/download.d.ts +66 -0
- package/dist/internal/rest/download.d.ts.map +1 -0
- package/dist/internal/rest/download.js +552 -0
- package/dist/internal/rest/download.js.map +1 -0
- package/dist/internal/rest/options.d.ts +42 -0
- package/dist/internal/rest/options.d.ts.map +1 -0
- package/dist/internal/rest/options.js +99 -0
- package/dist/internal/rest/options.js.map +1 -0
- package/dist/internal/rest/owner.d.ts +154 -0
- package/dist/internal/rest/owner.d.ts.map +1 -0
- package/dist/internal/rest/owner.js +1292 -0
- package/dist/internal/rest/owner.js.map +1 -0
- package/dist/internal/rest/request.d.ts +31 -0
- package/dist/internal/rest/request.d.ts.map +1 -0
- package/dist/internal/rest/request.js +227 -0
- package/dist/internal/rest/request.js.map +1 -0
- package/dist/internal/rest.d.ts +10 -0
- package/dist/internal/rest.d.ts.map +1 -0
- package/dist/internal/rest.js +9 -0
- package/dist/internal/rest.js.map +1 -0
- package/dist/internal/retention-age.d.ts +11 -0
- package/dist/internal/retention-age.d.ts.map +1 -0
- package/dist/internal/retention-age.js +29 -0
- package/dist/internal/retention-age.js.map +1 -0
- package/dist/internal/role-hierarchy-workflow.d.ts +15 -0
- package/dist/internal/role-hierarchy-workflow.d.ts.map +1 -0
- package/dist/internal/role-hierarchy-workflow.js +122 -0
- package/dist/internal/role-hierarchy-workflow.js.map +1 -0
- package/dist/internal/role-hierarchy.d.ts +11 -0
- package/dist/internal/role-hierarchy.d.ts.map +1 -0
- package/dist/internal/role-hierarchy.js +87 -0
- package/dist/internal/role-hierarchy.js.map +1 -0
- package/dist/internal/scheduled-tasks.d.ts +46 -0
- package/dist/internal/scheduled-tasks.d.ts.map +1 -0
- package/dist/internal/scheduled-tasks.js +190 -0
- package/dist/internal/scheduled-tasks.js.map +1 -0
- package/dist/internal/sharding.d.ts +62 -0
- package/dist/internal/sharding.d.ts.map +1 -0
- package/dist/internal/sharding.js +205 -0
- package/dist/internal/sharding.js.map +1 -0
- package/dist/internal/starter-project.d.ts +27 -0
- package/dist/internal/starter-project.d.ts.map +1 -0
- package/dist/internal/starter-project.js +224 -0
- package/dist/internal/starter-project.js.map +1 -0
- package/dist/internal/suggest.d.ts +12 -0
- package/dist/internal/suggest.d.ts.map +1 -0
- package/dist/internal/suggest.js +51 -0
- package/dist/internal/suggest.js.map +1 -0
- package/dist/internal/supervisor.d.ts +95 -0
- package/dist/internal/supervisor.d.ts.map +1 -0
- package/dist/internal/supervisor.js +1829 -0
- package/dist/internal/supervisor.js.map +1 -0
- package/dist/internal/testing/discovery.d.ts +24 -0
- package/dist/internal/testing/discovery.d.ts.map +1 -0
- package/dist/internal/testing/discovery.js +22 -0
- package/dist/internal/testing/discovery.js.map +1 -0
- package/dist/internal/testing/errors.d.ts +43 -0
- package/dist/internal/testing/errors.d.ts.map +1 -0
- package/dist/internal/testing/errors.js +63 -0
- package/dist/internal/testing/errors.js.map +1 -0
- package/dist/internal/testing/fixtures.d.ts +477 -0
- package/dist/internal/testing/fixtures.d.ts.map +1 -0
- package/dist/internal/testing/fixtures.js +233 -0
- package/dist/internal/testing/fixtures.js.map +1 -0
- package/dist/internal/testing/gateway.d.ts +51 -0
- package/dist/internal/testing/gateway.d.ts.map +1 -0
- package/dist/internal/testing/gateway.js +265 -0
- package/dist/internal/testing/gateway.js.map +1 -0
- package/dist/internal/testing/harness.d.ts +60 -0
- package/dist/internal/testing/harness.d.ts.map +1 -0
- package/dist/internal/testing/harness.js +280 -0
- package/dist/internal/testing/harness.js.map +1 -0
- package/dist/internal/testing/http.d.ts +31 -0
- package/dist/internal/testing/http.d.ts.map +1 -0
- package/dist/internal/testing/http.js +347 -0
- package/dist/internal/testing/http.js.map +1 -0
- package/dist/internal/testing/types.d.ts +222 -0
- package/dist/internal/testing/types.d.ts.map +1 -0
- package/dist/internal/testing/types.js +2 -0
- package/dist/internal/testing/types.js.map +1 -0
- package/dist/internal/testing/wait.d.ts +16 -0
- package/dist/internal/testing/wait.d.ts.map +1 -0
- package/dist/internal/testing/wait.js +55 -0
- package/dist/internal/testing/wait.js.map +1 -0
- package/dist/internal/thread-events.d.ts +40 -0
- package/dist/internal/thread-events.d.ts.map +1 -0
- package/dist/internal/thread-events.js +121 -0
- package/dist/internal/thread-events.js.map +1 -0
- package/dist/internal/threads.d.ts +47 -0
- package/dist/internal/threads.d.ts.map +1 -0
- package/dist/internal/threads.js +587 -0
- package/dist/internal/threads.js.map +1 -0
- package/dist/internal/transfer-source.d.ts +29 -0
- package/dist/internal/transfer-source.d.ts.map +1 -0
- package/dist/internal/transfer-source.js +347 -0
- package/dist/internal/transfer-source.js.map +1 -0
- package/dist/internal/transport/http.d.ts +12 -0
- package/dist/internal/transport/http.d.ts.map +1 -0
- package/dist/internal/transport/http.js +44 -0
- package/dist/internal/transport/http.js.map +1 -0
- package/dist/internal/transport/index.d.ts +21 -0
- package/dist/internal/transport/index.d.ts.map +1 -0
- package/dist/internal/transport/index.js +15 -0
- package/dist/internal/transport/index.js.map +1 -0
- package/dist/internal/transport/socket.d.ts +51 -0
- package/dist/internal/transport/socket.d.ts.map +1 -0
- package/dist/internal/transport/socket.js +27 -0
- package/dist/internal/transport/socket.js.map +1 -0
- package/dist/internal/transport/user-agent.d.ts +7 -0
- package/dist/internal/transport/user-agent.d.ts.map +1 -0
- package/dist/internal/transport/user-agent.js +42 -0
- package/dist/internal/transport/user-agent.js.map +1 -0
- package/dist/internal/uploads.d.ts +23 -0
- package/dist/internal/uploads.d.ts.map +1 -0
- package/dist/internal/uploads.js +89 -0
- package/dist/internal/uploads.js.map +1 -0
- package/dist/internal/user-cache.d.ts +50 -0
- package/dist/internal/user-cache.d.ts.map +1 -0
- package/dist/internal/user-cache.js +273 -0
- package/dist/internal/user-cache.js.map +1 -0
- package/dist/internal/users.d.ts +41 -0
- package/dist/internal/users.d.ts.map +1 -0
- package/dist/internal/users.js +333 -0
- package/dist/internal/users.js.map +1 -0
- package/dist/internal/vanity-url.d.ts +11 -0
- package/dist/internal/vanity-url.d.ts.map +1 -0
- package/dist/internal/vanity-url.js +58 -0
- package/dist/internal/vanity-url.js.map +1 -0
- package/dist/internal/webhooks.d.ts +58 -0
- package/dist/internal/webhooks.d.ts.map +1 -0
- package/dist/internal/webhooks.js +490 -0
- package/dist/internal/webhooks.js.map +1 -0
- package/dist/invites.d.ts +86 -0
- package/dist/invites.d.ts.map +1 -0
- package/dist/invites.js +2 -0
- package/dist/invites.js.map +1 -0
- package/dist/logging.d.ts +228 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +2 -0
- package/dist/logging.js.map +1 -0
- package/dist/member-chunks.d.ts +145 -0
- package/dist/member-chunks.d.ts.map +1 -0
- package/dist/member-chunks.js +68 -0
- package/dist/member-chunks.js.map +1 -0
- package/dist/member-search.d.ts +140 -0
- package/dist/member-search.d.ts.map +1 -0
- package/dist/member-search.js +14 -0
- package/dist/member-search.js.map +1 -0
- package/dist/message-cleanup.d.ts +227 -0
- package/dist/message-cleanup.d.ts.map +1 -0
- package/dist/message-cleanup.js +101 -0
- package/dist/message-cleanup.js.map +1 -0
- package/dist/message-errors.d.ts +172 -0
- package/dist/message-errors.d.ts.map +1 -0
- package/dist/message-errors.js +173 -0
- package/dist/message-errors.js.map +1 -0
- package/dist/message-search.d.ts +201 -0
- package/dist/message-search.d.ts.map +1 -0
- package/dist/message-search.js +2 -0
- package/dist/message-search.js.map +1 -0
- package/dist/messages.d.ts +694 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +37 -0
- package/dist/messages.js.map +1 -0
- package/dist/native-commands.d.ts +451 -0
- package/dist/native-commands.d.ts.map +1 -0
- package/dist/native-commands.js +432 -0
- package/dist/native-commands.js.map +1 -0
- package/dist/native-supervisor.d.ts +125 -0
- package/dist/native-supervisor.d.ts.map +1 -0
- package/dist/native-supervisor.js +126 -0
- package/dist/native-supervisor.js.map +1 -0
- package/dist/oauth.d.ts +298 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +128 -0
- package/dist/oauth.js.map +1 -0
- package/dist/observer.d.ts +111 -0
- package/dist/observer.d.ts.map +1 -0
- package/dist/observer.js +2 -0
- package/dist/observer.js.map +1 -0
- package/dist/pagination.d.ts +117 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +61 -0
- package/dist/pagination.js.map +1 -0
- package/dist/permissions.d.ts +73 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +2 -0
- package/dist/permissions.js.map +1 -0
- package/dist/pins.d.ts +62 -0
- package/dist/pins.d.ts.map +1 -0
- package/dist/pins.js +2 -0
- package/dist/pins.js.map +1 -0
- package/dist/presence.d.ts +84 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +46 -0
- package/dist/presence.js.map +1 -0
- package/dist/reaction-pages.d.ts +99 -0
- package/dist/reaction-pages.d.ts.map +1 -0
- package/dist/reaction-pages.js +2 -0
- package/dist/reaction-pages.js.map +1 -0
- package/dist/reactions.d.ts +118 -0
- package/dist/reactions.d.ts.map +1 -0
- package/dist/reactions.js +2 -0
- package/dist/reactions.js.map +1 -0
- package/dist/rest.d.ts +260 -0
- package/dist/rest.d.ts.map +1 -0
- package/dist/rest.js +46 -0
- package/dist/rest.js.map +1 -0
- package/dist/role-hierarchy.d.ts +81 -0
- package/dist/role-hierarchy.d.ts.map +1 -0
- package/dist/role-hierarchy.js +53 -0
- package/dist/role-hierarchy.js.map +1 -0
- package/dist/sharding.d.ts +219 -0
- package/dist/sharding.d.ts.map +1 -0
- package/dist/sharding.js +86 -0
- package/dist/sharding.js.map +1 -0
- package/dist/supervisor.d.ts +392 -0
- package/dist/supervisor.d.ts.map +1 -0
- package/dist/supervisor.js +101 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/testing.d.ts +258 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +202 -0
- package/dist/testing.js.map +1 -0
- package/dist/text.d.ts +38 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +46 -0
- package/dist/text.js.map +1 -0
- package/dist/threads.d.ts +258 -0
- package/dist/threads.d.ts.map +1 -0
- package/dist/threads.js +2 -0
- package/dist/threads.js.map +1 -0
- package/dist/users.d.ts +204 -0
- package/dist/users.d.ts.map +1 -0
- package/dist/users.js +44 -0
- package/dist/users.js.map +1 -0
- package/dist/webhooks.d.ts +423 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +68 -0
- package/dist/webhooks.js.map +1 -0
- package/esm-only.cjs +3 -0
- package/examples/starter/bot-effect.ts +17 -0
- package/examples/starter/bot.js +13 -0
- package/examples/starter/bot.ts +13 -0
- package/package.json +82 -0
- package/src/api/default/application.ts +40 -0
- package/src/api/default/attachments.ts +106 -0
- package/src/api/default/audit-logs.ts +58 -0
- package/src/api/default/bot.ts +586 -0
- package/src/api/default/cache.ts +106 -0
- package/src/api/default/channels.ts +317 -0
- package/src/api/default/client.ts +829 -0
- package/src/api/default/collectors.ts +81 -0
- package/src/api/default/commands.ts +92 -0
- package/src/api/default/direct-messages.ts +143 -0
- package/src/api/default/discovery.ts +103 -0
- package/src/api/default/emojis.ts +125 -0
- package/src/api/default/events.ts +144 -0
- package/src/api/default/gateway.ts +67 -0
- package/src/api/default/guards.ts +173 -0
- package/src/api/default/guilds.ts +271 -0
- package/src/api/default/helpers.ts +97 -0
- package/src/api/default/instance.ts +49 -0
- package/src/api/default/invites.ts +73 -0
- package/src/api/default/logging.ts +37 -0
- package/src/api/default/members.ts +550 -0
- package/src/api/default/messages.ts +1053 -0
- package/src/api/default/oauth.ts +293 -0
- package/src/api/default/permissions.ts +47 -0
- package/src/api/default/presence.ts +88 -0
- package/src/api/default/rest.ts +30 -0
- package/src/api/default/results.ts +44 -0
- package/src/api/default/roles.ts +154 -0
- package/src/api/default/stickers.ts +129 -0
- package/src/api/default/supervisor.ts +53 -0
- package/src/api/default/threads.ts +233 -0
- package/src/api/default/users.ts +82 -0
- package/src/api/default/webhook-client.ts +266 -0
- package/src/api/default/webhooks.ts +89 -0
- package/src/api/effect/application.ts +29 -0
- package/src/api/effect/attachments.ts +100 -0
- package/src/api/effect/audit-logs.ts +50 -0
- package/src/api/effect/bot.ts +546 -0
- package/src/api/effect/cache.ts +110 -0
- package/src/api/effect/channels.ts +293 -0
- package/src/api/effect/client.ts +792 -0
- package/src/api/effect/collectors.ts +103 -0
- package/src/api/effect/commands.ts +87 -0
- package/src/api/effect/direct-messages.ts +119 -0
- package/src/api/effect/discovery.ts +87 -0
- package/src/api/effect/emojis.ts +108 -0
- package/src/api/effect/events.ts +92 -0
- package/src/api/effect/failures.ts +14 -0
- package/src/api/effect/gateway.ts +63 -0
- package/src/api/effect/guards.ts +194 -0
- package/src/api/effect/guilds.ts +247 -0
- package/src/api/effect/helpers.ts +359 -0
- package/src/api/effect/hierarchy.ts +26 -0
- package/src/api/effect/instance.ts +50 -0
- package/src/api/effect/invites.ts +59 -0
- package/src/api/effect/logging.ts +37 -0
- package/src/api/effect/members.ts +521 -0
- package/src/api/effect/messages.ts +1003 -0
- package/src/api/effect/oauth.ts +208 -0
- package/src/api/effect/permissions.ts +44 -0
- package/src/api/effect/presence.ts +83 -0
- package/src/api/effect/rest.ts +27 -0
- package/src/api/effect/roles.ts +136 -0
- package/src/api/effect/service.ts +104 -0
- package/src/api/effect/stickers.ts +112 -0
- package/src/api/effect/supervisor.ts +58 -0
- package/src/api/effect/threads.ts +221 -0
- package/src/api/effect/users.ts +66 -0
- package/src/api/effect/webhook-client.ts +206 -0
- package/src/api/effect/webhooks.ts +75 -0
- package/src/api-errors.ts +985 -0
- package/src/application.ts +103 -0
- package/src/assets.ts +731 -0
- package/src/attachments.ts +469 -0
- package/src/audit-logs.ts +355 -0
- package/src/bot-runner.ts +91 -0
- package/src/builders.ts +390 -0
- package/src/cache.ts +190 -0
- package/src/channels.ts +1051 -0
- package/src/cli.ts +60 -0
- package/src/client.ts +663 -0
- package/src/collectors.ts +248 -0
- package/src/colors.ts +91 -0
- package/src/command-arguments.ts +432 -0
- package/src/command-help.ts +55 -0
- package/src/commands.ts +403 -0
- package/src/counts.ts +160 -0
- package/src/default-commands.ts +1147 -0
- package/src/default-supervisor.ts +484 -0
- package/src/discovery.ts +241 -0
- package/src/effect-testing.ts +603 -0
- package/src/effect.ts +751 -0
- package/src/embeds.ts +253 -0
- package/src/error-tools.ts +191 -0
- package/src/errors.ts +849 -0
- package/src/events.ts +830 -0
- package/src/expressions.ts +198 -0
- package/src/failures.ts +55 -0
- package/src/gateway.ts +86 -0
- package/src/guilds.ts +1108 -0
- package/src/helpers.ts +836 -0
- package/src/index.ts +796 -0
- package/src/input-validation.ts +94 -0
- package/src/instance.ts +111 -0
- package/src/internal/agents-section.ts +114 -0
- package/src/internal/application.ts +51 -0
- package/src/internal/attachment-refresh.ts +57 -0
- package/src/internal/attachments.ts +313 -0
- package/src/internal/audit-logs.ts +336 -0
- package/src/internal/audit.ts +33 -0
- package/src/internal/binding/default-adapters.ts +482 -0
- package/src/internal/binding/default.ts +155 -0
- package/src/internal/binding/execute.ts +221 -0
- package/src/internal/binding/native-adapters.ts +199 -0
- package/src/internal/binding/native.ts +72 -0
- package/src/internal/binding/operations.ts +1171 -0
- package/src/internal/bot-runner.ts +480 -0
- package/src/internal/cache-changes.ts +363 -0
- package/src/internal/cache.ts +323 -0
- package/src/internal/calls.ts +119 -0
- package/src/internal/channel-cache.ts +435 -0
- package/src/internal/channel-decode.ts +399 -0
- package/src/internal/channels.ts +874 -0
- package/src/internal/client/backoff.ts +69 -0
- package/src/internal/client/configuration-fields.ts +18 -0
- package/src/internal/client/drain.ts +150 -0
- package/src/internal/client/intake.ts +228 -0
- package/src/internal/client/lifetime.ts +165 -0
- package/src/internal/client/shard-loop.ts +586 -0
- package/src/internal/client-registry.ts +35 -0
- package/src/internal/client.ts +2448 -0
- package/src/internal/clock.ts +11 -0
- package/src/internal/code-catalogue.ts +739 -0
- package/src/internal/collector.ts +452 -0
- package/src/internal/command-arguments.ts +585 -0
- package/src/internal/command-guards.ts +96 -0
- package/src/internal/command-help.ts +156 -0
- package/src/internal/commands.ts +1319 -0
- package/src/internal/configuration.ts +529 -0
- package/src/internal/counts.ts +471 -0
- package/src/internal/decode/primitives.ts +67 -0
- package/src/internal/decode/timestamp.ts +29 -0
- package/src/internal/decode/trace.ts +65 -0
- package/src/internal/defects.ts +115 -0
- package/src/internal/effect-failures.ts +65 -0
- package/src/internal/embeds.ts +355 -0
- package/src/internal/events.ts +1345 -0
- package/src/internal/expiry-queue.ts +148 -0
- package/src/internal/expressions.ts +415 -0
- package/src/internal/failures.ts +492 -0
- package/src/internal/field-text.ts +40 -0
- package/src/internal/gateway/commands.ts +328 -0
- package/src/internal/gateway/dispatch-table.ts +383 -0
- package/src/internal/gateway/event-dispatches.ts +201 -0
- package/src/internal/gateway/frames.ts +176 -0
- package/src/internal/gateway/options.ts +144 -0
- package/src/internal/gateway/session.ts +625 -0
- package/src/internal/gateway-requests.ts +26 -0
- package/src/internal/gateway.ts +22 -0
- package/src/internal/guild-cache.ts +424 -0
- package/src/internal/guild-discovery.ts +332 -0
- package/src/internal/guild-lifecycle.ts +128 -0
- package/src/internal/guild-settings.ts +209 -0
- package/src/internal/guilds.ts +949 -0
- package/src/internal/init-command.ts +305 -0
- package/src/internal/instance.ts +645 -0
- package/src/internal/invalid-callback-return.ts +28 -0
- package/src/internal/invites.ts +234 -0
- package/src/internal/logging.ts +1007 -0
- package/src/internal/logical-scheduler.ts +139 -0
- package/src/internal/masking.ts +224 -0
- package/src/internal/member-chunks.ts +649 -0
- package/src/internal/member-search-workflow.ts +237 -0
- package/src/internal/member-search.ts +272 -0
- package/src/internal/message-cleanup.ts +515 -0
- package/src/internal/message-fields.ts +71 -0
- package/src/internal/message-search-workflow.ts +166 -0
- package/src/internal/message-search.ts +476 -0
- package/src/internal/message.ts +879 -0
- package/src/internal/metrics.ts +55 -0
- package/src/internal/moderation.ts +288 -0
- package/src/internal/multipart.ts +171 -0
- package/src/internal/node-version.ts +22 -0
- package/src/internal/oauth.ts +1146 -0
- package/src/internal/observer.ts +62 -0
- package/src/internal/operation-signal.ts +26 -0
- package/src/internal/pagination.ts +494 -0
- package/src/internal/permission-requirements.ts +359 -0
- package/src/internal/permissions.ts +417 -0
- package/src/internal/pins.ts +115 -0
- package/src/internal/presence.ts +745 -0
- package/src/internal/protocol/gateway.ts +299 -0
- package/src/internal/rate-limit-templates.ts +138 -0
- package/src/internal/rate-limits.ts +346 -0
- package/src/internal/reaction-collector.ts +499 -0
- package/src/internal/reaction-pages.ts +260 -0
- package/src/internal/reactions.ts +174 -0
- package/src/internal/rejection-scope.ts +119 -0
- package/src/internal/response-json.ts +76 -0
- package/src/internal/rest/admission.ts +210 -0
- package/src/internal/rest/attempt.ts +617 -0
- package/src/internal/rest/classify.ts +391 -0
- package/src/internal/rest/download.ts +658 -0
- package/src/internal/rest/options.ts +145 -0
- package/src/internal/rest/owner.ts +1828 -0
- package/src/internal/rest/request.ts +289 -0
- package/src/internal/rest.ts +9 -0
- package/src/internal/retention-age.ts +33 -0
- package/src/internal/role-hierarchy-workflow.ts +150 -0
- package/src/internal/role-hierarchy.ts +93 -0
- package/src/internal/scheduled-tasks.ts +217 -0
- package/src/internal/sharding.ts +270 -0
- package/src/internal/starter-project.ts +251 -0
- package/src/internal/suggest.ts +50 -0
- package/src/internal/supervisor.ts +2253 -0
- package/src/internal/testing/discovery.ts +23 -0
- package/src/internal/testing/errors.ts +67 -0
- package/src/internal/testing/fixtures.ts +714 -0
- package/src/internal/testing/gateway.ts +305 -0
- package/src/internal/testing/harness.ts +328 -0
- package/src/internal/testing/http.ts +395 -0
- package/src/internal/testing/types.ts +240 -0
- package/src/internal/testing/wait.ts +63 -0
- package/src/internal/thread-events.ts +128 -0
- package/src/internal/threads.ts +718 -0
- package/src/internal/transfer-source.ts +359 -0
- package/src/internal/transport/http.ts +46 -0
- package/src/internal/transport/index.ts +23 -0
- package/src/internal/transport/socket.ts +71 -0
- package/src/internal/transport/user-agent.ts +46 -0
- package/src/internal/uploads.ts +111 -0
- package/src/internal/user-cache.ts +294 -0
- package/src/internal/users.ts +402 -0
- package/src/internal/vanity-url.ts +80 -0
- package/src/internal/webhooks.ts +690 -0
- package/src/invites.ts +87 -0
- package/src/logging.ts +247 -0
- package/src/member-chunks.ts +195 -0
- package/src/member-search.ts +152 -0
- package/src/message-cleanup.ts +308 -0
- package/src/message-errors.ts +245 -0
- package/src/message-search.ts +213 -0
- package/src/messages.ts +768 -0
- package/src/native-commands.ts +1249 -0
- package/src/native-supervisor.ts +345 -0
- package/src/oauth.ts +413 -0
- package/src/observer.ts +118 -0
- package/src/pagination.ts +172 -0
- package/src/permissions.ts +74 -0
- package/src/pins.ts +65 -0
- package/src/presence.ts +124 -0
- package/src/reaction-pages.ts +106 -0
- package/src/reactions.ts +126 -0
- package/src/rest.ts +282 -0
- package/src/role-hierarchy.ts +127 -0
- package/src/sharding.ts +272 -0
- package/src/supervisor.ts +460 -0
- package/src/testing.ts +424 -0
- package/src/text.ts +76 -0
- package/src/threads.ts +274 -0
- package/src/users.ts +237 -0
- package/src/webhooks.ts +512 -0
|
@@ -0,0 +1,1345 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event intake: Per-subscription scheduling, bounded pending delivery, overflow policies and event waits.
|
|
3
|
+
* Invariant: Gateway callbacks never await consumer work, overflow ends only the affected subscription, and shutdown discards
|
|
4
|
+
* pending delivery with one record per subscription that had waiting events. Default callback promises stay application-owned
|
|
5
|
+
* while native cleanup is cooperative and awaited, and a native handler's shutdown request runs in the client scope so the
|
|
6
|
+
* handler never joins itself. Each admitted event keeps the shard and
|
|
7
|
+
* received frame size it arrived with for its handler context, without changing queue accounting. Middleware wraps on handler
|
|
8
|
+
* invocations only, with the list registered when an invocation starts, and every failure inside the chain is reported where it
|
|
9
|
+
* occurs, so middleware cannot hide a handler failure. A partitioned handler starts events in receive order per key and runs
|
|
10
|
+
* at most one invocation per key, selecting from its own bounded queue so queue limits still cover every waiting event.
|
|
11
|
+
* A draining shutdown seals the bus: New events and registrations are refused while running and queued handler work
|
|
12
|
+
* continues until the client stops the bus, which records how many refused events had a subscription. Implements [SDK contracts: Delivery, requests and caches](/docs/SDK-CONTRACTS.md#delivery-requests-and-caches)
|
|
13
|
+
*/
|
|
14
|
+
import * as Cause from "effect/Cause"
|
|
15
|
+
import * as Clock from "effect/Clock"
|
|
16
|
+
import type * as Context from "effect/Context"
|
|
17
|
+
import * as Deferred from "effect/Deferred"
|
|
18
|
+
import * as Effect from "effect/Effect"
|
|
19
|
+
import * as Exit from "effect/Exit"
|
|
20
|
+
import * as Scope from "effect/Scope"
|
|
21
|
+
import * as Stream from "effect/Stream"
|
|
22
|
+
import type {
|
|
23
|
+
EventBufferOptions,
|
|
24
|
+
EventContext,
|
|
25
|
+
EventInvocation,
|
|
26
|
+
EventWaitOptions,
|
|
27
|
+
HandlerOptions,
|
|
28
|
+
EventMap,
|
|
29
|
+
EventName,
|
|
30
|
+
} from "#sdk/events"
|
|
31
|
+
import { ClientClosedError, ConfigurationError } from "#sdk/errors"
|
|
32
|
+
import {
|
|
33
|
+
EventOverflowError,
|
|
34
|
+
EventReadBusyError,
|
|
35
|
+
EventWaitError,
|
|
36
|
+
type EventReadError,
|
|
37
|
+
type RegistrationError,
|
|
38
|
+
} from "#sdk/message-errors"
|
|
39
|
+
import type { Message, MessageCore } from "#sdk/messages"
|
|
40
|
+
import type { MessageReference } from "#sdk/messages"
|
|
41
|
+
import type { MessageReaction, MessageReactionBatch } from "#sdk/reactions"
|
|
42
|
+
import { inputDefect, readInput } from "./defects.js"
|
|
43
|
+
import { withDeadline } from "./effect-failures.js"
|
|
44
|
+
import { nowMs } from "./clock.js"
|
|
45
|
+
import { record } from "./decode/primitives.js"
|
|
46
|
+
import { discardInvalidCallbackReturn } from "./invalid-callback-return.js"
|
|
47
|
+
import type { ClientLogger } from "./logging.js"
|
|
48
|
+
import {
|
|
49
|
+
logHandlerReport,
|
|
50
|
+
makeReport,
|
|
51
|
+
messageReference,
|
|
52
|
+
primaryError,
|
|
53
|
+
standaloneHookQueue,
|
|
54
|
+
throwIfErr,
|
|
55
|
+
type FailureReporter,
|
|
56
|
+
type HookQueue,
|
|
57
|
+
type InternalReport,
|
|
58
|
+
} from "./failures.js"
|
|
59
|
+
import { metrics } from "./metrics.js"
|
|
60
|
+
import { RejectionScope, fiberRejectionScope, withRejectionScope } from "./rejection-scope.js"
|
|
61
|
+
import { emitObservation, failureFacts, observing } from "./observer.js"
|
|
62
|
+
import { editDistance, unsupportedKeyHint } from "./suggest.js"
|
|
63
|
+
|
|
64
|
+
/** Mutable facts shared by the event worker and a command router that handles this invocation */
|
|
65
|
+
interface InvocationOutcome {
|
|
66
|
+
command: string | undefined
|
|
67
|
+
failure: Cause.Cause<unknown> | undefined
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Rejection scopes already cross both the native fiber and default Promise boundaries of one invocation
|
|
71
|
+
const invocationOutcomes = new WeakMap<RejectionScope, InvocationOutcome>()
|
|
72
|
+
|
|
73
|
+
/** Select the canonical command name once a router matches, before its guards and middleware run */
|
|
74
|
+
export function identifyCommand(name: string): Effect.Effect<void> {
|
|
75
|
+
return Effect.withFiber((fiber) => {
|
|
76
|
+
const scope = fiberRejectionScope(fiber.context)
|
|
77
|
+
const outcome = scope === undefined ? undefined : invocationOutcomes.get(scope)
|
|
78
|
+
if (outcome) outcome.command = name
|
|
79
|
+
return Effect.void
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Keep a reported command failure visible to the enclosing handler observation, even when dispatch recovers */
|
|
84
|
+
export function recordCommandFailure(
|
|
85
|
+
name: string | undefined,
|
|
86
|
+
cause: Cause.Cause<unknown>,
|
|
87
|
+
context: Context.Context<never>,
|
|
88
|
+
): void {
|
|
89
|
+
const scope = fiberRejectionScope(context)
|
|
90
|
+
const outcome = scope === undefined ? undefined : invocationOutcomes.get(scope)
|
|
91
|
+
if (outcome) outcome.failure ??= cause
|
|
92
|
+
metrics.handlerFailure(name ?? "messageCreate", context)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** One admitted event with the shard and received frame size it arrived with */
|
|
96
|
+
interface Delivery<A> {
|
|
97
|
+
readonly message: A
|
|
98
|
+
readonly bytes: number
|
|
99
|
+
readonly shardId: number
|
|
100
|
+
/** Partition key, computed once when a partitioned handler first considers this event, or the failure computing it */
|
|
101
|
+
key?: string | { readonly failure: unknown }
|
|
102
|
+
}
|
|
103
|
+
type Resume<A> = (value: Effect.Effect<Delivery<A> | null, EventOverflowError>) => void
|
|
104
|
+
type Limits = Required<Omit<HandlerOptions, "partition">> & { readonly partition: HandlerOptions["partition"] }
|
|
105
|
+
|
|
106
|
+
/** Default handler concurrency when a partition is set, so events of different keys can run side by side */
|
|
107
|
+
const partitionedConcurrency = 8
|
|
108
|
+
|
|
109
|
+
/** Events whose own ID is the community they describe */
|
|
110
|
+
const guildSelfEvents: ReadonlySet<EventName> = new Set(["guildCreate", "guildUpdate", "guildDelete"])
|
|
111
|
+
/** Events whose own ID is the channel they describe, a thread being a channel */
|
|
112
|
+
const channelSelfEvents: ReadonlySet<EventName> = new Set([
|
|
113
|
+
"guildChannelCreate",
|
|
114
|
+
"guildChannelUpdate",
|
|
115
|
+
"guildChannelDelete",
|
|
116
|
+
"directMessageCreate",
|
|
117
|
+
"directMessageUpdate",
|
|
118
|
+
"directMessageDelete",
|
|
119
|
+
"threadCreate",
|
|
120
|
+
"threadUpdate",
|
|
121
|
+
"threadDelete",
|
|
122
|
+
])
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* The partition key of one event. The guild partition uses the community ID, else the channel ID, so direct messages are
|
|
126
|
+
* ordered per conversation, and the channel partition uses the channel ID, else the community ID. A thread member
|
|
127
|
+
* change's channel is its thread. An event with neither uses the empty key, shared by all such events. A function's
|
|
128
|
+
* undefined also selects the empty key
|
|
129
|
+
*/
|
|
130
|
+
function partitionKey(partition: NonNullable<Limits["partition"]>, event: EventName, payload: unknown): unknown {
|
|
131
|
+
if (typeof partition === "function") return partition(payload as never)
|
|
132
|
+
const value = payload as {
|
|
133
|
+
readonly id?: unknown
|
|
134
|
+
readonly guildId?: unknown
|
|
135
|
+
readonly channelId?: unknown
|
|
136
|
+
readonly threadId?: unknown
|
|
137
|
+
}
|
|
138
|
+
const guild = typeof value.guildId === "string" ? value.guildId : guildSelfEvents.has(event) ? value.id : undefined
|
|
139
|
+
const channel =
|
|
140
|
+
typeof value.channelId === "string"
|
|
141
|
+
? value.channelId
|
|
142
|
+
: typeof value.threadId === "string"
|
|
143
|
+
? value.threadId
|
|
144
|
+
: channelSelfEvents.has(event)
|
|
145
|
+
? value.id
|
|
146
|
+
: undefined
|
|
147
|
+
const key = partition === "guild" ? (guild ?? channel) : (channel ?? guild)
|
|
148
|
+
return typeof key === "string" ? key : undefined
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* One registered event middleware in its Effect form. Each entry point adapts its public middleware to this shape,
|
|
153
|
+
* and next never fails: Failures after it are reported where they occur
|
|
154
|
+
*/
|
|
155
|
+
export type InternalMiddleware = (
|
|
156
|
+
invocation: EventInvocation<MessageCore>,
|
|
157
|
+
next: Effect.Effect<void>,
|
|
158
|
+
) => Effect.Effect<unknown, unknown>
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Adapt default-API middleware. Its next promise runs the rest of the chain with the invocation's services and signal,
|
|
162
|
+
* and resolves once that finishes, even after a reported failure or interruption
|
|
163
|
+
*/
|
|
164
|
+
export function defaultMiddleware(
|
|
165
|
+
middleware: (invocation: EventInvocation<MessageCore>, next: () => Promise<void>, signal: AbortSignal) => unknown,
|
|
166
|
+
): InternalMiddleware {
|
|
167
|
+
return (invocation, next) =>
|
|
168
|
+
Effect.flatMap(Effect.context<never>(), (services) =>
|
|
169
|
+
// @effect-diagnostics-next-line unknownInEffectCatch:off
|
|
170
|
+
Effect.tryPromise({
|
|
171
|
+
try: (signal) =>
|
|
172
|
+
new Promise<unknown>((resolve) => {
|
|
173
|
+
const runNext = () =>
|
|
174
|
+
Effect.runPromiseExitWith(services)(next, { signal }).then(() => undefined)
|
|
175
|
+
resolve(middleware(invocation, runNext, signal))
|
|
176
|
+
}).then(throwIfErr),
|
|
177
|
+
// Keep the thrown or rejected value itself for the failure report
|
|
178
|
+
catch: (error) => error,
|
|
179
|
+
}),
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Adapt native middleware to run with the services captured at registration, while its next Effect runs the rest of
|
|
185
|
+
* the chain with the handler's own services
|
|
186
|
+
*/
|
|
187
|
+
export function nativeMiddleware(
|
|
188
|
+
middleware: (
|
|
189
|
+
invocation: EventInvocation<MessageCore>,
|
|
190
|
+
next: Effect.Effect<void>,
|
|
191
|
+
) => Effect.Effect<unknown, unknown, never>,
|
|
192
|
+
services: Context.Context<never>,
|
|
193
|
+
): InternalMiddleware {
|
|
194
|
+
return (invocation, next) =>
|
|
195
|
+
Effect.flatMap(Effect.context<never>(), (outer) =>
|
|
196
|
+
Effect.suspend(() =>
|
|
197
|
+
middleware(
|
|
198
|
+
invocation,
|
|
199
|
+
Effect.updateContext(next, () => outer),
|
|
200
|
+
),
|
|
201
|
+
).pipe(Effect.provideContext(services)),
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Frozen delivery details for a handler */
|
|
206
|
+
function eventContext(delivery: Delivery<unknown>): EventContext {
|
|
207
|
+
return Object.freeze({ shardId: delivery.shardId, receivedBytes: delivery.bytes })
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/** Identity and logging for one event source, shared with its overflow records */
|
|
211
|
+
export interface SourceMeta {
|
|
212
|
+
readonly event: EventName
|
|
213
|
+
readonly id: string
|
|
214
|
+
readonly logger: (() => ClientLogger | undefined) | undefined
|
|
215
|
+
/** Whether overflow ends the source. Registrations report it separately */
|
|
216
|
+
readonly managed: boolean
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Names commonly guessed for a readiness event, compared in lowercase */
|
|
220
|
+
const readyNames: ReadonlySet<string> = new Set(["ready", "clientready", "onready", "connected"])
|
|
221
|
+
|
|
222
|
+
/** Explain an unsupported event name, suggesting the closest supported one. Event names are not sensitive */
|
|
223
|
+
function unknownEventError(event: unknown, names: readonly string[]): ConfigurationError {
|
|
224
|
+
if (typeof event !== "string" || event.length > 64)
|
|
225
|
+
return new ConfigurationError("event", "Unsupported event name", {
|
|
226
|
+
hint: "Use an event name such as messageCreate",
|
|
227
|
+
})
|
|
228
|
+
// Readiness is connection state, not an event, so point to the ways to run code at startup
|
|
229
|
+
if (readyNames.has(event.toLowerCase()))
|
|
230
|
+
return new ConfigurationError("event", `Unknown event name ${JSON.stringify(event)}`, {
|
|
231
|
+
hint: "Fluxerly has no ready event. runBot logs when the bot is connected, and its setup option runs startup work before the bot connects. With createClient, code after client.connect() runs once the bot is connected, and client.observeState reports each connection state",
|
|
232
|
+
})
|
|
233
|
+
let best: string | undefined
|
|
234
|
+
let distance = Infinity
|
|
235
|
+
for (const name of names) {
|
|
236
|
+
const candidate = editDistance(event.toLowerCase(), name.toLowerCase())
|
|
237
|
+
if (candidate < distance) {
|
|
238
|
+
best = name
|
|
239
|
+
distance = candidate
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const suggestion = best !== undefined && distance <= Math.max(2, Math.floor(event.length / 3)) ? best : undefined
|
|
243
|
+
return new ConfigurationError("event", `Unknown event name ${JSON.stringify(event)}`, {
|
|
244
|
+
hint: `${suggestion === undefined ? "" : `Did you mean ${JSON.stringify(suggestion)}? `}Event names are listed in EventMap, such as messageCreate and guildMemberAdd`,
|
|
245
|
+
})
|
|
246
|
+
}
|
|
247
|
+
/** Narrow the two message-bearing dispatch names without treating other events as messages */
|
|
248
|
+
export function isMessageEvent<K extends EventName, M extends MessageCore>(
|
|
249
|
+
event: K,
|
|
250
|
+
_message: EventMap<M>[K],
|
|
251
|
+
): _message is EventMap<M>[K] & M {
|
|
252
|
+
return event === "messageCreate" || event === "messageUpdate"
|
|
253
|
+
}
|
|
254
|
+
type EventWaitSettings<K extends EventName, M extends MessageCore = Message> = {
|
|
255
|
+
readonly buffer: EventBufferOptions
|
|
256
|
+
readonly filter: ((event: EventMap<M>[K]) => boolean) | undefined
|
|
257
|
+
readonly timeoutMs: number
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const maximumTimerMs = 2_147_483_647
|
|
261
|
+
|
|
262
|
+
function eventWaitSettings<K extends EventName, M extends MessageCore = Message>(
|
|
263
|
+
options: EventWaitOptions<K, M> | undefined,
|
|
264
|
+
allowSignal: boolean,
|
|
265
|
+
): EventWaitSettings<K, M> | ConfigurationError {
|
|
266
|
+
const input = options === undefined ? {} : options
|
|
267
|
+
if (!record(input)) return new ConfigurationError("eventOptions", "Event wait options must be an object")
|
|
268
|
+
const supported = [
|
|
269
|
+
"filter",
|
|
270
|
+
"timeoutMs",
|
|
271
|
+
"maxPendingMessages",
|
|
272
|
+
"maxPendingBytes",
|
|
273
|
+
...(allowSignal ? ["signal"] : []),
|
|
274
|
+
]
|
|
275
|
+
const unsupported = Object.keys(input).find((key) => !supported.includes(key))
|
|
276
|
+
if (unsupported !== undefined)
|
|
277
|
+
return new ConfigurationError("eventOptions", `Unsupported event wait option ${JSON.stringify(unsupported)}`, {
|
|
278
|
+
hint: unsupportedKeyHint(unsupported, supported),
|
|
279
|
+
})
|
|
280
|
+
// Read each option once, so the validated values are the ones the wait uses
|
|
281
|
+
const timeoutInput = input.timeoutMs
|
|
282
|
+
const timeoutMs = timeoutInput === undefined ? 30_000 : timeoutInput
|
|
283
|
+
if (
|
|
284
|
+
typeof timeoutMs !== "number" ||
|
|
285
|
+
!Number.isSafeInteger(timeoutMs) ||
|
|
286
|
+
timeoutMs <= 0 ||
|
|
287
|
+
timeoutMs > maximumTimerMs
|
|
288
|
+
)
|
|
289
|
+
return new ConfigurationError(
|
|
290
|
+
"timeoutMs",
|
|
291
|
+
`The event wait option "timeoutMs" must be a positive safe integer of at most ${maximumTimerMs} ms`,
|
|
292
|
+
)
|
|
293
|
+
const filter = input.filter
|
|
294
|
+
if (filter !== undefined && typeof filter !== "function")
|
|
295
|
+
return new ConfigurationError("filter", 'The event wait option "filter" must be a function')
|
|
296
|
+
const maxPendingMessages = input.maxPendingMessages
|
|
297
|
+
const maxPendingBytes = input.maxPendingBytes
|
|
298
|
+
return {
|
|
299
|
+
buffer: {
|
|
300
|
+
...(maxPendingMessages === undefined ? {} : { maxPendingMessages }),
|
|
301
|
+
...(maxPendingBytes === undefined ? {} : { maxPendingBytes }),
|
|
302
|
+
} as EventBufferOptions,
|
|
303
|
+
filter: filter as ((event: EventMap<M>[K]) => boolean) | undefined,
|
|
304
|
+
timeoutMs,
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function limits(options: unknown, defaultOverflow: Limits["overflow"]): Limits | ConfigurationError {
|
|
309
|
+
if (options === undefined) options = {}
|
|
310
|
+
if (!record(options)) return new ConfigurationError("eventOptions", "Event options must be an object")
|
|
311
|
+
const partition = options.partition
|
|
312
|
+
if (partition !== undefined && partition !== "guild" && partition !== "channel" && typeof partition !== "function")
|
|
313
|
+
return new ConfigurationError(
|
|
314
|
+
"partition",
|
|
315
|
+
'The event option "partition" must be "guild", "channel" or a function',
|
|
316
|
+
)
|
|
317
|
+
const defaults = {
|
|
318
|
+
concurrency: partition === undefined ? 1 : partitionedConcurrency,
|
|
319
|
+
maxPendingMessages: 256,
|
|
320
|
+
maxPendingBytes: 4_194_304,
|
|
321
|
+
}
|
|
322
|
+
for (const key of Object.keys(defaults) as (keyof typeof defaults)[]) {
|
|
323
|
+
const value = options[key]
|
|
324
|
+
if (value !== undefined) {
|
|
325
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0)
|
|
326
|
+
return new ConfigurationError(
|
|
327
|
+
key,
|
|
328
|
+
`The event option ${JSON.stringify(key)} must be a positive safe integer`,
|
|
329
|
+
)
|
|
330
|
+
defaults[key] = value
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
const overflow = options.overflow ?? defaultOverflow
|
|
334
|
+
if (overflow !== "stop" && overflow !== "dropOldest" && overflow !== "dropNewest")
|
|
335
|
+
return new ConfigurationError(
|
|
336
|
+
"overflow",
|
|
337
|
+
'The event option "overflow" must be "stop", "dropOldest" or "dropNewest"',
|
|
338
|
+
)
|
|
339
|
+
return { ...defaults, overflow, partition: partition as Limits["partition"] }
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/** One bounded subscription. Gateway callbacks never await asynchronous consumer work, though a waiting synchronous filter can continue immediately after admission */
|
|
343
|
+
export class EventSource<A = Message> {
|
|
344
|
+
readonly closed = Deferred.makeUnsafe<void, EventOverflowError>()
|
|
345
|
+
readonly limits: Limits
|
|
346
|
+
#pending: Delivery<A>[] = []
|
|
347
|
+
#bytes = 0
|
|
348
|
+
#waiters = new Set<Resume<A>>()
|
|
349
|
+
#active = true
|
|
350
|
+
#reading = false
|
|
351
|
+
#failure: EventOverflowError | undefined
|
|
352
|
+
#stopWorker: (() => void) | undefined
|
|
353
|
+
#managed = false
|
|
354
|
+
#cleanupCause: Cause.Cause<never> = Cause.empty
|
|
355
|
+
#arrival: (() => void) | undefined
|
|
356
|
+
readonly meta: SourceMeta
|
|
357
|
+
|
|
358
|
+
constructor(
|
|
359
|
+
limits: Limits,
|
|
360
|
+
readonly release: () => void,
|
|
361
|
+
meta: SourceMeta = { event: "messageCreate", id: "messageCreate#0", logger: undefined, managed: false },
|
|
362
|
+
) {
|
|
363
|
+
this.limits = limits
|
|
364
|
+
this.meta = meta
|
|
365
|
+
}
|
|
366
|
+
/** Stable subscription identifier used in failure reports and log records */
|
|
367
|
+
get id() {
|
|
368
|
+
return this.meta.id
|
|
369
|
+
}
|
|
370
|
+
get active() {
|
|
371
|
+
return this.#active
|
|
372
|
+
}
|
|
373
|
+
get failure() {
|
|
374
|
+
return this.#failure
|
|
375
|
+
}
|
|
376
|
+
/** Events waiting in this source's queue */
|
|
377
|
+
get pendingCount() {
|
|
378
|
+
return this.#pending.length
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/** Call this function after each event that enters the queue, for a worker that selects events with takeFirst */
|
|
382
|
+
onArrival(callback: () => void) {
|
|
383
|
+
this.#arrival = callback
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/** Remove and return the first waiting event that accept selects, or undefined when none qualifies */
|
|
387
|
+
takeFirst(accept: (delivery: Delivery<A>) => boolean): Delivery<A> | undefined {
|
|
388
|
+
if (!this.#active) return undefined
|
|
389
|
+
const index = this.#pending.findIndex(accept)
|
|
390
|
+
if (index === -1) return undefined
|
|
391
|
+
const [delivery] = this.#pending.splice(index, 1)
|
|
392
|
+
this.#bytes -= delivery!.bytes
|
|
393
|
+
return delivery
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/** Admit one event received by a shard, in a frame of the given byte length */
|
|
397
|
+
offer(message: A, bytes: number, shardId = 0) {
|
|
398
|
+
if (!this.#active) return
|
|
399
|
+
const waiter = this.#waiters.values().next().value
|
|
400
|
+
if (waiter) {
|
|
401
|
+
this.#waiters.delete(waiter)
|
|
402
|
+
waiter(Effect.succeed({ message, bytes, shardId }))
|
|
403
|
+
return
|
|
404
|
+
}
|
|
405
|
+
const full = () =>
|
|
406
|
+
this.#pending.length >= this.limits.maxPendingMessages || bytes > this.limits.maxPendingBytes - this.#bytes
|
|
407
|
+
if (!full()) {
|
|
408
|
+
this.#pending.push({ message, bytes, shardId })
|
|
409
|
+
this.#bytes += bytes
|
|
410
|
+
this.#arrival?.()
|
|
411
|
+
return
|
|
412
|
+
}
|
|
413
|
+
const limit = this.#pending.length >= this.limits.maxPendingMessages ? "messages" : "bytes"
|
|
414
|
+
const policy = this.limits.overflow
|
|
415
|
+
if (policy === "dropOldest" && bytes <= this.limits.maxPendingBytes) {
|
|
416
|
+
let dropped = 0
|
|
417
|
+
while (full() && this.#pending.length) {
|
|
418
|
+
this.#bytes -= this.#pending.shift()!.bytes
|
|
419
|
+
dropped++
|
|
420
|
+
}
|
|
421
|
+
this.#pending.push({ message, bytes, shardId })
|
|
422
|
+
this.#bytes += bytes
|
|
423
|
+
this.#dropped(dropped, dropped === 1 ? "the oldest waiting event" : "the oldest waiting events", limit)
|
|
424
|
+
this.#arrival?.()
|
|
425
|
+
return
|
|
426
|
+
}
|
|
427
|
+
if (policy !== "stop") {
|
|
428
|
+
this.#dropped(1, "the newest event", limit)
|
|
429
|
+
return
|
|
430
|
+
}
|
|
431
|
+
const discarded = this.#pending.length + 1
|
|
432
|
+
const failure = new EventOverflowError(
|
|
433
|
+
limit,
|
|
434
|
+
limit === "messages" ? this.limits.maxPendingMessages : this.limits.maxPendingBytes,
|
|
435
|
+
)
|
|
436
|
+
const logger = this.meta.logger?.()
|
|
437
|
+
logger?.countDrop("overflow", discarded)
|
|
438
|
+
if (!this.meta.managed)
|
|
439
|
+
logger?.log({
|
|
440
|
+
level: "warn",
|
|
441
|
+
category: "events",
|
|
442
|
+
code: "events.overflow",
|
|
443
|
+
message: `The ${this.meta.event} subscription ${this.meta.id} stopped because ${limit === "messages" ? `more than ${failure.capacity} ${failure.capacity === 1 ? "event was" : "events were"} waiting (maxPendingMessages)` : `waiting events exceeded ${failure.capacity} bytes (maxPendingBytes)`}, so ${discarded} unhandled ${discarded === 1 ? "event was" : "events were"} discarded`,
|
|
444
|
+
event: this.meta.event,
|
|
445
|
+
subscriptionId: this.meta.id,
|
|
446
|
+
fields: { limit, capacity: failure.capacity, discarded },
|
|
447
|
+
error: failure,
|
|
448
|
+
})
|
|
449
|
+
this.stop(failure)
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
#dropped(count: number, which: string, limit: "messages" | "bytes") {
|
|
453
|
+
const logger = this.meta.logger?.()
|
|
454
|
+
if (!logger) return
|
|
455
|
+
logger.drop(
|
|
456
|
+
{ event: "overflow", amount: count },
|
|
457
|
+
{
|
|
458
|
+
level: "warn",
|
|
459
|
+
category: "events",
|
|
460
|
+
code: "events.dropped",
|
|
461
|
+
message: `The queue of the ${this.meta.event} subscription ${this.meta.id} is full (${limit === "messages" ? "maxPendingMessages" : "maxPendingBytes"}), so ${which} ${count === 1 ? "was" : "were"} dropped`,
|
|
462
|
+
event: this.meta.event,
|
|
463
|
+
subscriptionId: this.meta.id,
|
|
464
|
+
fields: {
|
|
465
|
+
limit,
|
|
466
|
+
capacity: limit === "messages" ? this.limits.maxPendingMessages : this.limits.maxPendingBytes,
|
|
467
|
+
policy: this.limits.overflow,
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
)
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/** Stop intake and discard waiting events. The reason names who stopped it in the record of what was discarded */
|
|
474
|
+
stop(failure?: EventOverflowError, reason: "clientClosed" | "subscriptionClosed" = "subscriptionClosed") {
|
|
475
|
+
if (!this.#active) return
|
|
476
|
+
this.#active = false
|
|
477
|
+
this.#failure = failure
|
|
478
|
+
// An overflow stop has already recorded and counted the events it discarded
|
|
479
|
+
if (!failure && this.#pending.length) this.#discarded(this.#pending.length, reason)
|
|
480
|
+
this.#pending = []
|
|
481
|
+
this.#bytes = 0
|
|
482
|
+
for (const resume of this.#waiters) resume(failure ? Effect.fail(failure) : Effect.succeed(null))
|
|
483
|
+
this.#waiters.clear()
|
|
484
|
+
this.#stopWorker?.()
|
|
485
|
+
if (!this.#managed) this.finish(Exit.void)
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/** Count the waiting events a stop discards and log one summary: Info when the client closes, Debug when the subscription closes */
|
|
489
|
+
#discarded(count: number, reason: "clientClosed" | "subscriptionClosed") {
|
|
490
|
+
const logger = this.meta.logger?.()
|
|
491
|
+
logger?.countDrop("closed", count)
|
|
492
|
+
logger?.log({
|
|
493
|
+
level: reason === "clientClosed" ? "info" : "debug",
|
|
494
|
+
category: "events",
|
|
495
|
+
code: "events.discarded",
|
|
496
|
+
message: `The ${this.meta.event} subscription ${this.meta.id} discarded ${count} waiting ${count === 1 ? "event" : "events"}, because ${reason === "clientClosed" ? "the client is closing" : "the subscription closed"}`,
|
|
497
|
+
event: this.meta.event,
|
|
498
|
+
subscriptionId: this.meta.id,
|
|
499
|
+
fields: { discarded: count, reason },
|
|
500
|
+
})
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
manage(stopWorker: () => void) {
|
|
504
|
+
this.#managed = true
|
|
505
|
+
this.#stopWorker = stopWorker
|
|
506
|
+
if (!this.#active) stopWorker()
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
recordCleanup(exit: Exit.Exit<unknown, unknown>) {
|
|
510
|
+
if (!this.#active && Exit.isFailure(exit) && Cause.hasDies(exit.cause)) {
|
|
511
|
+
this.#cleanupCause = Cause.combine(
|
|
512
|
+
this.#cleanupCause,
|
|
513
|
+
Cause.fromReasons<never>(exit.cause.reasons.filter((reason) => reason._tag !== "Fail")),
|
|
514
|
+
)
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
finish(exit: Exit.Exit<unknown, unknown>) {
|
|
519
|
+
this.#active = false
|
|
520
|
+
this.#pending = []
|
|
521
|
+
this.#bytes = 0
|
|
522
|
+
this.#stopWorker = undefined
|
|
523
|
+
this.#arrival = undefined
|
|
524
|
+
this.release()
|
|
525
|
+
let cause: Cause.Cause<EventOverflowError> = this.#failure ? Cause.fail(this.#failure) : Cause.empty
|
|
526
|
+
if (Exit.isFailure(exit) && Cause.hasDies(exit.cause)) {
|
|
527
|
+
cause = Cause.combine(
|
|
528
|
+
cause,
|
|
529
|
+
Cause.fromReasons(exit.cause.reasons.filter((reason) => reason._tag !== "Fail")),
|
|
530
|
+
)
|
|
531
|
+
}
|
|
532
|
+
cause = Cause.fromReasons([...new Set([...cause.reasons, ...this.#cleanupCause.reasons])])
|
|
533
|
+
Deferred.doneUnsafe(this.closed, cause.reasons.length ? Effect.failCause(cause) : Effect.void)
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
take(): Effect.Effect<A | null, EventOverflowError> {
|
|
537
|
+
return Effect.map(this.takeDelivery(), (delivery) => (delivery === null ? null : delivery.message))
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/** Take the next event with the shard and frame size it arrived with */
|
|
541
|
+
takeDelivery(): Effect.Effect<Delivery<A> | null, EventOverflowError> {
|
|
542
|
+
return Effect.suspend(() => {
|
|
543
|
+
if (this.#failure) return Effect.fail(this.#failure)
|
|
544
|
+
if (!this.#active) return Effect.succeed(null)
|
|
545
|
+
const item = this.#pending.shift()
|
|
546
|
+
if (item) {
|
|
547
|
+
this.#bytes -= item.bytes
|
|
548
|
+
return Effect.succeed(item)
|
|
549
|
+
}
|
|
550
|
+
return Effect.callback<Delivery<A> | null, EventOverflowError>((resume) => {
|
|
551
|
+
this.#waiters.add(resume)
|
|
552
|
+
return Effect.sync(() => {
|
|
553
|
+
this.#waiters.delete(resume)
|
|
554
|
+
})
|
|
555
|
+
})
|
|
556
|
+
})
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
next(): Effect.Effect<A | null, EventReadError> {
|
|
560
|
+
return Effect.suspend((): Effect.Effect<A | null, EventReadError> => {
|
|
561
|
+
if (this.#reading) return Effect.fail(new EventReadBusyError())
|
|
562
|
+
this.#reading = true
|
|
563
|
+
return this.take().pipe(
|
|
564
|
+
Effect.ensuring(
|
|
565
|
+
Effect.sync(() => {
|
|
566
|
+
this.#reading = false
|
|
567
|
+
}),
|
|
568
|
+
),
|
|
569
|
+
)
|
|
570
|
+
})
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/** One internal single-consumption event wait */
|
|
575
|
+
interface EventWaitSource<K extends EventName, M extends MessageCore = Message> {
|
|
576
|
+
stop(): void
|
|
577
|
+
wait(): Effect.Effect<EventMap<M>[K], EventWaitError | EventOverflowError | ClientClosedError>
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
class EventWait<K extends EventName, M extends MessageCore = Message> implements EventWaitSource<K, M> {
|
|
581
|
+
#stopped = false
|
|
582
|
+
#filter: ((event: EventMap<M>[K]) => boolean) | undefined
|
|
583
|
+
|
|
584
|
+
constructor(
|
|
585
|
+
private readonly source: EventSource<EventMap<M>[K]>,
|
|
586
|
+
filter: ((event: EventMap<M>[K]) => boolean) | undefined,
|
|
587
|
+
private readonly deadline: number,
|
|
588
|
+
private readonly clock: Clock.Clock,
|
|
589
|
+
) {
|
|
590
|
+
this.#filter = filter
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
stop() {
|
|
594
|
+
if (this.#stopped) return
|
|
595
|
+
this.#stopped = true
|
|
596
|
+
this.#filter = undefined
|
|
597
|
+
this.source.stop()
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
#now() {
|
|
601
|
+
return nowMs(this.clock)
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
#expired() {
|
|
605
|
+
return this.#now() >= this.deadline
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
#accept(event: EventMap<M>[K]): boolean | EventWaitError {
|
|
609
|
+
if (!this.#filter) return true
|
|
610
|
+
let accepted: unknown
|
|
611
|
+
try {
|
|
612
|
+
accepted = this.#filter(event)
|
|
613
|
+
} catch (error) {
|
|
614
|
+
return new EventWaitError("filter", { cause: error })
|
|
615
|
+
}
|
|
616
|
+
discardInvalidCallbackReturn(accepted)
|
|
617
|
+
return typeof accepted === "boolean" ? accepted : new EventWaitError("filter")
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
wait(): Effect.Effect<EventMap<M>[K], EventWaitError | EventOverflowError | ClientClosedError> {
|
|
621
|
+
return Effect.suspend(() => {
|
|
622
|
+
const remaining = this.deadline - this.#now()
|
|
623
|
+
if (remaining <= 0) {
|
|
624
|
+
this.stop()
|
|
625
|
+
return Effect.fail(new EventWaitError("timeout"))
|
|
626
|
+
}
|
|
627
|
+
const waiter = this
|
|
628
|
+
const wait = Effect.gen(function* () {
|
|
629
|
+
while (true) {
|
|
630
|
+
const event = yield* waiter.source.take()
|
|
631
|
+
if (event === null) return yield* Effect.fail(new ClientClosedError())
|
|
632
|
+
if (waiter.#expired()) return yield* Effect.fail(new EventWaitError("timeout"))
|
|
633
|
+
const accepted = waiter.#accept(event)
|
|
634
|
+
if (accepted instanceof EventWaitError) return yield* Effect.fail(accepted)
|
|
635
|
+
if (waiter.#expired()) return yield* Effect.fail(new EventWaitError("timeout"))
|
|
636
|
+
if (accepted) return event
|
|
637
|
+
}
|
|
638
|
+
})
|
|
639
|
+
return wait.pipe(
|
|
640
|
+
withDeadline(Math.max(1, Math.ceil(remaining)), () => new EventWaitError("timeout")),
|
|
641
|
+
Effect.ensuring(Effect.sync(() => this.stop())),
|
|
642
|
+
)
|
|
643
|
+
})
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
export class EventBus<M extends MessageCore = Message> {
|
|
648
|
+
constructor(
|
|
649
|
+
private readonly logging?: () => ClientLogger,
|
|
650
|
+
private readonly failures?: () => FailureReporter,
|
|
651
|
+
) {}
|
|
652
|
+
#nextId = 0
|
|
653
|
+
|
|
654
|
+
#reactionCollectors = new Map<
|
|
655
|
+
string,
|
|
656
|
+
Set<
|
|
657
|
+
(reaction: MessageReaction | MessageReactionBatch, bytes: number, shardId: number, removal: boolean) => void
|
|
658
|
+
>
|
|
659
|
+
>()
|
|
660
|
+
/** Open reaction listeners that also receive single removals, so Identify keeps MESSAGE_REACTION_REMOVE */
|
|
661
|
+
#reactionRemovalListeners = 0
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Exact message selection precedes queue admission, and user filters run outside gateway decoding.
|
|
665
|
+
* With removals, single messageReactionRemove events reach the listener in the same order as additions
|
|
666
|
+
*/
|
|
667
|
+
listenReactions(
|
|
668
|
+
target: MessageReference,
|
|
669
|
+
listener: (reaction: MessageReaction | MessageReactionBatch, bytes: number) => void,
|
|
670
|
+
shardId?: number,
|
|
671
|
+
removals = false,
|
|
672
|
+
) {
|
|
673
|
+
const key = `${target.channelId}:${target.id}`
|
|
674
|
+
let listeners = this.#reactionCollectors.get(key)
|
|
675
|
+
if (!listeners) this.#reactionCollectors.set(key, (listeners = new Set()))
|
|
676
|
+
const offer = (
|
|
677
|
+
message: MessageReaction | MessageReactionBatch,
|
|
678
|
+
bytes: number,
|
|
679
|
+
sourceShard: number,
|
|
680
|
+
removal: boolean,
|
|
681
|
+
) => {
|
|
682
|
+
if ((removals || !removal) && (shardId === undefined || shardId === sourceShard)) listener(message, bytes)
|
|
683
|
+
}
|
|
684
|
+
listeners.add(offer)
|
|
685
|
+
if (removals) this.#reactionRemovalListeners += 1
|
|
686
|
+
let open = true
|
|
687
|
+
return () => {
|
|
688
|
+
if (!open) return
|
|
689
|
+
open = false
|
|
690
|
+
if (removals) this.#reactionRemovalListeners -= 1
|
|
691
|
+
listeners.delete(offer)
|
|
692
|
+
if (!listeners.size) this.#reactionCollectors.delete(key)
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
#collectors = new Map<string, Set<(message: M, bytes: number, shardId: number) => void>>()
|
|
696
|
+
|
|
697
|
+
/** Channel selection precedes collector queue admission. These callbacks only enqueue, never run user filters */
|
|
698
|
+
listenMessages(channelId: string, listener: (message: M, bytes: number) => void, shardId?: number) {
|
|
699
|
+
let listeners = this.#collectors.get(channelId)
|
|
700
|
+
if (!listeners) this.#collectors.set(channelId, (listeners = new Set()))
|
|
701
|
+
const offer = (message: M, bytes: number, sourceShard: number) => {
|
|
702
|
+
if (shardId === undefined || shardId === sourceShard) listener(message, bytes)
|
|
703
|
+
}
|
|
704
|
+
listeners.add(offer)
|
|
705
|
+
return () => {
|
|
706
|
+
listeners.delete(offer)
|
|
707
|
+
if (!listeners.size) this.#collectors.delete(channelId)
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
#sources: { [K in EventName]: Set<EventSource<EventMap<M>[K]>> } = {
|
|
711
|
+
userUpdate: new Set(),
|
|
712
|
+
directMessageCreate: new Set(),
|
|
713
|
+
directMessageUpdate: new Set(),
|
|
714
|
+
directMessageDelete: new Set(),
|
|
715
|
+
directMessageRecipientAdd: new Set(),
|
|
716
|
+
directMessageRecipientRemove: new Set(),
|
|
717
|
+
guildCreate: new Set(),
|
|
718
|
+
guildUpdate: new Set(),
|
|
719
|
+
guildDelete: new Set(),
|
|
720
|
+
webhooksUpdate: new Set(),
|
|
721
|
+
inviteCreate: new Set(),
|
|
722
|
+
inviteDelete: new Set(),
|
|
723
|
+
guildAuditLogEntryCreate: new Set(),
|
|
724
|
+
guildEmojisUpdate: new Set(),
|
|
725
|
+
guildStickersUpdate: new Set(),
|
|
726
|
+
guildChannelCreate: new Set(),
|
|
727
|
+
guildChannelUpdate: new Set(),
|
|
728
|
+
guildChannelDelete: new Set(),
|
|
729
|
+
guildChannelUpdateBulk: new Set(),
|
|
730
|
+
threadCreate: new Set(),
|
|
731
|
+
threadUpdate: new Set(),
|
|
732
|
+
threadDelete: new Set(),
|
|
733
|
+
threadListSync: new Set(),
|
|
734
|
+
threadMembersUpdate: new Set(),
|
|
735
|
+
channelPinsUpdate: new Set(),
|
|
736
|
+
guildMemberAdd: new Set(),
|
|
737
|
+
guildMemberUpdate: new Set(),
|
|
738
|
+
guildMemberRemove: new Set(),
|
|
739
|
+
presenceUpdate: new Set(),
|
|
740
|
+
presenceUpdateBulk: new Set(),
|
|
741
|
+
voiceStateSnapshot: new Set(),
|
|
742
|
+
voiceStateUpdate: new Set(),
|
|
743
|
+
guildBanAdd: new Set(),
|
|
744
|
+
guildBanRemove: new Set(),
|
|
745
|
+
guildRoleDelete: new Set(),
|
|
746
|
+
guildRoleCreate: new Set(),
|
|
747
|
+
guildRoleUpdate: new Set(),
|
|
748
|
+
guildRoleUpdateBulk: new Set(),
|
|
749
|
+
typingStart: new Set(),
|
|
750
|
+
messageCreate: new Set(),
|
|
751
|
+
messageUpdate: new Set(),
|
|
752
|
+
messageDelete: new Set(),
|
|
753
|
+
messageDeleteBulk: new Set(),
|
|
754
|
+
messageReactionAdd: new Set(),
|
|
755
|
+
messageReactionAddMany: new Set(),
|
|
756
|
+
messageReactionRemove: new Set(),
|
|
757
|
+
messageReactionRemoveAll: new Set(),
|
|
758
|
+
messageReactionRemoveEmoji: new Set(),
|
|
759
|
+
guildHealthUpdate: new Set(),
|
|
760
|
+
entranceSoundPlay: new Set(),
|
|
761
|
+
callCreate: new Set(),
|
|
762
|
+
callUpdate: new Set(),
|
|
763
|
+
callDelete: new Set(),
|
|
764
|
+
raw: new Set(),
|
|
765
|
+
}
|
|
766
|
+
/** Registered middleware in registration order. Replaced rather than mutated, so an invocation keeps the list it started with */
|
|
767
|
+
#middleware: readonly InternalMiddleware[] = []
|
|
768
|
+
/** Whether the bus stopped with its client, so registration fails with ClientClosedError */
|
|
769
|
+
get closed() {
|
|
770
|
+
return this.#closed
|
|
771
|
+
}
|
|
772
|
+
/** Add middleware around later on handler invocations, returning its idempotent removal */
|
|
773
|
+
addMiddleware(middleware: InternalMiddleware): () => void {
|
|
774
|
+
// A wrapper gives each registration its own identity, even for a middleware function registered twice
|
|
775
|
+
const entry: InternalMiddleware = (invocation, next) => middleware(invocation, next)
|
|
776
|
+
this.#middleware = [...this.#middleware, entry]
|
|
777
|
+
return () => {
|
|
778
|
+
this.#middleware = this.#middleware.filter((candidate) => candidate !== entry)
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
/** Whether any open source currently receives this event, so producers can skip building unused payloads */
|
|
782
|
+
hasSources(event: EventName): boolean {
|
|
783
|
+
return this.#sources[event].size > 0
|
|
784
|
+
}
|
|
785
|
+
/** Event names with at least one open subscription, stream, wait or collector */
|
|
786
|
+
registeredEvents(): ReadonlySet<EventName> {
|
|
787
|
+
const names = new Set(
|
|
788
|
+
(Object.keys(this.#sources) as EventName[]).filter((event) => this.#sources[event].size > 0),
|
|
789
|
+
)
|
|
790
|
+
if (this.#collectors.size) names.add("messageCreate")
|
|
791
|
+
if (this.#reactionCollectors.size) {
|
|
792
|
+
names.add("messageReactionAdd")
|
|
793
|
+
names.add("messageReactionAddMany")
|
|
794
|
+
}
|
|
795
|
+
if (this.#reactionRemovalListeners) names.add("messageReactionRemove")
|
|
796
|
+
return names
|
|
797
|
+
}
|
|
798
|
+
#closed = false
|
|
799
|
+
/** Whether intake stopped for a draining shutdown: New events and registrations are refused, admitted work continues */
|
|
800
|
+
#sealed = false
|
|
801
|
+
/** Events refused after sealing that an open subscription or collector would have received, reported once when the bus stops */
|
|
802
|
+
#refused = 0
|
|
803
|
+
/** Handler invocations started and not yet finished, counted from admission so a drain never misses one about to start */
|
|
804
|
+
#running = 0
|
|
805
|
+
/** Released and replaced whenever a handler invocation finishes, so a drain can wait for progress */
|
|
806
|
+
#progress = Deferred.makeUnsafe<void>()
|
|
807
|
+
#closingSources: Pick<EventSource, "stop" | "closed">[] = []
|
|
808
|
+
#handlerFibers = new Set<number>()
|
|
809
|
+
ownsHandler(fiberId: number) {
|
|
810
|
+
return this.#handlerFibers.has(fiberId)
|
|
811
|
+
}
|
|
812
|
+
/** Stop intake for a draining shutdown. Handlers keep running, and events already waiting in on handler queues still run */
|
|
813
|
+
seal() {
|
|
814
|
+
this.#sealed = true
|
|
815
|
+
}
|
|
816
|
+
/** Handler invocations still running and events still waiting in on handler queues */
|
|
817
|
+
drainState(): { readonly running: number; readonly waiting: number } {
|
|
818
|
+
let waiting = 0
|
|
819
|
+
for (const sources of Object.values(this.#sources))
|
|
820
|
+
for (const source of sources) if (source.meta.managed && source.active) waiting += source.pendingCount
|
|
821
|
+
return { running: this.#running, waiting }
|
|
822
|
+
}
|
|
823
|
+
/** Wait until the next handler invocation finishes */
|
|
824
|
+
progress(): Effect.Effect<void> {
|
|
825
|
+
return Effect.suspend(() => Deferred.await(this.#progress))
|
|
826
|
+
}
|
|
827
|
+
#invocationFinished() {
|
|
828
|
+
this.#running--
|
|
829
|
+
this.#signalProgress()
|
|
830
|
+
}
|
|
831
|
+
/** Wake a waiting drain after its work changed without a finished invocation, such as a closed subscription */
|
|
832
|
+
#signalProgress() {
|
|
833
|
+
const released = this.#progress
|
|
834
|
+
this.#progress = Deferred.makeUnsafe<void>()
|
|
835
|
+
Deferred.doneUnsafe(released, Effect.void)
|
|
836
|
+
}
|
|
837
|
+
diagnostics() {
|
|
838
|
+
return {
|
|
839
|
+
subscriptions: Object.values(this.#sources).reduce((total, sources) => total + sources.size, 0),
|
|
840
|
+
messageCollectors: [...this.#collectors.values()].reduce((total, listeners) => total + listeners.size, 0),
|
|
841
|
+
reactionCollectors: [...this.#reactionCollectors.values()].reduce(
|
|
842
|
+
(total, listeners) => total + listeners.size,
|
|
843
|
+
0,
|
|
844
|
+
),
|
|
845
|
+
activeHandlers: this.#handlerFibers.size,
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* Open a source for one event. Misuse fails with ConfigurationError before the closed check. On a closing or closed
|
|
850
|
+
* bus, whenClosed "closed" returns an already-stopped source that never receives events, because shutdown can race a
|
|
851
|
+
* still-running handler that registers, and whenClosed "fail" fails with ClientClosedError for one-shot waits.
|
|
852
|
+
* An omitted overflow policy uses defaultOverflow, stop unless the caller names another
|
|
853
|
+
*/
|
|
854
|
+
open<K extends EventName>(
|
|
855
|
+
event: K,
|
|
856
|
+
options?: EventBufferOptions | HandlerOptions,
|
|
857
|
+
behavior: {
|
|
858
|
+
readonly managed?: boolean
|
|
859
|
+
readonly whenClosed?: "closed" | "fail"
|
|
860
|
+
readonly defaultOverflow?: Limits["overflow"]
|
|
861
|
+
} = {},
|
|
862
|
+
): Effect.Effect<EventSource<EventMap<M>[K]>, RegistrationError> {
|
|
863
|
+
const { managed = false, whenClosed = "closed", defaultOverflow = "stop" } = behavior
|
|
864
|
+
return Effect.suspend((): Effect.Effect<EventSource<EventMap<M>[K]>, RegistrationError> => {
|
|
865
|
+
if (typeof event !== "string" || !Object.hasOwn(this.#sources, event))
|
|
866
|
+
return Effect.fail(unknownEventError(event, Object.keys(this.#sources)))
|
|
867
|
+
let settings: Limits | ConfigurationError
|
|
868
|
+
try {
|
|
869
|
+
settings = limits(options, defaultOverflow)
|
|
870
|
+
} catch (error) {
|
|
871
|
+
return Effect.failCause(inputDefect(error))
|
|
872
|
+
}
|
|
873
|
+
if (settings instanceof ConfigurationError) return Effect.fail(settings)
|
|
874
|
+
// A draining client receives no new events, so a new registration is as closed as after shutdown
|
|
875
|
+
if (this.#closed || this.#sealed)
|
|
876
|
+
return whenClosed === "fail"
|
|
877
|
+
? Effect.fail(new ClientClosedError())
|
|
878
|
+
: Effect.succeed(this.#closedSource(event, settings, managed))
|
|
879
|
+
const sources = this.#sources[event]
|
|
880
|
+
const source = new EventSource<EventMap<M>[K]>(
|
|
881
|
+
settings,
|
|
882
|
+
() => {
|
|
883
|
+
sources.delete(source)
|
|
884
|
+
this.#signalProgress()
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
event,
|
|
888
|
+
id: `${event}#${++this.#nextId}`,
|
|
889
|
+
logger: this.logging,
|
|
890
|
+
managed,
|
|
891
|
+
},
|
|
892
|
+
)
|
|
893
|
+
sources.add(source)
|
|
894
|
+
return Effect.succeed(source)
|
|
895
|
+
})
|
|
896
|
+
}
|
|
897
|
+
/** A source registered after shutdown began: Stopped at once, never added to the bus and recorded as a warning */
|
|
898
|
+
#closedSource<K extends EventName>(event: K, settings: Limits, managed: boolean) {
|
|
899
|
+
const id = `${event}#${++this.#nextId}`
|
|
900
|
+
const source = new EventSource<EventMap<M>[K]>(settings, () => undefined, {
|
|
901
|
+
event,
|
|
902
|
+
id,
|
|
903
|
+
logger: this.logging,
|
|
904
|
+
managed,
|
|
905
|
+
})
|
|
906
|
+
source.stop()
|
|
907
|
+
this.logging?.().log({
|
|
908
|
+
level: "warn",
|
|
909
|
+
category: "events",
|
|
910
|
+
code: "events.registeredAfterShutdown",
|
|
911
|
+
message: `The ${event} subscription ${id} was registered after the client began shutting down, so it starts closed and receives no events`,
|
|
912
|
+
event,
|
|
913
|
+
subscriptionId: id,
|
|
914
|
+
})
|
|
915
|
+
return source
|
|
916
|
+
}
|
|
917
|
+
offer<K extends EventName>(event: K, message: EventMap<M>[K], bytes: number, shardId = 0) {
|
|
918
|
+
const reaction =
|
|
919
|
+
event === "messageReactionAdd" ||
|
|
920
|
+
event === "messageReactionAddMany" ||
|
|
921
|
+
(event === "messageReactionRemove" && this.#reactionRemovalListeners)
|
|
922
|
+
? (message as MessageReaction | MessageReactionBatch)
|
|
923
|
+
: undefined
|
|
924
|
+
const reactionCollectors = reaction && this.#reactionCollectors.get(`${reaction.channelId}:${reaction.id}`)
|
|
925
|
+
const messageCollectors =
|
|
926
|
+
event === "messageCreate" && isMessageEvent<K, M>(event, message)
|
|
927
|
+
? this.#collectors.get(message.channelId)
|
|
928
|
+
: undefined
|
|
929
|
+
if (this.#sealed) {
|
|
930
|
+
// Collectors count too, so an event only a collector would have received is still recorded
|
|
931
|
+
if (this.#sources[event].size || reactionCollectors || messageCollectors) this.#refused++
|
|
932
|
+
return
|
|
933
|
+
}
|
|
934
|
+
for (const offer of reactionCollectors ?? [])
|
|
935
|
+
offer(reaction!, bytes, shardId, event === "messageReactionRemove")
|
|
936
|
+
for (const offer of messageCollectors ?? []) offer(message as M, bytes, shardId)
|
|
937
|
+
for (const source of this.#sources[event]) source.offer(message, bytes, shardId)
|
|
938
|
+
}
|
|
939
|
+
stop() {
|
|
940
|
+
if (this.#closed) return
|
|
941
|
+
this.#closed = true
|
|
942
|
+
if (this.#refused) {
|
|
943
|
+
const logger = this.logging?.()
|
|
944
|
+
logger?.countDrop("closed", this.#refused)
|
|
945
|
+
logger?.log({
|
|
946
|
+
level: "info",
|
|
947
|
+
category: "events",
|
|
948
|
+
code: "events.refused",
|
|
949
|
+
message: `The draining shutdown refused ${this.#refused} received ${this.#refused === 1 ? "event" : "events"} that open subscriptions or collectors would have received, because it accepts no new events`,
|
|
950
|
+
fields: { refused: this.#refused },
|
|
951
|
+
})
|
|
952
|
+
}
|
|
953
|
+
this.#closingSources = Object.values(this.#sources).flatMap((sources) => [...sources])
|
|
954
|
+
for (const source of this.#closingSources) source.stop(undefined, "clientClosed")
|
|
955
|
+
}
|
|
956
|
+
shutdown(): Effect.Effect<void> {
|
|
957
|
+
return Effect.suspend(() => {
|
|
958
|
+
this.stop()
|
|
959
|
+
return Effect.forEach(this.#closingSources, (source) => Effect.exit(Deferred.await(source.closed)), {
|
|
960
|
+
concurrency: "unbounded",
|
|
961
|
+
}).pipe(
|
|
962
|
+
Effect.flatMap((exits) => {
|
|
963
|
+
const reasons = exits.flatMap((exit) =>
|
|
964
|
+
Exit.isFailure(exit) && Cause.hasDies(exit.cause)
|
|
965
|
+
? exit.cause.reasons.filter((reason) => reason._tag !== "Fail")
|
|
966
|
+
: [],
|
|
967
|
+
)
|
|
968
|
+
return reasons.length ? Effect.failCause(Cause.fromReasons<never>(reasons)) : Effect.void
|
|
969
|
+
}),
|
|
970
|
+
Effect.ensuring(
|
|
971
|
+
Effect.sync(() => {
|
|
972
|
+
this.#closingSources = []
|
|
973
|
+
}),
|
|
974
|
+
),
|
|
975
|
+
)
|
|
976
|
+
})
|
|
977
|
+
}
|
|
978
|
+
stream<K extends EventName>(event: K, options?: EventBufferOptions) {
|
|
979
|
+
const bus = this
|
|
980
|
+
return Stream.unwrap(
|
|
981
|
+
Effect.gen(function* () {
|
|
982
|
+
const source = yield* Effect.acquireRelease(bus.open(event, options), (source) =>
|
|
983
|
+
Effect.sync(() => source.stop()),
|
|
984
|
+
)
|
|
985
|
+
return Stream.fromEffectRepeat(source.take()).pipe(
|
|
986
|
+
Stream.takeWhile((message) => message !== null),
|
|
987
|
+
Stream.map((message) => message!),
|
|
988
|
+
)
|
|
989
|
+
}),
|
|
990
|
+
)
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
on<K extends EventName, E, R, E2, R2>(
|
|
994
|
+
event: K,
|
|
995
|
+
handler: (message: EventMap<M>[K], context: EventContext) => Effect.Effect<unknown, E, R>,
|
|
996
|
+
options: HandlerOptions<EventMap<M>[K]> | undefined,
|
|
997
|
+
onError: ((report: InternalReport) => Effect.Effect<unknown, E2, R2>) | undefined,
|
|
998
|
+
scope: Scope.Scope,
|
|
999
|
+
command?: string,
|
|
1000
|
+
): Effect.Effect<EventSource<EventMap<M>[K]>, RegistrationError, R | R2> {
|
|
1001
|
+
const bus = this
|
|
1002
|
+
return Effect.uninterruptible(
|
|
1003
|
+
Effect.gen(function* () {
|
|
1004
|
+
if (typeof handler !== "function")
|
|
1005
|
+
return yield* Effect.fail(new ConfigurationError("handler", "The event handler must be a function"))
|
|
1006
|
+
if (onError !== undefined && typeof onError !== "function")
|
|
1007
|
+
return yield* Effect.fail(
|
|
1008
|
+
new ConfigurationError("onError", 'The option "onError" must be a function'),
|
|
1009
|
+
)
|
|
1010
|
+
// Handlers drop the oldest waiting event by default, so one burst never ends a long-lived handler
|
|
1011
|
+
const source = yield* bus.open(event, options, { managed: true, defaultOverflow: "dropOldest" })
|
|
1012
|
+
// A registration after shutdown began gets an already-closed subscription with no worker or hook queue
|
|
1013
|
+
if (!source.active) return source
|
|
1014
|
+
// The subscription's own hook gets a bounded queue with one worker in the registration context, so
|
|
1015
|
+
// reporting only enqueues: Hooks run one at a time in order and never hold a handler slot or shutdown
|
|
1016
|
+
let hooks: HookQueue | undefined
|
|
1017
|
+
if (onError !== undefined) {
|
|
1018
|
+
const hook = onError as (report: InternalReport) => Effect.Effect<unknown, unknown>
|
|
1019
|
+
const context = (yield* Effect.context<R2>()) as Context.Context<never>
|
|
1020
|
+
const failures = bus.failures?.()
|
|
1021
|
+
hooks = failures
|
|
1022
|
+
? failures.subscriptionQueue(hook, context)
|
|
1023
|
+
: standaloneHookQueue(() => bus.logging?.(), hook, context)
|
|
1024
|
+
}
|
|
1025
|
+
const report = (kind: "handler" | "overflow", cause: Cause.Cause<unknown>, message?: unknown) =>
|
|
1026
|
+
Effect.withFiber((fiber) => {
|
|
1027
|
+
const logger = bus.logging?.()
|
|
1028
|
+
try {
|
|
1029
|
+
const internal = makeReport(
|
|
1030
|
+
{
|
|
1031
|
+
kind,
|
|
1032
|
+
cause,
|
|
1033
|
+
event,
|
|
1034
|
+
command,
|
|
1035
|
+
subscriptionId: source.id,
|
|
1036
|
+
message: messageReference(message),
|
|
1037
|
+
},
|
|
1038
|
+
logger?.secrets,
|
|
1039
|
+
)
|
|
1040
|
+
if (kind === "handler") metrics.handlerFailure(command ?? event, fiber.context)
|
|
1041
|
+
if (hooks) {
|
|
1042
|
+
if (kind === "handler") logger?.count("handlerFailures")
|
|
1043
|
+
hooks.offer(internal)
|
|
1044
|
+
return Effect.void
|
|
1045
|
+
}
|
|
1046
|
+
const failures = bus.failures?.()
|
|
1047
|
+
if (failures) failures.report(internal, fiber.context)
|
|
1048
|
+
else if (logger) logHandlerReport(logger, internal, fiber.context)
|
|
1049
|
+
} catch (fault) {
|
|
1050
|
+
// Reporting never alters handler scheduling or subscription lifetime
|
|
1051
|
+
logger?.outputFailure(fault)
|
|
1052
|
+
}
|
|
1053
|
+
return Effect.void
|
|
1054
|
+
})
|
|
1055
|
+
// Failures after a middleware's next are reported where they occur, so next itself never fails and a
|
|
1056
|
+
// middleware cannot hide a handler failure. Interruption still ends the whole invocation. The outcome
|
|
1057
|
+
// records the first reported failure of one invocation for its handler observation
|
|
1058
|
+
type Outcome = InvocationOutcome
|
|
1059
|
+
const failed = (outcome: Outcome, cause: Cause.Cause<unknown>, message: EventMap<M>[K]) => {
|
|
1060
|
+
outcome.failure ??= cause
|
|
1061
|
+
return report("handler", cause, message)
|
|
1062
|
+
}
|
|
1063
|
+
const reported = (
|
|
1064
|
+
effect: Effect.Effect<unknown, unknown, R>,
|
|
1065
|
+
message: EventMap<M>[K],
|
|
1066
|
+
outcome: Outcome,
|
|
1067
|
+
) =>
|
|
1068
|
+
effect.pipe(
|
|
1069
|
+
Effect.asVoid,
|
|
1070
|
+
Effect.catchCause((cause) =>
|
|
1071
|
+
Cause.hasInterrupts(cause)
|
|
1072
|
+
? Effect.failCause(
|
|
1073
|
+
Cause.fromReasons<never>(
|
|
1074
|
+
cause.reasons.filter((reason) => reason._tag !== "Fail") as never,
|
|
1075
|
+
),
|
|
1076
|
+
)
|
|
1077
|
+
: failed(outcome, cause, message),
|
|
1078
|
+
),
|
|
1079
|
+
)
|
|
1080
|
+
// Run the middleware registered when this invocation starts, first registered outermost, around the handler
|
|
1081
|
+
const invoke = (
|
|
1082
|
+
message: EventMap<M>[K],
|
|
1083
|
+
context: EventContext,
|
|
1084
|
+
outcome: Outcome,
|
|
1085
|
+
): Effect.Effect<unknown, unknown, R> => {
|
|
1086
|
+
const chain = bus.#middleware
|
|
1087
|
+
if (chain.length === 0) return handler(message, context)
|
|
1088
|
+
const invocation = Object.freeze({
|
|
1089
|
+
event,
|
|
1090
|
+
payload: message,
|
|
1091
|
+
context,
|
|
1092
|
+
subscriptionId: source.id,
|
|
1093
|
+
}) as EventInvocation<MessageCore>
|
|
1094
|
+
const step = (index: number): Effect.Effect<unknown, unknown, R> => {
|
|
1095
|
+
if (index === chain.length) return Effect.suspend(() => handler(message, context))
|
|
1096
|
+
return Effect.suspend(() => {
|
|
1097
|
+
let started: Deferred.Deferred<void> | undefined
|
|
1098
|
+
let finished = false
|
|
1099
|
+
const next: Effect.Effect<void, never, R> = Effect.suspend(() => {
|
|
1100
|
+
if (finished)
|
|
1101
|
+
return failed(
|
|
1102
|
+
outcome,
|
|
1103
|
+
Cause.fail(
|
|
1104
|
+
new ConfigurationError(
|
|
1105
|
+
"next",
|
|
1106
|
+
"Event middleware called next after it finished, so the rest of the chain did not run",
|
|
1107
|
+
{ hint: "Return or await the result of next inside the middleware" },
|
|
1108
|
+
),
|
|
1109
|
+
),
|
|
1110
|
+
message,
|
|
1111
|
+
)
|
|
1112
|
+
// A repeated call observes the same run instead of invoking the handler again
|
|
1113
|
+
if (started) return Deferred.await(started)
|
|
1114
|
+
const done = (started = Deferred.makeUnsafe<void>())
|
|
1115
|
+
return reported(step(index + 1), message, outcome).pipe(
|
|
1116
|
+
Effect.ensuring(Effect.sync(() => Deferred.doneUnsafe(done, Effect.void))),
|
|
1117
|
+
)
|
|
1118
|
+
})
|
|
1119
|
+
return Effect.exit(
|
|
1120
|
+
Effect.suspend(() => chain[index]!(invocation, next as Effect.Effect<void>)),
|
|
1121
|
+
).pipe(
|
|
1122
|
+
Effect.flatMap((exit) => {
|
|
1123
|
+
finished = true
|
|
1124
|
+
// A middleware that started next without awaiting it still holds this handler slot until the chain ends
|
|
1125
|
+
return started ? Deferred.await(started).pipe(Effect.andThen(exit)) : exit
|
|
1126
|
+
}),
|
|
1127
|
+
)
|
|
1128
|
+
})
|
|
1129
|
+
}
|
|
1130
|
+
return step(0)
|
|
1131
|
+
}
|
|
1132
|
+
/** Report one finished invocation to the application observer */
|
|
1133
|
+
const observeInvocation = (
|
|
1134
|
+
exit: Exit.Exit<unknown, unknown>,
|
|
1135
|
+
outcome: Outcome,
|
|
1136
|
+
context: EventContext,
|
|
1137
|
+
startedAt: number,
|
|
1138
|
+
) => {
|
|
1139
|
+
const logger = bus.logging?.()
|
|
1140
|
+
const cancelled = Exit.isFailure(exit) && Cause.hasInterrupts(exit.cause)
|
|
1141
|
+
const failure = cancelled ? undefined : outcome.failure
|
|
1142
|
+
emitObservation(logger, {
|
|
1143
|
+
type: "handler",
|
|
1144
|
+
event,
|
|
1145
|
+
...(outcome.command === undefined ? {} : { command: outcome.command }),
|
|
1146
|
+
subscriptionId: source.id,
|
|
1147
|
+
shardId: context.shardId,
|
|
1148
|
+
durationMs: performance.now() - startedAt,
|
|
1149
|
+
outcome: cancelled ? "cancelled" : failure ? "failure" : "success",
|
|
1150
|
+
...(failure ? failureFacts(primaryError(failure), logger?.secrets ?? []) : {}),
|
|
1151
|
+
})
|
|
1152
|
+
}
|
|
1153
|
+
let active = 0
|
|
1154
|
+
let capacity = Deferred.makeUnsafe<void>()
|
|
1155
|
+
// Replace the latch before releasing it. Completion resumes the waiting loop synchronously, and a loop
|
|
1156
|
+
// that found the completed latch again would spin
|
|
1157
|
+
const wake = () => {
|
|
1158
|
+
const released = capacity
|
|
1159
|
+
capacity = Deferred.makeUnsafe<void>()
|
|
1160
|
+
Deferred.doneUnsafe(released, Effect.void)
|
|
1161
|
+
}
|
|
1162
|
+
const partition = source.limits.partition
|
|
1163
|
+
/** Partition keys with a running invocation, so later events of the same key wait their turn */
|
|
1164
|
+
const busyKeys = new Set<string>()
|
|
1165
|
+
const worker = (delivery: Delivery<EventMap<M>[K]>) =>
|
|
1166
|
+
Effect.withFiber((fiber) => {
|
|
1167
|
+
const { message } = delivery
|
|
1168
|
+
const context = eventContext(delivery)
|
|
1169
|
+
const outcome: Outcome = { command, failure: undefined }
|
|
1170
|
+
const startedAt = observing(bus.logging?.()) ? performance.now() : undefined
|
|
1171
|
+
// Rejection records of this invocation wait for its outcome, so a failure is logged once
|
|
1172
|
+
const rejections = new RejectionScope()
|
|
1173
|
+
invocationOutcomes.set(rejections, outcome)
|
|
1174
|
+
const invocation = Effect.gen(function* () {
|
|
1175
|
+
bus.#handlerFibers.add(fiber.id)
|
|
1176
|
+
yield* Effect.scoped(Effect.suspend(() => invoke(message, context, outcome))).pipe(
|
|
1177
|
+
Effect.withSpan(
|
|
1178
|
+
command === undefined ? "fluxerly.event.handle" : "fluxerly.command.execute",
|
|
1179
|
+
{
|
|
1180
|
+
attributes: {
|
|
1181
|
+
"fluxerly.event": event,
|
|
1182
|
+
"fluxerly.subscription": source.id,
|
|
1183
|
+
...(command === undefined ? {} : { "fluxerly.command": command }),
|
|
1184
|
+
},
|
|
1185
|
+
},
|
|
1186
|
+
// The SDK-internal call site gives applications nothing, and capturing it costs every invocation
|
|
1187
|
+
{ captureStackTrace: false },
|
|
1188
|
+
),
|
|
1189
|
+
Effect.onExit((exit) =>
|
|
1190
|
+
Effect.sync(() => {
|
|
1191
|
+
source.recordCleanup(exit)
|
|
1192
|
+
}),
|
|
1193
|
+
),
|
|
1194
|
+
Effect.catchCause((cause) => {
|
|
1195
|
+
if (Cause.hasInterrupts(cause))
|
|
1196
|
+
return Effect.failCause(
|
|
1197
|
+
Cause.fromReasons(cause.reasons.filter((reason) => reason._tag !== "Fail")),
|
|
1198
|
+
)
|
|
1199
|
+
return failed(outcome, cause, message)
|
|
1200
|
+
}),
|
|
1201
|
+
)
|
|
1202
|
+
})
|
|
1203
|
+
return withRejectionScope(invocation, rejections).pipe(
|
|
1204
|
+
Effect.ensuring(Effect.sync(() => rejections.end())),
|
|
1205
|
+
Effect.onExit((exit) =>
|
|
1206
|
+
Effect.sync(() => {
|
|
1207
|
+
invocationOutcomes.delete(rejections)
|
|
1208
|
+
if (startedAt !== undefined) observeInvocation(exit, outcome, context, startedAt)
|
|
1209
|
+
}),
|
|
1210
|
+
),
|
|
1211
|
+
)
|
|
1212
|
+
})
|
|
1213
|
+
/** Release an invocation's slot and key. Runs as a fiber observer, so it also runs for a worker interrupted before it started */
|
|
1214
|
+
const finished = (fiberId: number, key: string | undefined) => {
|
|
1215
|
+
bus.#handlerFibers.delete(fiberId)
|
|
1216
|
+
active--
|
|
1217
|
+
if (key !== undefined) busyKeys.delete(key)
|
|
1218
|
+
bus.#invocationFinished()
|
|
1219
|
+
wake()
|
|
1220
|
+
}
|
|
1221
|
+
/** The partition key of a waiting event, computed once. A throwing or invalid partition function becomes the event's failure */
|
|
1222
|
+
const keyOf = (delivery: Delivery<EventMap<M>[K]>): string | { readonly failure: unknown } => {
|
|
1223
|
+
if (delivery.key !== undefined) return delivery.key
|
|
1224
|
+
let key: string | { readonly failure: unknown }
|
|
1225
|
+
try {
|
|
1226
|
+
const value = partitionKey(partition!, event, delivery.message)
|
|
1227
|
+
key =
|
|
1228
|
+
value === undefined
|
|
1229
|
+
? ""
|
|
1230
|
+
: typeof value === "string"
|
|
1231
|
+
? value
|
|
1232
|
+
: {
|
|
1233
|
+
failure: new ConfigurationError(
|
|
1234
|
+
"partition",
|
|
1235
|
+
"The partition function must return a string or undefined",
|
|
1236
|
+
),
|
|
1237
|
+
}
|
|
1238
|
+
} catch (error) {
|
|
1239
|
+
key = { failure: error }
|
|
1240
|
+
}
|
|
1241
|
+
delivery.key = key
|
|
1242
|
+
return key
|
|
1243
|
+
}
|
|
1244
|
+
// An event whose key is running waits, while a later event of another key can start before it
|
|
1245
|
+
const eligible = (delivery: Delivery<EventMap<M>[K]>) => {
|
|
1246
|
+
const key = keyOf(delivery)
|
|
1247
|
+
return typeof key !== "string" || !busyKeys.has(key)
|
|
1248
|
+
}
|
|
1249
|
+
// Allocate work only for received messages, not one idle fiber for every configured concurrency slot
|
|
1250
|
+
const program = Effect.scoped(
|
|
1251
|
+
Effect.gen(function* () {
|
|
1252
|
+
if (partition !== undefined) source.onArrival(wake)
|
|
1253
|
+
while (source.active) {
|
|
1254
|
+
if (active >= source.limits.concurrency) {
|
|
1255
|
+
yield* Deferred.await(capacity)
|
|
1256
|
+
continue
|
|
1257
|
+
}
|
|
1258
|
+
let delivery: Delivery<EventMap<M>[K]> | null | undefined
|
|
1259
|
+
let key: string | undefined
|
|
1260
|
+
if (partition === undefined) {
|
|
1261
|
+
delivery = yield* source.takeDelivery()
|
|
1262
|
+
if (delivery === null || !source.active) return
|
|
1263
|
+
} else {
|
|
1264
|
+
// Nothing can arrive or finish between this scan and the wait, so no wake-up is missed
|
|
1265
|
+
const latch = capacity
|
|
1266
|
+
delivery = source.takeFirst(eligible)
|
|
1267
|
+
if (delivery === undefined) {
|
|
1268
|
+
yield* Deferred.await(latch)
|
|
1269
|
+
continue
|
|
1270
|
+
}
|
|
1271
|
+
const selected = keyOf(delivery)
|
|
1272
|
+
if (typeof selected !== "string") {
|
|
1273
|
+
// The handler cannot run without a key, so the failure is reported in its place
|
|
1274
|
+
yield* report("handler", Cause.fail(selected.failure), delivery.message)
|
|
1275
|
+
bus.#signalProgress()
|
|
1276
|
+
continue
|
|
1277
|
+
}
|
|
1278
|
+
key = selected
|
|
1279
|
+
busyKeys.add(key)
|
|
1280
|
+
}
|
|
1281
|
+
active++
|
|
1282
|
+
bus.#running++
|
|
1283
|
+
const invocation = yield* Effect.forkScoped(
|
|
1284
|
+
worker(delivery).pipe(
|
|
1285
|
+
// allow-silent: The worker reports handler failures itself, so only interruption reaches this point
|
|
1286
|
+
Effect.catchCause(() => Effect.void),
|
|
1287
|
+
),
|
|
1288
|
+
)
|
|
1289
|
+
const selectedKey = key
|
|
1290
|
+
invocation.addObserver(() => finished(invocation.id, selectedKey))
|
|
1291
|
+
}
|
|
1292
|
+
}).pipe(Effect.onExit(() => Effect.sync(() => source.stop()))),
|
|
1293
|
+
).pipe(
|
|
1294
|
+
Effect.interruptible,
|
|
1295
|
+
Effect.onExit((exit) =>
|
|
1296
|
+
Effect.gen(function* () {
|
|
1297
|
+
source.stop()
|
|
1298
|
+
if (source.failure) yield* report("overflow", Cause.fail(source.failure))
|
|
1299
|
+
source.finish(exit)
|
|
1300
|
+
}),
|
|
1301
|
+
),
|
|
1302
|
+
// allow-silent: The source.finish call retains the subscription outcome for waitForClose
|
|
1303
|
+
Effect.catchCause(() => Effect.void),
|
|
1304
|
+
)
|
|
1305
|
+
// Effect.forkIn retains the registration caller's context, with no hidden native runPromise or detached runtime
|
|
1306
|
+
// Install closure before enabling interruption, including cancellation before the first fiber turn
|
|
1307
|
+
const fiber = yield* Effect.forkIn(program, scope, { uninterruptible: true })
|
|
1308
|
+
source.manage(() => fiber.interruptUnsafe())
|
|
1309
|
+
return source
|
|
1310
|
+
}),
|
|
1311
|
+
)
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
function openEventWait<K extends EventName, M extends MessageCore = Message>(
|
|
1316
|
+
bus: EventBus<M>,
|
|
1317
|
+
event: K,
|
|
1318
|
+
options?: EventWaitOptions<K, M>,
|
|
1319
|
+
allowSignal = false,
|
|
1320
|
+
): Effect.Effect<EventWaitSource<K, M>, RegistrationError> {
|
|
1321
|
+
return Clock.clockWith((clock) =>
|
|
1322
|
+
Effect.gen(function* () {
|
|
1323
|
+
const settings = yield* readInput(() => eventWaitSettings(options, allowSignal))
|
|
1324
|
+
if (settings instanceof ConfigurationError) return yield* Effect.fail(settings)
|
|
1325
|
+
// A one-shot wait on a closing client keeps its distinct ClientClosedError failure
|
|
1326
|
+
const source = yield* bus.open(event, settings.buffer, { whenClosed: "fail" })
|
|
1327
|
+
const now = nowMs(clock)
|
|
1328
|
+
return new EventWait(source, settings.filter, now + settings.timeoutMs, clock)
|
|
1329
|
+
}),
|
|
1330
|
+
)
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
/** One lazy wait. Its internal scope releases intake on completion, timeout, interruption or client shutdown */
|
|
1334
|
+
export function waitForEvent<K extends EventName, M extends MessageCore = Message>(
|
|
1335
|
+
bus: EventBus<M>,
|
|
1336
|
+
event: K,
|
|
1337
|
+
options?: EventWaitOptions<K, M>,
|
|
1338
|
+
allowSignal = false,
|
|
1339
|
+
): Effect.Effect<EventMap<M>[K], RegistrationError | EventWaitError | EventOverflowError> {
|
|
1340
|
+
return Effect.scoped(
|
|
1341
|
+
Effect.acquireRelease(openEventWait(bus, event, options, allowSignal), (source) =>
|
|
1342
|
+
Effect.sync(() => source.stop()),
|
|
1343
|
+
).pipe(Effect.flatMap((source) => source.wait())),
|
|
1344
|
+
)
|
|
1345
|
+
}
|