@seedcord/core 0.1.3 → 0.2.0-next.0
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/README.md +35 -5
- package/dist/{subscribers-nEpbJj3Z.mjs → Bus-DcuUtOEL.mjs} +401 -31
- package/dist/Bus-DcuUtOEL.mjs.map +1 -0
- package/dist/{HmrModuleHandler-KxRP8lqJ.mjs → HmrModuleHandler-9AUfKXRl.mjs} +2 -2
- package/dist/{HmrModuleHandler-KxRP8lqJ.mjs.map → HmrModuleHandler-9AUfKXRl.mjs.map} +1 -1
- package/dist/{Plugin-CDAV7P9l.mjs → Plugin-Bkeqcjy6.mjs} +12 -3
- package/dist/Plugin-Bkeqcjy6.mjs.map +1 -0
- package/dist/{Plugin-qRc7Ch4g.d.mts → Plugin-Cl5P7-PO.d.mts} +19 -7
- package/dist/{cursor-D207VrRo.mjs → cursor-B07ArwDz.mjs} +4 -4
- package/dist/cursor-B07ArwDz.mjs.map +1 -0
- package/dist/{cursor-C77xH5QT.d.mts → cursor-__0_F4rW.d.mts} +10 -3
- package/dist/hmr.index.mjs +1 -1
- package/dist/{index-C0k7lRDi.d.mts → index-TYnQ-ztr.d.mts} +15 -4
- package/dist/index.d.mts +24 -11
- package/dist/index.mjs +26 -6
- package/dist/index.mjs.map +1 -1
- package/dist/internal.index.d.mts +13 -18
- package/dist/internal.index.mjs +16 -48
- package/dist/internal.index.mjs.map +1 -1
- package/dist/node-internal.index.d.mts +6 -5
- package/dist/node-internal.index.mjs +54 -49
- package/dist/node-internal.index.mjs.map +1 -1
- package/dist/plugin.index.d.mts +1 -1
- package/dist/plugin.index.mjs +1 -1
- package/dist/subscribers-DuHg-bGT.mjs +3 -0
- package/package.json +27 -35
- package/dist/HmrModuleHandler-CxGOo1LT.cjs +0 -182
- package/dist/HmrModuleHandler-CxGOo1LT.cjs.map +0 -1
- package/dist/Plugin-CDAV7P9l.mjs.map +0 -1
- package/dist/Plugin-DVNh1kvX.cjs +0 -95
- package/dist/Plugin-DVNh1kvX.cjs.map +0 -1
- package/dist/cursor-D207VrRo.mjs.map +0 -1
- package/dist/cursor-DFgJ70_B.cjs +0 -1339
- package/dist/cursor-DFgJ70_B.cjs.map +0 -1
- package/dist/devChannel-Cdnmz6hd.cjs +0 -25
- package/dist/devChannel-Cdnmz6hd.cjs.map +0 -1
- package/dist/hmr.index.cjs +0 -4
- package/dist/hmr.index.d.cts +0 -1
- package/dist/index.cjs +0 -889
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -1
- package/dist/internal.index.cjs +0 -717
- package/dist/internal.index.cjs.map +0 -1
- package/dist/internal.index.d.cts +0 -1
- package/dist/node-internal.index.cjs +0 -799
- package/dist/node-internal.index.cjs.map +0 -1
- package/dist/node-internal.index.d.cts +0 -1
- package/dist/phases-8qiiLKjS.cjs +0 -42
- package/dist/phases-8qiiLKjS.cjs.map +0 -1
- package/dist/plugin.index.cjs +0 -4
- package/dist/plugin.index.d.cts +0 -1
- package/dist/publishDefault-BCrMG9T8.mjs +0 -273
- package/dist/publishDefault-BCrMG9T8.mjs.map +0 -1
- package/dist/publishDefault-D52iT8mF.cjs +0 -368
- package/dist/publishDefault-D52iT8mF.cjs.map +0 -1
- package/dist/slashRouteLeaves-HVl6Ymr0.cjs +0 -28
- package/dist/slashRouteLeaves-HVl6Ymr0.cjs.map +0 -1
- package/dist/subscribers-6x4xw39Z.cjs +0 -531
- package/dist/subscribers-6x4xw39Z.cjs.map +0 -1
- package/dist/subscribers-nEpbJj3Z.mjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"subscribers-nEpbJj3Z.mjs","names":[],"sources":["../src/subscribers/Subscriber.ts","../src/subscribers/bases/webhookHelpers.ts","../src/subscribers/bases/WebhookSender.ts","../src/subscribers/bases/WebhookLog.ts","../src/subscribers/decorators/Subscribe.ts","../src/subscribers/decorators/WebhookUrl.ts","../src/subscribers/default/HandledException.ts","../src/subscribers/default/UnknownException.ts","../src/subscribers/Bus.ts"],"sourcesContent":["import { Logger } from '@seedcord/logger';\n\nimport type { SubscriptionKey, AllSubscriptions } from './types/Subscriptions';\nimport type { CoreBase } from '@interfaces/CoreBase';\n\n/**\n * Abstract base class for handling application subscribers.\n *\n * Provides type-safe access to subscribers data and the core framework instance.\n * Extend this class to create custom subscriber handlers.\n *\n * @typeParam KeyOfSubscribers - The specific subscriber type this handler processes\n * @typeParam TCore - The transport's Core\n */\nexport abstract class Subscriber<KeyOfSubscribers extends SubscriptionKey, TCore extends CoreBase> {\n protected readonly logger: Logger;\n\n /**\n * Instantiates the subscriber with event data and core.\n *\n * @param data - The subscriber event data\n * @param core - The core framework instance\n */\n constructor(\n protected readonly data: AllSubscriptions[KeyOfSubscribers],\n protected readonly core: TCore\n ) {\n this.logger = new Logger(this.constructor.name, { channel: 'subscribers' });\n }\n\n /**\n * Executes the subscriber handler logic.\n */\n abstract execute(): Promise<void>;\n}\n","import { filterCirculars, stripAnsi } from '@seedcord/utils';\nimport { SeparatorSpacingSize } from 'discord-api-types/v10';\n\nimport { BuilderComponent } from '@components/Component';\n\nimport type { WebhookFile } from './WebhookSender';\n\nconst DISCORD_WEBHOOK_REGEX = new RegExp(\n String.raw`^https?:\\/\\/(?:canary\\.|ptb\\.)?discord(?:app)?\\.com\\/api\\/webhooks\\/\\d+\\/[\\w$-]+$`\n);\n\nexport function isDiscordWebhookUrl(value: string): boolean {\n return URL.canParse(value) && DISCORD_WEBHOOK_REGEX.test(value);\n}\n\nexport function jsonAttachment(name: string, description: string, data: unknown): WebhookFile {\n const content = filterCirculars(data);\n return { name, description, data: new TextEncoder().encode(JSON.stringify(content, undefined, 2)) };\n}\n\n// the report renders inside a ``` fence, so break any triple-backtick run to keep it from closing early\nexport function neutralizeFences(text: string): string {\n return text.replaceAll('```', '```');\n}\n\n// stack plus one level of cause, ansi codes stripped since discord won't render them\nexport function errorReport(error: Error): string {\n let report = error.stack ?? `${error.name}: ${error.message}`;\n if (Error.isError(error.cause)) {\n const cause = error.cause.stack ?? `${error.cause.name}: ${error.cause.message}`;\n report += `\\n\\nCaused by:\\n${cause}`;\n }\n const stripped = neutralizeFences(stripAnsi(report));\n // eslint-disable-next-line no-magic-numbers\n return stripped.length > 1800 ? `${stripped.slice(0, 1799)}…` : stripped;\n}\n\nexport class WebhookSeparator extends BuilderComponent<'separator'> {\n constructor() {\n super('separator');\n this.instance.setSpacing(SeparatorSpacingSize.Small).setDivider(true);\n }\n}\n","import { DiscordAPIError, REST } from '@discordjs/rest';\nimport { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { Routes } from 'discord-api-types/v10';\n\nimport type { ReplyFile } from '@seedcord/types';\nimport type { APIMessageTopLevelComponent } from 'discord-api-types/v10';\n\nconst HTTP_NOT_FOUND = 404;\nconst HTTP_UNAUTHORIZED = 401;\n\n/** A file attached to a webhook report. */\nexport interface WebhookFile extends ReplyFile {\n readonly description: string;\n}\n\nexport interface WebhookSendOptions {\n flags: number;\n username: string;\n components: readonly { toJSON(): APIMessageTopLevelComponent }[];\n files?: readonly WebhookFile[] | undefined;\n}\n\n// throws SeedcordError when the url has no webhook id and token\nexport class WebhookSender {\n private readonly rest = new REST();\n private readonly route: `/${string}`;\n\n constructor(url: string) {\n const match = /\\/webhooks\\/(\\d+)\\/([\\w$-]+)$/.exec(url);\n if (!match?.[1] || !match[2]) throw new SeedcordError(SeedcordErrorCode.ConfigWebhookUrlInvalid, ['The url']);\n this.route = Routes.webhook(match[1], match[2]);\n }\n\n // missing means discord answered 404 or 401\n async verify(): Promise<'ok' | 'missing' | 'unreachable'> {\n try {\n await this.rest.get(this.route, { auth: false });\n return 'ok';\n } catch (error) {\n const gone =\n error instanceof DiscordAPIError &&\n (error.status === HTTP_NOT_FOUND || error.status === HTTP_UNAUTHORIZED);\n return gone ? 'missing' : 'unreachable';\n }\n }\n\n async send(options: WebhookSendOptions): Promise<void> {\n const { flags, username, components, files } = options;\n await this.rest.post(this.route, {\n auth: false,\n // with_components=true makes discord accept a components-v2 payload. wait=true makes it\n // return payload errors in the response\n query: new URLSearchParams({ with_components: 'true', wait: 'true' }),\n body: {\n flags,\n username,\n components: components.map((component) => component.toJSON()),\n ...(files?.length && {\n attachments: files.map((file, id) => ({ id, filename: file.name, description: file.description }))\n })\n },\n ...(files?.length && { files: files.map((file) => ({ name: file.name, data: file.data })) })\n });\n }\n}\n","import { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport chalk from 'chalk';\nimport { Converters, Envapter } from 'envapt';\n\nimport { sendFlags } from '@reply/flags';\nimport { WebhookUrlMetadataKey } from '@src/metadataKeys';\n\nimport { Subscriber } from '../Subscriber';\nimport { isDiscordWebhookUrl } from './webhookHelpers';\nimport { WebhookSender } from './WebhookSender';\n\nimport type { WebhookFile } from './WebhookSender';\nimport type { SubscriptionKey } from '../types/Subscriptions';\nimport type { CoreBase } from '@interfaces/CoreBase';\nimport type { APIMessageTopLevelComponent } from 'discord-api-types/v10';\n\n/**\n * The content a reporter returns from {@link WebhookLog.report}.\n */\nexport interface WebhookReport {\n /** Shown as the webhook message author. Defaults to the reporter's class name. */\n username?: string;\n components: readonly { toJSON(): APIMessageTopLevelComponent }[];\n files?: readonly WebhookFile[] | undefined;\n}\n\n/**\n * Base class for subscribers that deliver their event to a Discord webhook.\n *\n * Declare the url's environment variable with `@WebhookUrl` and implement {@link report}. Url\n * resolution, validation, sender reuse, and sending run in the base. When the variable is unset\n * the reporter is skipped at registration with a boot warning.\n *\n * @typeParam KeyOfSubscribers - The subscription key this reporter receives\n * @typeParam TCore - The transport's Core\n */\nexport abstract class WebhookLog<KeyOfSubscribers extends SubscriptionKey, TCore extends CoreBase> extends Subscriber<\n KeyOfSubscribers,\n TCore\n> {\n private static readonly senders = new Map<string, WebhookSender>();\n\n /** Builds the message for one published event. */\n abstract report(): WebhookReport | Promise<WebhookReport>;\n\n async execute(): Promise<void> {\n const url = WebhookLog.urlOf(WebhookLog.envKeyOf(this.constructor));\n if (url === null) {\n // a server host skips url-less reporters at registration, an edge host registers lazily and reaches this branch\n this.logger.warn(`${chalk.bold(this.constructor.name)} has no webhook url set, this reporter is disabled`);\n return;\n }\n\n const { username, components, files } = await this.report();\n try {\n await WebhookLog.senderFor(url).send({\n flags: sendFlags({ ephemeral: false }),\n username: username ?? this.constructor.name,\n components,\n files\n });\n } catch (error) {\n this.logger.error('Failed to send webhook report', error);\n }\n }\n\n /** @internal */\n static senderFor(url: string): WebhookSender {\n let sender = WebhookLog.senders.get(url);\n if (!sender) {\n sender = new WebhookSender(url);\n WebhookLog.senders.set(url, sender);\n }\n return sender;\n }\n\n /** @internal */\n static envKeyOf(ctor: NewableFunction): string {\n const envKey = Reflect.getMetadata(WebhookUrlMetadataKey, ctor) as string | undefined;\n if (!envKey) throw new SeedcordError(SeedcordErrorCode.DecoratorWebhookUrlMissing, [ctor.name]);\n return envKey;\n }\n\n /** @internal Returns null when the env var is unset, throws when set but malformed. */\n static urlOf(envKey: string): string | null {\n if (!Envapter.has(envKey)) return null;\n const raw = Envapter.getRequired(envKey, Converters.String).trim();\n if (raw === '') return null;\n if (!isDiscordWebhookUrl(raw)) throw new SeedcordError(SeedcordErrorCode.ConfigWebhookUrlInvalid, [envKey]);\n return raw;\n }\n}\n","// the default reporters are decorated at Bus module load, before any entry's own polyfill import runs\nimport 'reflect-metadata';\n\nimport { SubscribeMetadataKey } from '@src/metadataKeys';\n\nimport type { Subscriber } from '../Subscriber';\nimport type { SubscriptionKey } from '../types/Subscriptions';\nimport type { CoreBase } from '@interfaces/CoreBase';\nimport type { EventFrequency } from '@seedcord/types';\nimport type { Constructor } from 'type-fest';\n\n/**\n * Options accepted by the `@Subscribe` decorator.\n */\nexport interface SubscribeOptions {\n /**\n * Frequency: `'once'` or `'on'`.\n *\n * @defaultValue `'on'`\n */\n readonly frequency?: EventFrequency | undefined;\n}\n\n/** @internal */\nexport interface SubscribeMetadataEntry {\n readonly subscriber: SubscriptionKey;\n readonly frequency?: EventFrequency | undefined;\n}\n\n/**\n * Registers a subscriber handler class with a specific subscriber event.\n *\n * Associates the decorated class with a subscriber event type for automatic\n * registration and execution when the subscriber is emitted.\n *\n * @typeParam TSubscriber - The subscriber event name to register for\n * @param subscriber - The subscriber event name to register for\n * @param options - Options to configure the subscriber handler registration.\n * @decorator\n * @example\n * ```typescript\n * \\@Subscribe('userJoin')\n * class WelcomeHandler extends Subscriber<'userJoin'> {\n * async execute() {\n * }\n * }\n * ```\n * @example\n * ```ts\n * \\@Subscribe('userJoin', { frequency: 'once' })\n * // or\n * \\@Subscribe('userJoin')\n * ```\n */\nexport function Subscribe<TSubscriber extends SubscriptionKey>(subscriber: TSubscriber, options?: SubscribeOptions) {\n return function <HandlerCtor extends Constructor<Subscriber<TSubscriber, CoreBase>>>(\n constructor: HandlerCtor\n ): void {\n const meta: SubscribeMetadataEntry = {\n subscriber,\n frequency: options?.frequency\n };\n\n Reflect.defineMetadata(SubscribeMetadataKey, meta, constructor);\n };\n}\n","import 'reflect-metadata';\n\nimport { WebhookUrlMetadataKey } from '@src/metadataKeys';\n\nimport type { WebhookLog } from '../bases/WebhookLog';\nimport type { SubscriptionKey } from '../types/Subscriptions';\nimport type { CoreBase } from '@interfaces/CoreBase';\nimport type { Constructor } from 'type-fest';\n\n/**\n * Declares the environment variable a {@link WebhookLog} reporter reads its webhook url from.\n *\n * An unset variable disables the reporter with a boot warning. A set but malformed value throws\n * at boot.\n *\n * @param envKey - The environment variable name holding the webhook url\n * @decorator\n * @example\n * ```ts\n * \\@Subscribe('memberBanned')\n * \\@WebhookUrl('BAN_LOG_WEBHOOK_URL')\n * class BanLog extends WebhookLog<'memberBanned'> {\n * report() {\n * return { components: [new BanCard(this.data).component] };\n * }\n * }\n * ```\n */\nexport function WebhookUrl(envKey: string) {\n return function <HandlerCtor extends Constructor<WebhookLog<SubscriptionKey, CoreBase>>>(\n constructor: HandlerCtor\n ): void {\n Reflect.defineMetadata(WebhookUrlMetadataKey, envKey, constructor);\n };\n}\n","import { stripAnsi } from '@seedcord/utils';\n\nimport { BuilderComponent } from '@components/Component';\n\nimport { jsonAttachment, neutralizeFences, WebhookSeparator } from '../bases/webhookHelpers';\nimport { WebhookLog } from '../bases/WebhookLog';\nimport { Subscribe } from '../decorators/Subscribe';\nimport { WebhookUrl } from '../decorators/WebhookUrl';\n\nimport type { WebhookReport } from '../bases/WebhookLog';\nimport type { AllSubscriptions, FaultSource } from '../types/Subscriptions';\nimport type { CoreBase } from '@interfaces/CoreBase';\nimport type { Notice } from '@stops/Notice';\n\n// FaultThrottle drops repeat faults before they reach this subscriber\n// no HANDLED_EXCEPTION_WEBHOOK_URL disables the reporter with a boot warning\n@Subscribe('handledException')\n@WebhookUrl('HANDLED_EXCEPTION_WEBHOOK_URL')\nexport class HandledException extends WebhookLog<'handledException', CoreBase> {\n report(): WebhookReport {\n return {\n username: 'Handled Exception',\n components: [new HandledExceptionContainer(this.data).component],\n files: [jsonAttachment('source.json', 'The raw source the fault came from', this.data.source.raw)]\n };\n }\n}\n\nclass HandledExceptionContainer extends BuilderComponent<'container'> {\n constructor(data: AllSubscriptions['handledException']) {\n super('container');\n\n const { denial, uuid, source } = data;\n\n this.instance\n .addTextDisplayComponents((text) => text.setContent(faultSummary(denial, source)))\n .addSeparatorComponents(new WebhookSeparator().component)\n .addTextDisplayComponents((text) =>\n text.setContent(`### UUID \\`${uuid}\\`\\n\\`\\`\\`${neutralizeFences(causeStack(denial))}\\`\\`\\``)\n )\n .addSeparatorComponents(new WebhookSeparator().component)\n .addTextDisplayComponents((text) => text.setContent('### Source'))\n .addFileComponents((file) => file.setURL('attachment://source.json'));\n }\n}\n\nfunction faultSummary(denial: Notice, source: FaultSource): string {\n // name and message carry chalk codes that the webhook payload would otherwise render raw\n const head = stripAnsi(`### A handled fault was reported: \\`${denial.name}\\`\\n**Message:** ${denial.message}\\n`);\n if (source.kind === 'event') {\n return (\n `${head}**Event:** ${source.eventName}\\n` +\n `**Handler:** ${source.handler}\\n` +\n `**User ID:** \\`${source.userId ?? 'n/a'}\\`\\n` +\n `**Guild ID:** \\`${source.guildId ?? 'n/a'}\\`\\n` +\n `**Channel ID:** \\`${source.channelId ?? 'n/a'}\\``\n );\n }\n return (\n `${head}**Kind:** ${source.interactionKind}\\n` +\n `**Command:** ${source.command ?? 'n/a'}\\n` +\n `**CustomId:** ${source.customId ?? 'n/a'}\\n` +\n `**User ID:** \\`${source.userId}\\`\\n` +\n `**Guild ID:** \\`${source.guildId ?? 'n/a'}\\`\\n` +\n `**Channel ID:** \\`${source.channelId ?? 'n/a'}\\`\\n` +\n `**Interaction ID:** \\`${source.interactionId}\\``\n );\n}\n\n// every cause shape returns a string, so building the report never throws on a bigint or circular cause\nfunction causeStack(denial: Notice): string {\n const { cause } = denial;\n if (Error.isError(cause)) return stripAnsi(cause.stack ?? cause.message);\n if (typeof cause === 'string') return stripAnsi(cause);\n if (typeof cause === 'bigint' || typeof cause === 'symbol' || typeof cause === 'function') return cause.toString();\n if (cause !== undefined) {\n try {\n return JSON.stringify(cause);\n } catch {\n return '[unserializable cause]';\n }\n }\n return stripAnsi(denial.stack ?? 'No cause recorded.');\n}\n","import { DiscordAPIError } from '@discordjs/rest';\nimport { timestampFromSnowflake } from '@seedcord/utils';\n\nimport { BuilderComponent } from '@components/Component';\n\nimport { errorReport, jsonAttachment, WebhookSeparator } from '../bases/webhookHelpers';\nimport { WebhookLog } from '../bases/WebhookLog';\nimport { Subscribe } from '../decorators/Subscribe';\nimport { WebhookUrl } from '../decorators/WebhookUrl';\n\nimport type { WebhookReport } from '../bases/WebhookLog';\nimport type { AllSubscriptions } from '../types/Subscriptions';\nimport type { CoreBase } from '@interfaces/CoreBase';\n\n// no UNKNOWN_EXCEPTION_WEBHOOK_URL disables the reporter with a boot warning\n@Subscribe('unknownException')\n@WebhookUrl('UNKNOWN_EXCEPTION_WEBHOOK_URL')\nexport class UnknownException extends WebhookLog<'unknownException', CoreBase> {\n report(): WebhookReport {\n const { metadata } = this.data;\n return {\n username: 'Unknown Exception',\n components: [new UnhandledErrorContainer(this.data).component],\n files: metadata\n ? [jsonAttachment('metadata.json', 'Metadata associated with the error', metadata)]\n : undefined\n };\n }\n}\n\nclass UnhandledErrorContainer extends BuilderComponent<'container'> {\n constructor(data: AllSubscriptions['unknownException']) {\n super('container');\n\n const { uuid, error, guild, user, metadata } = data;\n\n this.instance\n .addTextDisplayComponents((text) =>\n text.setContent(\n `### An unknown exception was thrown\\n` +\n `**Guild ID:** \\`${guild?.id ?? 'Not used in a guild'}\\`\\n` +\n `**Guild Name:** ${guild?.name ?? 'Not used in a guild'}\\n` +\n `**User ID:** \\`${user?.id ?? 'Missing user info'}\\`\\n` +\n `**Username:** ${user?.username ?? 'Missing user info'}\\n`\n )\n )\n .addSeparatorComponents(new WebhookSeparator().component)\n .addTextDisplayComponents((text) =>\n text.setContent(`### UUID \\`${uuid}\\`\\n\\`\\`\\`${errorReport(error)}\\`\\`\\``)\n );\n\n this.addTimestampsIfAvailable(error);\n this.addMetadataIfAvailable(metadata);\n }\n\n private addTimestampsIfAvailable(error: Error): void {\n if (!(error instanceof DiscordAPIError)) return;\n\n const now = Date.now();\n\n const snowflake = error.url.match(/\\/interactions\\/(\\d+)\\//)?.[1];\n if (!snowflake) return undefined;\n\n const interactionTs = timestampFromSnowflake(snowflake);\n\n const diff = now - interactionTs;\n const seconds = Math.floor(diff / 1000);\n const millis = diff % 1000;\n\n this.instance\n .addSeparatorComponents(new WebhookSeparator().component)\n .addTextDisplayComponents((text) =>\n text.setContent(\n `### Timestamps\\n` +\n `- **\\`Interaction sent\\` :** ${new Date(interactionTs).toISOString()} (${interactionTs})\\n` +\n `- **\\`Error logged \\` :** ${new Date(now).toISOString()} (${now})\\n` +\n `- **\\`Offset \\` :** ${seconds}s ${millis}ms`\n )\n );\n }\n\n private addMetadataIfAvailable(metadata: unknown): void {\n if (!metadata) return;\n\n this.instance\n .addSeparatorComponents(new WebhookSeparator().component)\n .addTextDisplayComponents((text) => text.setContent('### Metadata'))\n .addFileComponents((file) => file.setURL('attachment://metadata.json'));\n }\n}\n","import { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\nimport { TypedEventEmitter } from '@seedcord/event-emitter';\nimport { Logger, paint } from '@seedcord/logger';\nimport chalk from 'chalk';\n\nimport { SubscribeMetadataKey } from '@src/metadataKeys';\n\nimport { WebhookLog } from './bases/WebhookLog';\nimport { HandledException } from './default/HandledException';\nimport { UnknownException } from './default/UnknownException';\nimport { PublishDefault } from './publishDefault';\n\nimport type { SubscribeMetadataEntry } from './decorators/Subscribe';\nimport type { Subscriber } from './Subscriber';\nimport type {\n AllSubscriptions,\n DefaultSubscriptions,\n PublishableKey,\n SubscriptionKey,\n SubscriptionTuples\n} from './types/Subscriptions';\nimport type { CoreBase } from '@interfaces/CoreBase';\nimport type { EventFrequency } from '@seedcord/types';\n\n/**\n * Both parameters are `never` because construct-signature parameters check contravariantly, and a\n * concrete subscriber narrows each to its own payload and transport `Core`. One cast at dispatch\n * restores both.\n *\n * @internal\n */\nexport type StoredSubscriberCtor = new (data: never, core: never) => Subscriber<SubscriptionKey, CoreBase>;\n\n/**\n * `resolve` is lazy so an edge host registers from a manifest row without importing the module\n * until that key first publishes.\n *\n * @internal\n */\nexport interface SubscriberRegistration {\n readonly keys: readonly SubscriptionKey[];\n readonly frequency: EventFrequency;\n readonly resolve: () => StoredSubscriberCtor | Promise<StoredSubscriberCtor>;\n /** A server-host registration carries it from the start. A lazy one fills it on first resolve. */\n ctor?: StoredSubscriberCtor | undefined;\n}\n\n/**\n * Registers and dispatches subscribers. Subscribers run on a programmatic or framework publish.\n * Accessed via `core.bus`. Do not construct it directly.\n */\nexport class Bus extends TypedEventEmitter<SubscriptionTuples> {\n /** @internal */\n public readonly logger = new Logger('Subscribers', { channel: 'subscribers' });\n\n private readonly subscribersMap = new Map<SubscriptionKey, SubscriberRegistration[]>();\n private readonly executedOnce = new Set<SubscriberRegistration>();\n // url -> env keys, filled as reporters register and read once by verifyWebhooks\n private readonly webhookProbes = new Map<string, string[]>();\n\n constructor(protected core: CoreBase) {\n super();\n }\n\n /** @internal the host calls this during startup, keeping the url validation inside `start()` where a failure can still release the singleton guard. */\n public registerDefaults(): void {\n this.register(registrationFor(UnknownException));\n this.register(registrationFor(HandledException));\n }\n\n /** @internal */\n public register(registration: SubscriberRegistration): void {\n // a url-less reporter never registers. a publish on its key reaches nothing\n if (registration.ctor && !this.probeWebhook(registration.ctor)) return;\n\n for (const key of registration.keys) {\n let registrations = this.subscribersMap.get(key);\n if (!registrations) {\n registrations = [];\n this.subscribersMap.set(key, registrations);\n }\n registrations.push(registration);\n }\n }\n\n /** @internal */\n public unregister(ctor: StoredSubscriberCtor, keys?: readonly SubscriptionKey[]): void {\n for (const key of keys ?? [...this.subscribersMap.keys()]) {\n const registrations = this.subscribersMap.get(key);\n if (!registrations) continue;\n const index = registrations.findIndex((entry) => entry.ctor === ctor);\n if (index !== -1) registrations.splice(index, 1);\n }\n // the once state hangs off the registration identity, which is why a restored subscriber runs again\n }\n\n /** @internal */\n public get registeredCount(): number {\n return [...this.subscribersMap.values()].reduce((total, entries) => total + entries.length, 0);\n }\n\n /** @internal Only eagerly registered reporters are probed, which is every server-host one. */\n public async verifyWebhooks(): Promise<void> {\n const missing: string[] = [];\n await Promise.all(\n [...this.webhookProbes].map(async ([url, envKeys]) => {\n const result = await WebhookLog.senderFor(url).verify();\n if (result === 'missing') missing.push(...envKeys);\n else if (result === 'unreachable')\n this.logger.warn(`could not verify webhook at ${paint.sky.bold(envKeys.join(', '))}`);\n })\n );\n // collected first so the first boot names every missing webhook at once\n if (missing.length > 0) throw new SeedcordError(SeedcordErrorCode.ConfigWebhookNotFound, [missing.join(', ')]);\n }\n\n // true means the class registers\n private probeWebhook(ctor: StoredSubscriberCtor): boolean {\n if (!(ctor.prototype instanceof WebhookLog)) return true;\n\n const envKey = WebhookLog.envKeyOf(ctor);\n const url = WebhookLog.urlOf(envKey);\n if (url === null) {\n this.logger.warn(`${chalk.bold(ctor.name)} disabled, ${paint.sky.bold(envKey)} is not set`);\n return false;\n }\n const envKeys = this.webhookProbes.get(url) ?? [];\n if (!envKeys.includes(envKey)) envKeys.push(envKey);\n this.webhookProbes.set(url, envKeys);\n return true;\n }\n\n /**\n * Publishes an event to its subscribers and native listeners.\n *\n * Fire-and-forget. Subscriber handlers run asynchronously and this returns before they finish. A\n * caller cannot assume a side effect has completed. Errors thrown by a subscriber or by an `on()`\n * listener are caught and logged, never surfaced here. One throwing listener does not stop the\n * others. Subscribers on one key run concurrently and carry no ordering guarantee. A `'once'`\n * subscriber is marked as executed when it starts, even if it throws. It never runs twice.\n *\n * The framework's own keys are excluded. Subscribe to those and listen with `on`. The framework\n * is their only publisher.\n *\n * @param event - The subscription key to publish\n * @param data - Payload passed to each subscriber\n * @returns Whether the underlying emitter had native listeners for the event\n */\n public publish<KeyOfSubscribers extends PublishableKey>(\n event: KeyOfSubscribers,\n data: AllSubscriptions[KeyOfSubscribers]\n ): boolean {\n return this.dispatchKey(event, data);\n }\n\n /** @internal the framework's own publish path, keyed by a symbol no public entry exports */\n public [PublishDefault]<KeyOfSubscribers extends keyof DefaultSubscriptions>(\n event: KeyOfSubscribers,\n data: AllSubscriptions[KeyOfSubscribers]\n ): boolean {\n return this.dispatchKey(event, data);\n }\n\n private dispatchKey<KeyOfSubscribers extends SubscriptionKey>(\n event: KeyOfSubscribers,\n data: AllSubscriptions[KeyOfSubscribers]\n ): boolean {\n void this.processSubscriber(event, data);\n // justified: a generic key can't reduce SubscriptionTuples[K], but data is this event's payload by the signature\n return this.emitSafe(event, ...([data] as SubscriptionTuples[KeyOfSubscribers]));\n }\n\n protected override onListenerError(error: unknown, event: string | symbol): void {\n this.logger.error(`listener for ${String(event)} threw`, error);\n }\n\n private async processSubscriber<KeyOfSubscribers extends SubscriptionKey>(\n subscriberName: KeyOfSubscribers,\n data: AllSubscriptions[KeyOfSubscribers]\n ): Promise<void> {\n const registrations = this.subscribersMap.get(subscriberName);\n if (!registrations) return;\n\n const pending = registrations.reduce<Promise<void>[]>((acc, entry) => {\n if (entry.frequency === 'once') {\n if (this.executedOnce.has(entry)) return acc;\n // mark before awaiting, so a re-entrant publish can't run a 'once' subscriber twice mid-flight\n this.executedOnce.add(entry);\n }\n acc.push(this.runSubscriber(entry, subscriberName, data));\n return acc;\n }, []);\n\n await Promise.allSettled(pending);\n }\n\n private async runSubscriber<KeyOfSubscribers extends SubscriptionKey>(\n entry: SubscriberRegistration,\n subscriberName: KeyOfSubscribers,\n data: AllSubscriptions[KeyOfSubscribers]\n ): Promise<void> {\n // named outside the try so the catch can say which subscriber threw. several run per key\n let name = '<unresolved>';\n try {\n entry.ctor ??= await entry.resolve();\n // the registration keys each subscriber to its subscriptions, so data matches this ctor's payload arm\n const Ctor = entry.ctor as new (\n data: AllSubscriptions[KeyOfSubscribers],\n core: CoreBase\n ) => Subscriber<KeyOfSubscribers, CoreBase>;\n name = Ctor.name;\n await new Ctor(data, this.core).execute();\n } catch (err) {\n this.logger.error(`Error in subscriber ${String(subscriberName)} handler ${paint.sky.bold(name)}:`, err);\n }\n }\n}\n\n// every caller has already gated on the Subscribe metadata being there\n/** @internal */\nexport function registrationFor(ctor: StoredSubscriberCtor): SubscriberRegistration {\n const meta = Reflect.getMetadata(SubscribeMetadataKey, ctor) as SubscribeMetadataEntry;\n return { keys: [meta.subscriber], frequency: meta.frequency ?? 'on', resolve: () => ctor, ctor };\n}\n"],"mappings":"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"}
|