@seedcord/core 0.1.1-next.0 → 0.1.2
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/dist/HmrModuleHandler-CxGOo1LT.cjs.map +1 -1
- package/dist/HmrModuleHandler-KxRP8lqJ.mjs.map +1 -1
- package/dist/Plugin-CDAV7P9l.mjs.map +1 -1
- package/dist/Plugin-DVNh1kvX.cjs.map +1 -1
- package/dist/{Plugin-BPz0obbN.d.mts → Plugin-qRc7Ch4g.d.mts} +22 -43
- package/dist/{basic-CeSFvbaz.d.mts → basic-Dng__Ena.d.mts} +2 -2
- package/dist/{contextMenuLeaves-CC3-qObq.d.mts → contextMenuLeaves-COzDYa6c.d.mts} +4 -5
- package/dist/{cursor-Bk-W5MTq.d.mts → cursor-C77xH5QT.d.mts} +30 -52
- package/dist/{cursor-Y6ct-N_8.mjs → cursor-D207VrRo.mjs} +20 -44
- package/dist/cursor-D207VrRo.mjs.map +1 -0
- package/dist/{cursor-D2iP-CCS.cjs → cursor-DFgJ70_B.cjs} +20 -44
- package/dist/cursor-DFgJ70_B.cjs.map +1 -0
- package/dist/{index-Dm0WKN37.d.mts → index-C0k7lRDi.d.mts} +3 -14
- package/dist/index.cjs +17 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +21 -24
- package/dist/index.mjs +17 -22
- package/dist/index.mjs.map +1 -1
- package/dist/internal.index.cjs +10 -48
- package/dist/internal.index.cjs.map +1 -1
- package/dist/internal.index.d.mts +15 -62
- package/dist/internal.index.mjs +10 -48
- package/dist/internal.index.mjs.map +1 -1
- package/dist/node-internal.index.cjs +3 -76
- package/dist/node-internal.index.cjs.map +1 -1
- package/dist/node-internal.index.d.mts +4 -76
- package/dist/node-internal.index.mjs +3 -76
- package/dist/node-internal.index.mjs.map +1 -1
- package/dist/plugin.index.d.mts +1 -1
- package/dist/{publishDefault-CldnxcT2.mjs → publishDefault-BCrMG9T8.mjs} +5 -19
- package/dist/publishDefault-BCrMG9T8.mjs.map +1 -0
- package/dist/{publishDefault-CVlwYUS5.cjs → publishDefault-D52iT8mF.cjs} +5 -19
- package/dist/publishDefault-D52iT8mF.cjs.map +1 -0
- package/dist/{slashRouteLeaves-BANDtPFm.mjs → slashRouteLeaves-De1SxqnX.mjs} +4 -4
- package/dist/slashRouteLeaves-De1SxqnX.mjs.map +1 -0
- package/dist/{slashRouteLeaves-nfxOAM7Q.cjs → slashRouteLeaves-HVl6Ymr0.cjs} +4 -4
- package/dist/slashRouteLeaves-HVl6Ymr0.cjs.map +1 -0
- package/dist/{subscribers-CDbep0RH.cjs → subscribers-6x4xw39Z.cjs} +8 -26
- package/dist/subscribers-6x4xw39Z.cjs.map +1 -0
- package/dist/{subscribers-xO6DZ-70.mjs → subscribers-nEpbJj3Z.mjs} +8 -26
- package/dist/subscribers-nEpbJj3Z.mjs.map +1 -0
- package/package.json +9 -9
- package/dist/cursor-D2iP-CCS.cjs.map +0 -1
- package/dist/cursor-Y6ct-N_8.mjs.map +0 -1
- package/dist/publishDefault-CVlwYUS5.cjs.map +0 -1
- package/dist/publishDefault-CldnxcT2.mjs.map +0 -1
- package/dist/slashRouteLeaves-BANDtPFm.mjs.map +0 -1
- package/dist/slashRouteLeaves-nfxOAM7Q.cjs.map +0 -1
- package/dist/subscribers-CDbep0RH.cjs.map +0 -1
- package/dist/subscribers-xO6DZ-70.mjs.map +0 -1
package/dist/internal.index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_publishDefault = require('./publishDefault-
|
|
3
|
-
const require_cursor = require('./cursor-
|
|
2
|
+
const require_publishDefault = require('./publishDefault-D52iT8mF.cjs');
|
|
3
|
+
const require_cursor = require('./cursor-DFgJ70_B.cjs');
|
|
4
4
|
const require_devChannel = require('./devChannel-Cdnmz6hd.cjs');
|
|
5
|
-
const require_slashRouteLeaves = require('./slashRouteLeaves-
|
|
5
|
+
const require_slashRouteLeaves = require('./slashRouteLeaves-HVl6Ymr0.cjs');
|
|
6
6
|
require("reflect-metadata");
|
|
7
7
|
let _discordjs_builders = require("@discordjs/builders");
|
|
8
8
|
let _seedcord_logger = require("@seedcord/logger");
|
|
@@ -27,11 +27,6 @@ async function timedCheck(gate, ctx, observe) {
|
|
|
27
27
|
observe(gate.name, performance.now() - start);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
/**
|
|
31
|
-
* Runs each gate's check in order, so the first refusal propagates to the dispatcher boundary. An effect
|
|
32
|
-
* gate's commit runs once the whole set passes. When `observe` is given, each check is timed and reported,
|
|
33
|
-
* commits excluded.
|
|
34
|
-
*/
|
|
35
30
|
async function runGates(gates, ctx, observe) {
|
|
36
31
|
try {
|
|
37
32
|
for (const gate of gates) await (observe ? timedCheck(gate, ctx, observe) : require_cursor.runCheck(gate, ctx));
|
|
@@ -77,18 +72,13 @@ function slowGateMonitor() {
|
|
|
77
72
|
|
|
78
73
|
//#endregion
|
|
79
74
|
//#region src/miscellaneous/emojiConfig.ts
|
|
80
|
-
/** Narrows a configured emoji value to the `[name, guildId]` form. @internal */
|
|
81
75
|
function isEmojiTuple(value) {
|
|
82
76
|
return Array.isArray(value) && value.length === 2 && typeof value[0] === "string" && typeof value[1] === "string";
|
|
83
77
|
}
|
|
84
78
|
|
|
85
79
|
//#endregion
|
|
86
80
|
//#region src/hmr/wrapHot.ts
|
|
87
|
-
/**
|
|
88
|
-
* Wraps a raw vite hot object as a typed {@link DevChannel}.
|
|
89
|
-
*
|
|
90
|
-
* @internal
|
|
91
|
-
*/
|
|
81
|
+
/** @internal */
|
|
92
82
|
function wrapHot(hot) {
|
|
93
83
|
return {
|
|
94
84
|
send: (event, data) => hot.send(event, data),
|
|
@@ -209,7 +199,6 @@ const SEND_TARGET = {
|
|
|
209
199
|
"deferred-update": "followUp",
|
|
210
200
|
replied: "followUp"
|
|
211
201
|
};
|
|
212
|
-
/** Throws before any API call. `ackedBy` becomes the throw cause, its stack points at the first ack. */
|
|
213
202
|
function checkAckLegality(method, state, routeId, ackedBy) {
|
|
214
203
|
if (method === "send") return;
|
|
215
204
|
const illegal = ILLEGAL[method][state];
|
|
@@ -227,7 +216,6 @@ function sendTarget(state) {
|
|
|
227
216
|
|
|
228
217
|
//#endregion
|
|
229
218
|
//#region src/reply/AckTrace.ts
|
|
230
|
-
/** The first ack's stack, passed as the throw cause so a double-ack points to both lines. */
|
|
231
219
|
var AckTrace = class extends Error {
|
|
232
220
|
constructor(method) {
|
|
233
221
|
super(`${method}() acknowledged this interaction`);
|
|
@@ -256,11 +244,6 @@ function publishResponse(telemetry, report) {
|
|
|
256
244
|
});
|
|
257
245
|
logger$1().trace(`${_seedcord_logger.paint.mint.bold(report.routeId)} ${report.method} ${report.outcome} ${_seedcord_logger.paint.mute("in")} ${Math.round(durationMs)}ms`);
|
|
258
246
|
}
|
|
259
|
-
/**
|
|
260
|
-
* Runs a write that returns no message and publishes whichever arm it takes.
|
|
261
|
-
*
|
|
262
|
-
* @internal
|
|
263
|
-
*/
|
|
264
247
|
async function reportedWrite(telemetry, routeId, method, write) {
|
|
265
248
|
const startedAt = performance.now();
|
|
266
249
|
const result = await attemptWrite(telemetry, routeId, method, startedAt, write);
|
|
@@ -273,12 +256,6 @@ async function reportedWrite(telemetry, routeId, method, write) {
|
|
|
273
256
|
});
|
|
274
257
|
return result;
|
|
275
258
|
}
|
|
276
|
-
/**
|
|
277
|
-
* Runs a wire write and publishes the `failed` arm when it throws, since the caller's success report
|
|
278
|
-
* sits after the write and a throw skips it.
|
|
279
|
-
*
|
|
280
|
-
* @internal
|
|
281
|
-
*/
|
|
282
259
|
async function attemptWrite(telemetry, routeId, method, startedAt, write) {
|
|
283
260
|
try {
|
|
284
261
|
return await write();
|
|
@@ -392,10 +369,6 @@ function detailOf(value, depth) {
|
|
|
392
369
|
}
|
|
393
370
|
return describeLeaf(record);
|
|
394
371
|
}
|
|
395
|
-
/**
|
|
396
|
-
* Translates a shapeshift throw into an actionable message, keeping the original as `cause`. Any other
|
|
397
|
-
* throw contributes its message as the detail.
|
|
398
|
-
*/
|
|
399
372
|
function translateSerializationError(error, componentClass, index, routeId) {
|
|
400
373
|
const detail = detailOf(error, 0);
|
|
401
374
|
return new _seedcord_errors_internal.SeedcordError(_seedcord_errors.SeedcordErrorCode.ReplyComponentSerialization, [
|
|
@@ -408,7 +381,6 @@ function translateSerializationError(error, componentClass, index, routeId) {
|
|
|
408
381
|
|
|
409
382
|
//#endregion
|
|
410
383
|
//#region src/reply/serializeReply.ts
|
|
411
|
-
/** Wraps a string in a TextDisplay component. */
|
|
412
384
|
function serializeReply(response, routeId) {
|
|
413
385
|
if (typeof response === "string") try {
|
|
414
386
|
return { components: [new _discordjs_builders.TextDisplayBuilder().setContent(response).toJSON()] };
|
|
@@ -433,9 +405,9 @@ function serializeReply(response, routeId) {
|
|
|
433
405
|
//#region src/reply/BaseReplySender.ts
|
|
434
406
|
/**
|
|
435
407
|
* Tracks acknowledgement state and throws a translated `SeedcordError` on an illegal verb before any
|
|
436
|
-
* transport call.
|
|
437
|
-
* state and ack trace. Each transport binds `TMessage` to its created-message
|
|
438
|
-
* writers.
|
|
408
|
+
* transport call. Every verb runs the legality check, calls the transport's wire writer, then updates
|
|
409
|
+
* the state and the ack trace. Each transport binds `TMessage` to its own created-message type and
|
|
410
|
+
* supplies the writers.
|
|
439
411
|
*/
|
|
440
412
|
var BaseReplySender = class {
|
|
441
413
|
routeId;
|
|
@@ -484,7 +456,7 @@ var BaseReplySender = class {
|
|
|
484
456
|
this.report("deferUpdate", startedAt, "sent", null);
|
|
485
457
|
}
|
|
486
458
|
/**
|
|
487
|
-
* After a deferUpdate the state stays deferred-update
|
|
459
|
+
* After a deferUpdate the state stays deferred-update. Calling this again rewrites. The returned message
|
|
488
460
|
* is the source message, editable only through a bare `update` or `edit`. A targeted `edit` or `delete`
|
|
489
461
|
* of it throws the foreign-target error.
|
|
490
462
|
*/
|
|
@@ -597,21 +569,12 @@ var BaseReplySender = class {
|
|
|
597
569
|
|
|
598
570
|
//#endregion
|
|
599
571
|
//#region src/subscribers/FaultThrottle.ts
|
|
600
|
-
/**
|
|
601
|
-
* Drops duplicate fault reports inside a fixed window, so a recurring fault (a database outage on a
|
|
602
|
-
* hot path) reports once per window and never floods the webhook.
|
|
603
|
-
*
|
|
604
|
-
* @internal
|
|
605
|
-
*/
|
|
572
|
+
/** @internal */
|
|
606
573
|
var FaultThrottle = class FaultThrottle {
|
|
607
574
|
windowMs;
|
|
608
575
|
now;
|
|
609
576
|
static perCore = /* @__PURE__ */ new WeakMap();
|
|
610
|
-
/**
|
|
611
|
-
* The throttle for one bot instance.
|
|
612
|
-
*
|
|
613
|
-
* @internal
|
|
614
|
-
*/
|
|
577
|
+
/** @internal */
|
|
615
578
|
static for(core) {
|
|
616
579
|
let throttle = FaultThrottle.perCore.get(core);
|
|
617
580
|
if (!throttle) {
|
|
@@ -625,7 +588,6 @@ var FaultThrottle = class FaultThrottle {
|
|
|
625
588
|
this.windowMs = windowMs;
|
|
626
589
|
this.now = now;
|
|
627
590
|
}
|
|
628
|
-
/** Evicts the entry for this key if it has aged out. */
|
|
629
591
|
shouldReport(key) {
|
|
630
592
|
const last = this.lastReportedAt.get(key);
|
|
631
593
|
if (last === void 0) return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal.index.cjs","names":["InteractionRouteKeys","runCheck","runCommits","GatedMetadataKey","logger","Logger","Envapter","paint","Logger","Envapter","paint","SeedcordError","SeedcordErrorCode","logger","Logger","PublishDefault","paint","SeedcordError","SeedcordErrorCode","TextDisplayBuilder","SeedcordError","SeedcordErrorCode","Logger","Silence","Notice","timestampFromSnowflake","PublishDefault","paint"],"sources":["../src/gates/runGates.ts","../src/gates/slowGate.ts","../src/miscellaneous/emojiConfig.ts","../src/hmr/wrapHot.ts","../src/hmr/HmrManager.ts","../src/stops/asError.ts","../src/reply/ackLegality.ts","../src/reply/AckTrace.ts","../src/reply/responseReport.ts","../src/reply/translateSerialization.ts","../src/reply/serializeReply.ts","../src/reply/BaseReplySender.ts","../src/subscribers/FaultThrottle.ts","../src/dispatch/dispatchReport.ts"],"sourcesContent":["import 'reflect-metadata';\n\nimport { GatedMetadataKey, InteractionRouteKeys } from '@src/metadataKeys';\n\nimport { discardCommits, runCheck, runCommits } from './effects';\n\nimport type { Gate, GateContextBase } from './Gate';\n\n/**\n * Receives each gate's name and how long its check ran, in ms. A combinator (`and`/`or`) reports once\n * under its joined name.\n */\nexport type GateObserver = (gateName: string, elapsedMs: number) => void;\n\n// the stable id a route decorator stored, e.g. slash:daily or button:confirm. null for a plain event handler.\nexport function routeIdOf(handlerCtor: object): string | null {\n for (const [kind, key] of Object.entries(InteractionRouteKeys)) {\n // justified: getMetadata returns any, this key only ever stores the route/prefix string array\n const routes = Reflect.getMetadata(key, handlerCtor) as string[] | undefined;\n if (routes?.length) return `${kind}:${routes.join(',')}`;\n }\n return null;\n}\n\nasync function timedCheck(gate: Gate<GateContextBase>, ctx: GateContextBase, observe: GateObserver): Promise<void> {\n const start = performance.now();\n // finally so a refusing gate still reports\n try {\n await runCheck(gate, ctx);\n } finally {\n observe(gate.name, performance.now() - start);\n }\n}\n\n/**\n * Runs each gate's check in order, so the first refusal propagates to the dispatcher boundary. An effect\n * gate's commit runs once the whole set passes. When `observe` is given, each check is timed and reported,\n * commits excluded.\n */\nexport async function runGates(\n gates: readonly Gate<GateContextBase>[],\n ctx: GateContextBase,\n observe?: GateObserver\n): Promise<void> {\n try {\n for (const gate of gates) {\n await (observe ? timedCheck(gate, ctx, observe) : runCheck(gate, ctx));\n }\n await runCommits(ctx);\n } finally {\n discardCommits(ctx);\n }\n}\n\n// dispatchers call this before execute, inside the boundary, so a refusal renders or drops. the\n// explicit routeId overrides the ctor-derived id for manifest-driven handlers with no route metadata.\nexport async function runHandlerGates(\n handlerCtor: object,\n ctx: GateContextBase,\n routeId?: string,\n observe?: GateObserver\n): Promise<void> {\n // justified: getMetadata returns any, and this key only ever stores the @Gated gate array\n const gates = Reflect.getMetadata(GatedMetadataKey, handlerCtor) as readonly Gate<GateContextBase>[] | undefined;\n if (!gates) return;\n await runGates(gates, { ...ctx, routeId: routeId ?? routeIdOf(handlerCtor) }, observe);\n}\n","import { Logger, paint } from '@seedcord/logger';\nimport { Envapter } from 'envapt';\n\nimport type { GateObserver } from './runGates';\n\n// combined check time slower than this cuts into the 3s interaction-ack budget\nconst SLOW_GATE_MS = 750;\n\n// lazy because the logger reads the environment, which binds after this module loads\nlet gateLogger: Logger | undefined;\nfunction logger(): Logger {\n gateLogger ??= new Logger('Gates', { channel: 'gates' });\n return gateLogger;\n}\n\n/**\n * Collects each gate check's elapsed time for one dispatch. `report` warns once when the checks sum\n * past the threshold, naming the total, the route, and each gate's share.\n */\nexport interface SlowGateMonitor {\n readonly observe: GateObserver;\n report(routeId: string | null): void;\n}\n\n// undefined in production, so timedCheck skips the clock there. read per call, the environment binds late\nexport function slowGateMonitor(): SlowGateMonitor | undefined {\n if (Envapter.isProduction) return undefined;\n const readings: { name: string; ms: number }[] = [];\n return {\n observe: (name, ms) => readings.push({ name, ms }),\n report(routeId) {\n const total = readings.reduce((sum, reading) => sum + reading.ms, 0);\n if (total < SLOW_GATE_MS) return;\n const shares = readings\n .toSorted((a, b) => b.ms - a.ms)\n .map((reading) => `${paint.sky.bold(reading.name)} ${Math.round(reading.ms)}ms`);\n const route = routeId === null ? '' : ` for ${paint.sky.bold(routeId)}`;\n const headline = `gates${route} took ${paint.amber(`${Math.round(total)}ms`)} of the 3s ack budget`;\n logger().utils.block(headline, shares, 'warn', (text) => text);\n }\n };\n}\n","/** Narrows a configured emoji value to the `[name, guildId]` form. @internal */\nexport function isEmojiTuple(value: unknown): value is readonly [string, string] {\n return Array.isArray(value) && value.length === 2 && typeof value[0] === 'string' && typeof value[1] === 'string';\n}\n","import type { DevChannel } from '@seedcord/types/internal';\n\n// the minimal raw-hot shape, satisfied by both vite's `import.meta.hot` and the CLI's `NormalizedHotChannel`.\ninterface RawHot {\n send(event: string, data?: unknown): void;\n on(event: string, cb: (data: unknown) => void): void;\n}\n\n/**\n * Wraps a raw vite hot object as a typed {@link DevChannel}.\n *\n * @internal\n */\nexport function wrapHot<TSend, TRecv>(hot: RawHot): DevChannel<TSend, TRecv> {\n return {\n send: (event, data) => hot.send(event, data),\n // justified: RawHot types every payload as unknown, the wire contract guarantees it matches TRecv[Key]\n on: (event, cb) => hot.on(event, cb as (data: unknown) => void)\n };\n}\n","// scoped here so import.meta.hot stays untyped in the rest of the package\n/// <reference types=\"vite/client\" />\nimport { Logger, paint } from '@seedcord/logger';\nimport { Envapter } from 'envapt';\n\nimport { setDevChannel } from './devChannel';\nimport { wrapHot } from './wrapHot';\n\nimport type { HmrAware, HmrUpdateEvent } from '@seedcord/types';\nimport type { SeedcordCliEvents, SeedcordFrameworkEvents } from '@seedcord/types/internal';\n\nexport class HmrManager {\n private readonly logger = new Logger('HMR', { channel: 'hmr' });\n private readonly listeners = new Set<HmrAware>();\n\n /** @internal */\n public init(): void {\n if (!import.meta.hot) return;\n // the only raw `import.meta.hot` read in the framework\n const channel = wrapHot<SeedcordFrameworkEvents, SeedcordCliEvents>(import.meta.hot);\n setDevChannel(channel);\n\n if (Envapter.isDevelopment || Envapter.isTest) {\n this.logger.debug('Enabled');\n channel.on('seedcord:hmr', (payload) => void this.handleUpdate(payload));\n }\n }\n\n /** @internal */\n public register(listener: HmrAware): void {\n this.listeners.add(listener);\n }\n\n /** @internal */\n public unregister(listener: HmrAware): void {\n this.listeners.delete(listener);\n }\n\n private async handleUpdate(event: HmrUpdateEvent): Promise<void> {\n const promises = [...this.listeners].map(async (listener) => {\n try {\n await listener.onHmr(event);\n } catch (error) {\n this.logger.error(`Error handling HMR update in ${paint.sky.bold(listener.constructor.name)}`, error);\n }\n });\n\n await Promise.all(promises);\n }\n}\n","// dropping a non-Error throw would leave the user with no fault card, and every report payload declares an Error\n/** @internal */\nexport function asError(caught: unknown): Error {\n return Error.isError(caught) ? caught : new Error(String(caught), { cause: caught });\n}\n","import { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport type { AckTrace } from './AckTrace';\n\nexport type AckState = 'unacked' | 'deferred-reply' | 'deferred-update' | 'replied';\n\nexport type ReplyMethod =\n 'reply' | 'defer' | 'deferUpdate' | 'update' | 'followUp' | 'edit' | 'delete' | 'send' | 'showModal';\n\ninterface Illegal {\n // spliced into the message after \"was called when\"\n readonly reason: string;\n readonly alternative: string;\n}\n\nconst showModalReason: Illegal = {\n reason: 'this interaction was already acknowledged',\n alternative: 'showModal() must be the initial response.'\n};\n\nfunction deferReason(what: string): Illegal {\n return {\n reason: `this interaction was already acknowledged with ${what}`,\n alternative: 'A deferral can only be the initial response.'\n };\n}\n\n// a missing entry means legal in that state\nconst ILLEGAL: Record<Exclude<ReplyMethod, 'send'>, Partial<Record<AckState, Illegal>>> = {\n reply: {\n 'deferred-reply': {\n reason: 'this interaction was already deferred',\n alternative: 'Use edit() to fill the deferred reply or followUp() for a new message.'\n },\n 'deferred-update': {\n reason: 'this interaction was already acknowledged with a deferred update',\n alternative: 'Use followUp() for a new message.'\n },\n replied: {\n reason: 'this interaction was already replied to',\n alternative: 'Use followUp() for a new message or edit() to rewrite the reply.'\n }\n },\n defer: {\n 'deferred-reply': deferReason('a deferred reply'),\n 'deferred-update': deferReason('a deferred update'),\n replied: deferReason('a reply')\n },\n deferUpdate: {\n 'deferred-reply': deferReason('a deferred reply'),\n 'deferred-update': deferReason('a deferred update'),\n replied: deferReason('a reply')\n },\n update: {\n 'deferred-reply': {\n reason: 'this interaction was deferred as a reply',\n alternative: 'The placeholder is yours via edit(). update() rewrites a source message.'\n },\n replied: {\n reason: 'this interaction was already replied to',\n alternative: 'update() rewrites a source message. Use edit() or followUp() instead.'\n }\n },\n followUp: {\n unacked: {\n reason: 'this interaction has not been acknowledged yet',\n alternative: 'Ack first with reply() or defer().'\n }\n },\n edit: {\n unacked: {\n reason: 'nothing has been sent yet',\n alternative: 'Send with reply() or defer() first, then edit() rewrites it.'\n }\n },\n delete: {\n unacked: {\n reason: 'nothing has been sent yet',\n alternative: 'Acknowledge first with reply() or defer(), then delete() removes it.'\n }\n },\n showModal: {\n 'deferred-reply': showModalReason,\n 'deferred-update': showModalReason,\n replied: showModalReason\n }\n};\n\nconst SEND_TARGET: Record<AckState, 'reply' | 'edit' | 'followUp'> = {\n unacked: 'reply',\n 'deferred-reply': 'edit',\n 'deferred-update': 'followUp',\n replied: 'followUp'\n};\n\n/** Throws before any API call. `ackedBy` becomes the throw cause, its stack points at the first ack. */\nexport function checkAckLegality(method: ReplyMethod, state: AckState, routeId: string, ackedBy?: AckTrace): void {\n if (method === 'send') return;\n const illegal = ILLEGAL[method][state];\n if (!illegal) return;\n throw new SeedcordError(\n SeedcordErrorCode.ReplyIllegalAckState,\n [method, illegal.reason, illegal.alternative, routeId],\n { cause: ackedBy }\n );\n}\n\nexport function sendTarget(state: AckState): 'reply' | 'edit' | 'followUp' {\n return SEND_TARGET[state];\n}\n","import type { ReplyMethod } from './ackLegality';\n\n/** The first ack's stack, passed as the throw cause so a double-ack points to both lines. */\nexport class AckTrace extends Error {\n public constructor(method: ReplyMethod) {\n super(`${method}() acknowledged this interaction`);\n this.name = 'AckTrace';\n }\n}\n","import { Logger, paint } from '@seedcord/logger';\n\nimport { asError } from '@stops/asError';\nimport { PublishDefault } from '@subscribers/publishDefault';\n\nimport type { ReplyMethod } from './ackLegality';\nimport type { Bus } from '@subscribers/Bus';\nimport type { ResponseOutcome } from '@subscribers/types/Subscriptions';\n\nlet replyLogger: Logger | undefined;\nfunction logger(): Logger {\n replyLogger ??= new Logger('Reply', { channel: 'interactions' });\n return replyLogger;\n}\n\n/** The bus a write publishes on, and the interaction it belongs to. */\nexport interface ReplyTelemetry {\n readonly bus: Bus;\n readonly interactionId: string;\n}\n\n/** The reply verbs plus the autocomplete choices callback, which runs outside the ack state machine. */\nexport type WriteMethod = ReplyMethod | 'respond';\n\n/** What one write reports once it settles. */\nexport interface ResponseReport {\n readonly routeId: string;\n readonly method: WriteMethod;\n /** `performance.now()` captured before the write began. */\n readonly startedAt: number;\n readonly outcome: ResponseOutcome;\n readonly messageId: string | null;\n readonly error?: Error;\n}\n\n/** @internal */\nexport function publishResponse(telemetry: ReplyTelemetry, report: ResponseReport): void {\n const durationMs = performance.now() - report.startedAt;\n telemetry.bus[PublishDefault]('responseAttempted', {\n routeId: report.routeId,\n interactionId: telemetry.interactionId,\n method: report.method,\n outcome: report.outcome,\n durationMs,\n messageId: report.messageId,\n ...(report.error && { error: report.error })\n });\n\n // after publish so a throwing sink doesn't reach the publish above\n logger().trace(\n `${paint.mint.bold(report.routeId)} ${report.method} ${report.outcome} ${paint.mute('in')} ${Math.round(durationMs)}ms`\n );\n}\n\n/**\n * Runs a write that returns no message and publishes whichever arm it takes.\n *\n * @internal\n */\nexport async function reportedWrite<Result>(\n telemetry: ReplyTelemetry,\n routeId: string,\n method: WriteMethod,\n write: () => Promise<Result>\n): Promise<Result> {\n const startedAt = performance.now();\n const result = await attemptWrite(telemetry, routeId, method, startedAt, write);\n publishResponse(telemetry, { routeId, method, startedAt, outcome: 'sent', messageId: null });\n return result;\n}\n\n/**\n * Runs a wire write and publishes the `failed` arm when it throws, since the caller's success report\n * sits after the write and a throw skips it.\n *\n * @internal\n */\nexport async function attemptWrite<Result>(\n telemetry: ReplyTelemetry,\n routeId: string,\n method: WriteMethod,\n startedAt: number,\n write: () => Promise<Result>\n): Promise<Result> {\n try {\n return await write();\n } catch (caught) {\n const error = asError(caught);\n publishResponse(telemetry, { routeId, method, startedAt, outcome: 'failed', messageId: null, error });\n // rethrown raw, so the caller catches the value the write threw\n throw caught;\n }\n}\n","import { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\n// shapeshift aggregate errors nest, the cap bounds the recursion\nconst MAX_DEPTH = 8;\n\ninterface ShapeshiftLike {\n readonly message?: unknown;\n readonly errors?: unknown;\n readonly constraint?: unknown;\n readonly validator?: unknown;\n readonly expected?: unknown;\n readonly given?: unknown;\n}\n\nconst OPERATOR_WORD: Record<string, string> = {\n '<=': 'at most',\n '>=': 'at least',\n '<': 'fewer than',\n '>': 'more than'\n};\n\nconst KIND_WORD: Record<string, string> = {\n string: 'a string',\n number: 'a number',\n boolean: 'a boolean',\n bigint: 'a bigint',\n array: 'a list',\n tuple: 'a list',\n date: 'a date',\n object: 'an object'\n};\n\nfunction asRecord(value: unknown): ShapeshiftLike | null {\n return typeof value === 'object' && value !== null ? value : null;\n}\n\nfunction firstLine(message: unknown): string {\n if (typeof message !== 'string') return 'unknown validation failure';\n return message.split('\\n')[0] ?? message;\n}\n\n// strings over this limit render as a character count\nconst GIVEN_PREVIEW_LIMIT = 40;\n\nfunction gotPhrase(given: unknown): string {\n if (given === undefined) return 'nothing';\n if (given === null) return 'null';\n if (typeof given === 'string') {\n if (given.length === 0) return 'an empty string';\n if (given.length > GIVEN_PREVIEW_LIMIT) return `${given.length} characters`;\n return JSON.stringify(given);\n }\n if (Array.isArray(given)) return given.length === 0 ? 'an empty list' : `${given.length} items`;\n if (typeof given === 'number' || typeof given === 'bigint' || typeof given === 'boolean') return String(given);\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- a null-prototype value has no constructor at runtime\n if (typeof given === 'object') return given.constructor?.name ?? 'an object';\n return typeof given;\n}\n\n// shapeshift constraint strings take the form 'expected.length >= 1' or 'expected <= 16777215'\nfunction needPhrase(expected: string, given: unknown): string | null {\n const bounds = [...expected.matchAll(/expected(\\.length)?\\s*(<=|>=|<|>)\\s*(\\d+)/g)];\n if (bounds.length === 0) return null;\n const phrases = bounds.map(([, lengthPart, operator, limit]) => {\n const word = OPERATOR_WORD[operator ?? ''] ?? operator ?? '';\n if (!lengthPart) return `${word} ${limit}`;\n const unit = typeof given === 'string' ? 'character' : 'item';\n return `${word} ${limit} ${Number(limit) === 1 ? unit : `${unit}s`}`;\n });\n return phrases.join(' and ');\n}\n\nfunction instanceName(expected: unknown): string {\n if (typeof expected === 'function' && expected.name) return expected.name;\n return 'specific class instance';\n}\n\nfunction describeLeaf(record: ShapeshiftLike): string {\n if (typeof record.constraint === 'string') {\n const need = typeof record.expected === 'string' ? needPhrase(record.expected, record.given) : null;\n if (need) return `need ${need}, got ${gotPhrase(record.given)}`;\n return `${firstLine(record.message)}${'given' in record ? ` (got ${gotPhrase(record.given)})` : ''}`;\n }\n if (typeof record.expected === 'function') {\n return `need a ${instanceName(record.expected)}, got ${gotPhrase(record.given)}`;\n }\n if (typeof record.validator === 'string') {\n const kind = KIND_WORD[record.validator.replace(/^s\\./, '').replace(/\\(.*$/, '')];\n if (kind) return `need ${kind}, got ${gotPhrase(record.given)}`;\n return `${firstLine(record.message)}, got ${gotPhrase(record.given)}`;\n }\n return firstLine(record.message);\n}\n\n// a concrete bound is picked first, then accepted instance classes, then the first branch\nfunction describeUnion(branches: unknown[], depth: number): string {\n const records: ShapeshiftLike[] = [];\n for (const branch of branches) {\n const record = asRecord(branch);\n if (record) records.push(record);\n }\n const bounded = records.find((record) => typeof record.constraint === 'string');\n if (bounded) return describeLeaf(bounded);\n\n const names: string[] = [];\n let allInstances = records.length > 0;\n for (const record of records) {\n if (typeof record.expected === 'function') names.push(instanceName(record.expected));\n else allInstances = false;\n }\n if (allInstances) {\n return `need a ${[...new Set(names)].join(' or ')}, got ${gotPhrase(records[0]?.given)}`;\n }\n return detailOf(branches[0], depth + 1);\n}\n\n// shapeshift nests errors as [key, inner] tuples\nfunction detailOf(value: unknown, depth: number): string {\n const record = asRecord(value);\n if (!record || depth >= MAX_DEPTH) return firstLine(record?.message);\n\n if (Array.isArray(record.errors) && record.errors.length > 0) {\n const errors = record.errors as unknown[];\n const [first] = errors;\n if (Array.isArray(first)) {\n const [key, inner] = first as [unknown, unknown];\n return `${String(key)}: ${detailOf(inner, depth + 1)}`;\n }\n return describeUnion(errors, depth);\n }\n\n return describeLeaf(record);\n}\n\n/**\n * Translates a shapeshift throw into an actionable message, keeping the original as `cause`. Any other\n * throw contributes its message as the detail.\n */\nexport function translateSerializationError(\n error: unknown,\n componentClass: string,\n index: number,\n routeId: string\n): SeedcordError<SeedcordErrorCode.ReplyComponentSerialization> {\n const detail = detailOf(error, 0);\n return new SeedcordError(SeedcordErrorCode.ReplyComponentSerialization, [componentClass, index, detail, routeId], {\n cause: error\n });\n}\n","import { TextDisplayBuilder } from '@discordjs/builders';\n\nimport { translateSerializationError } from './translateSerialization';\n\nimport type { ReplyResponse } from '@seedcord/types';\nimport type { APIMessageTopLevelComponent } from 'discord-api-types/v10';\n\n/** Serialized message data the transport wire writers consume. */\nexport interface SerializedReply<TNative = never> {\n readonly components: APIMessageTopLevelComponent[];\n readonly allowedMentions?: ReplyResponse['allowedMentions'];\n readonly files?: ReplyResponse<TNative>['files'];\n}\n\n/** Wraps a string in a TextDisplay component. */\nexport function serializeReply<TNative>(\n response: ReplyResponse<TNative> | string,\n routeId: string\n): SerializedReply<TNative> {\n if (typeof response === 'string') {\n try {\n return { components: [new TextDisplayBuilder().setContent(response).toJSON()] };\n } catch (error) {\n throw translateSerializationError(error, 'TextDisplayBuilder', 0, routeId);\n }\n }\n\n const components = response.components.map((component, index) => {\n try {\n return component.toJSON();\n } catch (error) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- a null-prototype value has no constructor at runtime\n const name = component.constructor?.name;\n throw translateSerializationError(error, !name || name === 'Object' ? 'component' : name, index, routeId);\n }\n });\n\n return {\n components,\n ...(response.allowedMentions && { allowedMentions: response.allowedMentions }),\n ...(response.files && { files: response.files })\n };\n}\n","import { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { checkAckLegality, sendTarget } from './ackLegality';\nimport { AckTrace } from './AckTrace';\nimport { attemptWrite, publishResponse } from './responseReport';\nimport { serializeReply } from './serializeReply';\nimport { translateSerializationError } from './translateSerialization';\n\nimport type { AckState, ReplyMethod } from './ackLegality';\nimport type { ReplyTelemetry } from './responseReport';\nimport type { SerializedReply } from './serializeReply';\nimport type { DeferOpts, ReplyResponse, SendOpts } from '@seedcord/types';\nimport type { ResponseOutcome } from '@subscribers/types/Subscriptions';\nimport type { APIModalInteractionResponseCallbackData } from 'discord-api-types/v10';\n\n/** The shape djs modal builders emit from `toJSON()`. */\nexport interface ModalLike {\n toJSON(): APIModalInteractionResponseCallbackData;\n}\n\n/**\n * Tracks acknowledgement state and throws a translated `SeedcordError` on an illegal verb before any\n * transport call. Verbs execute the legality check, control the transport wire writer, then update the\n * state and ack trace. Each transport binds `TMessage` to its created-message lens and supplies the\n * writers.\n */\nexport abstract class BaseReplySender<TMessage extends { id: string }, TNative = never> {\n private state: AckState;\n // the only ids a targeted edit accepts\n private readonly sent = new Set<string>();\n // the cause carries the first ack's stack so a double-ack reports both lines\n private ackedBy?: AckTrace;\n\n protected constructor(\n protected readonly routeId: string,\n private readonly telemetry: ReplyTelemetry,\n initialState: AckState = 'unacked'\n ) {\n this.state = initialState;\n }\n\n private report(method: ReplyMethod, startedAt: number, outcome: ResponseOutcome, messageId: string | null): void {\n publishResponse(this.telemetry, { routeId: this.routeId, method, startedAt, outcome, messageId });\n }\n\n private async attempt<Result>(\n method: ReplyMethod,\n startedAt: number,\n write: () => Promise<Result>\n ): Promise<Result> {\n return await attemptWrite(this.telemetry, this.routeId, method, startedAt, write);\n }\n\n public async reply(response: ReplyResponse<TNative> | string, opts?: SendOpts): Promise<TMessage> {\n this.checkLegality('reply');\n const startedAt = performance.now();\n const created = await this.attempt('reply', startedAt, () => this.writeReply(response, opts));\n // the callback already acked discord, so record replied before the message guard can throw\n this.transition('reply', 'replied');\n const message = this.remember(this.requireMessage(created, 'reply'));\n this.report('reply', startedAt, 'sent', message.id);\n return message;\n }\n\n public async defer(opts?: DeferOpts): Promise<void> {\n this.checkLegality('defer');\n const startedAt = performance.now();\n await this.attempt('defer', startedAt, () => this.writeDefer(opts));\n this.transition('defer', 'deferred-reply');\n this.report('defer', startedAt, 'sent', null);\n }\n\n public async deferUpdate(): Promise<void> {\n this.checkLegality('deferUpdate');\n const startedAt = performance.now();\n await this.attempt('deferUpdate', startedAt, () => this.writeDeferUpdate());\n this.transition('deferUpdate', 'deferred-update');\n this.report('deferUpdate', startedAt, 'sent', null);\n }\n\n /**\n * After a deferUpdate the state stays deferred-update, so the rewrite repeats. The returned message\n * is the source message, editable only through a bare `update` or `edit`. A targeted `edit` or `delete`\n * of it throws the foreign-target error.\n */\n public async update(response: ReplyResponse<TNative> | string): Promise<TMessage> {\n this.checkLegality('update');\n const startedAt = performance.now();\n // in deferred-update the source message is @original and the ack-legality check above already passed\n if (this.state === 'deferred-update') {\n const edited = await this.attempt('update', startedAt, () => this.editOriginal(response));\n this.report('update', startedAt, 'sent', edited.id);\n return edited;\n }\n const created = await this.attempt('update', startedAt, () => this.writeUpdate(response));\n this.transition('update', 'replied');\n const message = this.remember(this.requireMessage(created, 'update'));\n this.report('update', startedAt, 'sent', message.id);\n return message;\n }\n\n public async followUp(response: ReplyResponse<TNative> | string, opts?: SendOpts): Promise<TMessage> {\n this.checkLegality('followUp');\n const startedAt = performance.now();\n const created = await this.attempt('followUp', startedAt, () => this.writeFollowUp(response, opts));\n const message = this.remember(created);\n this.report('followUp', startedAt, 'sent', message.id);\n return message;\n }\n\n public edit(response: ReplyResponse<TNative> | string): Promise<TMessage>;\n public edit(target: TMessage, response: ReplyResponse<TNative> | string): Promise<TMessage>;\n public async edit(\n targetOrResponse: TMessage | ReplyResponse<TNative> | string,\n maybeResponse?: ReplyResponse<TNative> | string\n ): Promise<TMessage> {\n this.checkLegality('edit');\n const startedAt = performance.now();\n if (maybeResponse === undefined) {\n // justified: the overloads narrow targetOrResponse to a response once maybeResponse is absent\n const edited = await this.attempt('edit', startedAt, () =>\n this.editOriginal(targetOrResponse as ReplyResponse<TNative> | string)\n );\n this.report('edit', startedAt, 'sent', edited.id);\n return edited;\n }\n // justified: the overloads narrow targetOrResponse to a target message once maybeResponse is defined\n const target = targetOrResponse as TMessage;\n if (!this.sent.has(target.id)) {\n throw new SeedcordError(SeedcordErrorCode.ReplyForeignEditTarget, ['edit', target.id, this.routeId]);\n }\n const written = await this.attempt('edit', startedAt, () => this.writeEditTarget(target.id, maybeResponse));\n const message = this.remember(written);\n this.report('edit', startedAt, 'sent', message.id);\n return message;\n }\n\n public delete(): Promise<void>;\n public delete(target: TMessage): Promise<void>;\n public async delete(target?: TMessage): Promise<void> {\n this.checkLegality('delete');\n const startedAt = performance.now();\n if (target === undefined) {\n await this.attempt('delete', startedAt, () => this.writeDeleteOriginal());\n this.report('delete', startedAt, 'sent', null);\n return;\n }\n if (!this.sent.has(target.id)) {\n throw new SeedcordError(SeedcordErrorCode.ReplyForeignEditTarget, ['delete', target.id, this.routeId]);\n }\n await this.attempt('delete', startedAt, () => this.writeDeleteTarget(target.id));\n // evict so a later targeted edit of this id throws foreign\n this.sent.delete(target.id);\n this.report('delete', startedAt, 'sent', null);\n }\n\n /** Routes to the verb the current ack state permits. Every state has a route, so the illegal-ack throw is unreachable. */\n public async send(response: ReplyResponse<TNative> | string, opts?: SendOpts): Promise<TMessage> {\n const target = sendTarget(this.state);\n if (target === 'reply') return await this.reply(response, opts);\n if (target === 'edit') return await this.edit(response);\n return await this.followUp(response, opts);\n }\n\n /** Must be the initial response. */\n public async showModal(modal: ModalLike): Promise<void> {\n this.checkLegality('showModal');\n this.guardModalSource();\n let data: APIModalInteractionResponseCallbackData;\n try {\n data = modal.toJSON();\n } catch (error) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- a null-prototype modal has no constructor at runtime\n const name = modal.constructor?.name;\n throw translateSerializationError(error, !name || name === 'Object' ? 'modal' : name, 0, this.routeId);\n }\n const startedAt = performance.now();\n await this.attempt('showModal', startedAt, () => this.writeModal(data));\n this.transition('showModal', 'replied');\n this.report('showModal', startedAt, 'sent', null);\n }\n\n protected serialize(response: ReplyResponse<TNative> | string): SerializedReply<TNative> {\n return serializeReply(response, this.routeId);\n }\n\n protected remember(created: TMessage): TMessage {\n this.sent.add(created.id);\n return created;\n }\n\n // a with_response callback always returns the created message, so this guards a wire-contract gap\n private requireMessage(created: TMessage | undefined, method: 'reply' | 'update'): TMessage {\n if (!created) throw new SeedcordError(SeedcordErrorCode.ReplyCallbackMissingMessage, [method, this.routeId]);\n return created;\n }\n\n private async editOriginal(response: ReplyResponse<TNative> | string): Promise<TMessage> {\n const edited = await this.writeEditOriginal(response);\n // after a deferUpdate the source message is @original, which this interaction did not send\n if (this.state !== 'deferred-update') this.remember(edited);\n return edited;\n }\n\n private checkLegality(method: ReplyMethod): void {\n checkAckLegality(method, this.state, this.routeId, this.ackedBy);\n }\n\n private transition(method: ReplyMethod, state: AckState): void {\n this.state = state;\n this.ackedBy = new AckTrace(method);\n }\n\n // gateway overrides this to reject a modal-submit source\n protected guardModalSource(): void {}\n\n protected abstract writeReply(\n response: ReplyResponse<TNative> | string,\n opts?: SendOpts\n ): Promise<TMessage | undefined>;\n protected abstract writeDefer(opts?: DeferOpts): Promise<void>;\n protected abstract writeDeferUpdate(): Promise<void>;\n protected abstract writeUpdate(response: ReplyResponse<TNative> | string): Promise<TMessage | undefined>;\n protected abstract writeFollowUp(response: ReplyResponse<TNative> | string, opts?: SendOpts): Promise<TMessage>;\n protected abstract writeEditOriginal(response: ReplyResponse<TNative> | string): Promise<TMessage>;\n protected abstract writeEditTarget(targetId: string, response: ReplyResponse<TNative> | string): Promise<TMessage>;\n protected abstract writeDeleteOriginal(): Promise<void>;\n protected abstract writeDeleteTarget(targetId: string): Promise<void>;\n protected abstract writeModal(data: APIModalInteractionResponseCallbackData): Promise<void>;\n}\n","/**\n * Drops duplicate fault reports inside a fixed window, so a recurring fault (a database outage on a\n * hot path) reports once per window and never floods the webhook.\n *\n * @internal\n */\nexport class FaultThrottle {\n // keyed by core so each bot gets its own window, and the entry is collected with the core\n private static readonly perCore = new WeakMap<object, FaultThrottle>();\n\n /**\n * The throttle for one bot instance.\n *\n * @internal\n */\n public static for(core: object): FaultThrottle {\n let throttle = FaultThrottle.perCore.get(core);\n if (!throttle) {\n throttle = new FaultThrottle();\n FaultThrottle.perCore.set(core, throttle);\n }\n return throttle;\n }\n\n private readonly lastReportedAt = new Map<string, number>();\n\n constructor(\n private readonly windowMs = 60_000,\n private readonly now: () => number = () => Date.now()\n ) {}\n\n /** Evicts the entry for this key if it has aged out. */\n public shouldReport(key: string): boolean {\n const last = this.lastReportedAt.get(key);\n if (last === undefined) return true;\n if (this.now() - last < this.windowMs) return false;\n\n this.lastReportedAt.delete(key);\n return true;\n }\n\n public markReported(key: string): void {\n this.lastReportedAt.set(key, this.now());\n }\n\n public clear(): void {\n this.lastReportedAt.clear();\n }\n}\n","import { Logger, paint } from '@seedcord/logger';\nimport { timestampFromSnowflake } from '@seedcord/utils';\n\nimport { Notice } from '@stops/Notice';\nimport { Silence } from '@stops/Silence';\nimport { PublishDefault } from '@subscribers/publishDefault';\n\nimport type { InteractionRoutes } from '@src/metadataKeys';\nimport type { Bus } from '@subscribers/Bus';\nimport type { DispatchOutcome } from '@subscribers/types/Subscriptions';\n\nlet dispatchLogger: Logger | undefined;\nfunction logger(): Logger {\n dispatchLogger ??= new Logger('Dispatch', { channel: 'interactions' });\n return dispatchLogger;\n}\n\n/**\n * Classifies a caught stop for `interactionDispatched` so a gate and a\n * handler label the same stop identically.\n *\n * @internal\n */\nexport function outcomeFor(caught: unknown): DispatchOutcome {\n if (caught instanceof Silence) return 'refused';\n if (caught instanceof Notice) return caught.report ? 'failed' : 'refused';\n return 'failed';\n}\n\n/** The values a dispatcher has once its handler chain settles. */\ninterface DispatchReport {\n readonly routeId: string;\n readonly interactionId: string;\n readonly kind: `${InteractionRoutes}`;\n readonly outcome: DispatchOutcome;\n /** True when no route matched and the unhandled default ran. */\n readonly fallback: boolean;\n /** `performance.now()` captured as the dispatch began. */\n readonly startedAt: number;\n /** {@link queuedMsFor} read at the same moment as `startedAt`. */\n readonly queuedMs: number;\n}\n\n/**\n * Discord's interaction creation to now, read from the snowflake. Called at dispatch entry, since\n * a later read would count the handler run into the queue time as well.\n *\n * @internal\n */\nexport function queuedMsFor(interactionId: string): number {\n // telemetry never breaks a dispatch, and BigInt() throws on a malformed id\n try {\n return Date.now() - timestampFromSnowflake(interactionId);\n } catch {\n return 0;\n }\n}\n\nexport function reportDispatch(bus: Bus, report: DispatchReport): void {\n const durationMs = performance.now() - report.startedAt;\n bus[PublishDefault]('interactionDispatched', {\n routeId: report.routeId,\n interactionId: report.interactionId,\n kind: report.kind,\n outcome: report.outcome,\n fallback: report.fallback,\n durationMs,\n queuedMs: report.queuedMs\n });\n\n // after publish so a throwing sink doesn't reach the publish above\n logger().trace(\n `${paint.mint.bold(report.routeId)} ${report.outcome} ${paint.mute('in')} ${Math.round(durationMs)}ms`\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"internal.index.cjs","names":["InteractionRouteKeys","runCheck","runCommits","GatedMetadataKey","logger","Logger","Envapter","paint","Logger","Envapter","paint","SeedcordError","SeedcordErrorCode","logger","Logger","PublishDefault","paint","SeedcordError","SeedcordErrorCode","TextDisplayBuilder","SeedcordError","SeedcordErrorCode","Logger","Silence","Notice","timestampFromSnowflake","PublishDefault","paint"],"sources":["../src/gates/runGates.ts","../src/gates/slowGate.ts","../src/miscellaneous/emojiConfig.ts","../src/hmr/wrapHot.ts","../src/hmr/HmrManager.ts","../src/stops/asError.ts","../src/reply/ackLegality.ts","../src/reply/AckTrace.ts","../src/reply/responseReport.ts","../src/reply/translateSerialization.ts","../src/reply/serializeReply.ts","../src/reply/BaseReplySender.ts","../src/subscribers/FaultThrottle.ts","../src/dispatch/dispatchReport.ts"],"sourcesContent":["import 'reflect-metadata';\n\nimport { GatedMetadataKey, InteractionRouteKeys } from '@src/metadataKeys';\n\nimport { discardCommits, runCheck, runCommits } from './effects';\n\nimport type { Gate, GateContextBase } from './Gate';\n\n// a combinator (`and`/`or`) reports once under its joined name.\nexport type GateObserver = (gateName: string, elapsedMs: number) => void;\n\n// the stable id a route decorator stored, e.g. slash:daily or button:confirm. null for a plain event handler.\nexport function routeIdOf(handlerCtor: object): string | null {\n for (const [kind, key] of Object.entries(InteractionRouteKeys)) {\n // justified: getMetadata returns any, this key only ever stores the route/prefix string array\n const routes = Reflect.getMetadata(key, handlerCtor) as string[] | undefined;\n if (routes?.length) return `${kind}:${routes.join(',')}`;\n }\n return null;\n}\n\nasync function timedCheck(gate: Gate<GateContextBase>, ctx: GateContextBase, observe: GateObserver): Promise<void> {\n const start = performance.now();\n // finally so a refusing gate still reports\n try {\n await runCheck(gate, ctx);\n } finally {\n observe(gate.name, performance.now() - start);\n }\n}\n\n// the first refusal throws out to the dispatcher boundary. an effect gate's commit runs once the\n// whole set passes, and observe never times the commit phase.\nexport async function runGates(\n gates: readonly Gate<GateContextBase>[],\n ctx: GateContextBase,\n observe?: GateObserver\n): Promise<void> {\n try {\n for (const gate of gates) {\n await (observe ? timedCheck(gate, ctx, observe) : runCheck(gate, ctx));\n }\n await runCommits(ctx);\n } finally {\n discardCommits(ctx);\n }\n}\n\n// dispatchers call this before execute, inside the boundary, so a refusal renders or drops. an explicit\n// routeId is for manifest-driven handlers, which carry no route metadata to derive one from.\nexport async function runHandlerGates(\n handlerCtor: object,\n ctx: GateContextBase,\n routeId?: string,\n observe?: GateObserver\n): Promise<void> {\n // justified: getMetadata returns any, and this key only ever stores the @Gated gate array\n const gates = Reflect.getMetadata(GatedMetadataKey, handlerCtor) as readonly Gate<GateContextBase>[] | undefined;\n if (!gates) return;\n await runGates(gates, { ...ctx, routeId: routeId ?? routeIdOf(handlerCtor) }, observe);\n}\n","import { Logger, paint } from '@seedcord/logger';\nimport { Envapter } from 'envapt';\n\nimport type { GateObserver } from './runGates';\n\n// combined check time slower than this cuts into the 3s interaction-ack budget\nconst SLOW_GATE_MS = 750;\n\n// lazy because the logger reads the environment, which binds after this module loads\nlet gateLogger: Logger | undefined;\nfunction logger(): Logger {\n gateLogger ??= new Logger('Gates', { channel: 'gates' });\n return gateLogger;\n}\n\n/**\n * collects each gate check's elapsed time for one dispatch. `report` warns once when the checks sum\n * past the threshold, naming the total, the route, and each gate's share.\n */\nexport interface SlowGateMonitor {\n readonly observe: GateObserver;\n report(routeId: string | null): void;\n}\n\n// undefined in production, so timedCheck skips the clock there. read per call, the environment binds late\nexport function slowGateMonitor(): SlowGateMonitor | undefined {\n if (Envapter.isProduction) return undefined;\n const readings: { name: string; ms: number }[] = [];\n return {\n observe: (name, ms) => readings.push({ name, ms }),\n report(routeId) {\n const total = readings.reduce((sum, reading) => sum + reading.ms, 0);\n if (total < SLOW_GATE_MS) return;\n const shares = readings\n .toSorted((a, b) => b.ms - a.ms)\n .map((reading) => `${paint.sky.bold(reading.name)} ${Math.round(reading.ms)}ms`);\n const route = routeId === null ? '' : ` for ${paint.sky.bold(routeId)}`;\n const headline = `gates${route} took ${paint.amber(`${Math.round(total)}ms`)} of the 3s ack budget`;\n logger().utils.block(headline, shares, 'warn', (text) => text);\n }\n };\n}\n","// narrows a configured emoji value to the [name, guildId] form\nexport function isEmojiTuple(value: unknown): value is readonly [string, string] {\n return Array.isArray(value) && value.length === 2 && typeof value[0] === 'string' && typeof value[1] === 'string';\n}\n","import type { DevChannel } from '@seedcord/types/internal';\n\n// the minimal raw-hot shape, satisfied by both vite's `import.meta.hot` and the CLI's `NormalizedHotChannel`.\ninterface RawHot {\n send(event: string, data?: unknown): void;\n on(event: string, cb: (data: unknown) => void): void;\n}\n\n/** @internal */\nexport function wrapHot<TSend, TRecv>(hot: RawHot): DevChannel<TSend, TRecv> {\n return {\n send: (event, data) => hot.send(event, data),\n // justified: RawHot types every payload as unknown, and the wire contract guarantees it matches TRecv[Key]\n on: (event, cb) => hot.on(event, cb as (data: unknown) => void)\n };\n}\n","// scoped here so import.meta.hot stays untyped in the rest of the package\n/// <reference types=\"vite/client\" />\nimport { Logger, paint } from '@seedcord/logger';\nimport { Envapter } from 'envapt';\n\nimport { setDevChannel } from './devChannel';\nimport { wrapHot } from './wrapHot';\n\nimport type { HmrAware, HmrUpdateEvent } from '@seedcord/types';\nimport type { SeedcordCliEvents, SeedcordFrameworkEvents } from '@seedcord/types/internal';\n\nexport class HmrManager {\n private readonly logger = new Logger('HMR', { channel: 'hmr' });\n private readonly listeners = new Set<HmrAware>();\n\n /** @internal */\n public init(): void {\n if (!import.meta.hot) return;\n // the only raw `import.meta.hot` read in the framework\n const channel = wrapHot<SeedcordFrameworkEvents, SeedcordCliEvents>(import.meta.hot);\n setDevChannel(channel);\n\n if (Envapter.isDevelopment || Envapter.isTest) {\n this.logger.debug('Enabled');\n channel.on('seedcord:hmr', (payload) => void this.handleUpdate(payload));\n }\n }\n\n /** @internal */\n public register(listener: HmrAware): void {\n this.listeners.add(listener);\n }\n\n /** @internal */\n public unregister(listener: HmrAware): void {\n this.listeners.delete(listener);\n }\n\n private async handleUpdate(event: HmrUpdateEvent): Promise<void> {\n const promises = [...this.listeners].map(async (listener) => {\n try {\n await listener.onHmr(event);\n } catch (error) {\n this.logger.error(`Error handling HMR update in ${paint.sky.bold(listener.constructor.name)}`, error);\n }\n });\n\n await Promise.all(promises);\n }\n}\n","// dropping a non-Error throw would leave the user with no fault card, and every report payload declares an Error\n/** @internal */\nexport function asError(caught: unknown): Error {\n return Error.isError(caught) ? caught : new Error(String(caught), { cause: caught });\n}\n","import { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport type { AckTrace } from './AckTrace';\n\nexport type AckState = 'unacked' | 'deferred-reply' | 'deferred-update' | 'replied';\n\nexport type ReplyMethod =\n 'reply' | 'defer' | 'deferUpdate' | 'update' | 'followUp' | 'edit' | 'delete' | 'send' | 'showModal';\n\ninterface Illegal {\n // spliced into the message after \"was called when\"\n readonly reason: string;\n readonly alternative: string;\n}\n\nconst showModalReason: Illegal = {\n reason: 'this interaction was already acknowledged',\n alternative: 'showModal() must be the initial response.'\n};\n\nfunction deferReason(what: string): Illegal {\n return {\n reason: `this interaction was already acknowledged with ${what}`,\n alternative: 'A deferral can only be the initial response.'\n };\n}\n\n// a missing entry means legal in that state\nconst ILLEGAL: Record<Exclude<ReplyMethod, 'send'>, Partial<Record<AckState, Illegal>>> = {\n reply: {\n 'deferred-reply': {\n reason: 'this interaction was already deferred',\n alternative: 'Use edit() to fill the deferred reply or followUp() for a new message.'\n },\n 'deferred-update': {\n reason: 'this interaction was already acknowledged with a deferred update',\n alternative: 'Use followUp() for a new message.'\n },\n replied: {\n reason: 'this interaction was already replied to',\n alternative: 'Use followUp() for a new message or edit() to rewrite the reply.'\n }\n },\n defer: {\n 'deferred-reply': deferReason('a deferred reply'),\n 'deferred-update': deferReason('a deferred update'),\n replied: deferReason('a reply')\n },\n deferUpdate: {\n 'deferred-reply': deferReason('a deferred reply'),\n 'deferred-update': deferReason('a deferred update'),\n replied: deferReason('a reply')\n },\n update: {\n 'deferred-reply': {\n reason: 'this interaction was deferred as a reply',\n alternative: 'The placeholder is yours via edit(). update() rewrites a source message.'\n },\n replied: {\n reason: 'this interaction was already replied to',\n alternative: 'update() rewrites a source message. Use edit() or followUp() instead.'\n }\n },\n followUp: {\n unacked: {\n reason: 'this interaction has not been acknowledged yet',\n alternative: 'Ack first with reply() or defer().'\n }\n },\n edit: {\n unacked: {\n reason: 'nothing has been sent yet',\n alternative: 'Send with reply() or defer() first, then edit() rewrites it.'\n }\n },\n delete: {\n unacked: {\n reason: 'nothing has been sent yet',\n alternative: 'Acknowledge first with reply() or defer(), then delete() removes it.'\n }\n },\n showModal: {\n 'deferred-reply': showModalReason,\n 'deferred-update': showModalReason,\n replied: showModalReason\n }\n};\n\nconst SEND_TARGET: Record<AckState, 'reply' | 'edit' | 'followUp'> = {\n unacked: 'reply',\n 'deferred-reply': 'edit',\n 'deferred-update': 'followUp',\n replied: 'followUp'\n};\n\n// throws before any API call, and ackedBy becomes the throw cause with its stack pointing at the first ack\nexport function checkAckLegality(method: ReplyMethod, state: AckState, routeId: string, ackedBy?: AckTrace): void {\n if (method === 'send') return;\n const illegal = ILLEGAL[method][state];\n if (!illegal) return;\n throw new SeedcordError(\n SeedcordErrorCode.ReplyIllegalAckState,\n [method, illegal.reason, illegal.alternative, routeId],\n { cause: ackedBy }\n );\n}\n\nexport function sendTarget(state: AckState): 'reply' | 'edit' | 'followUp' {\n return SEND_TARGET[state];\n}\n","import type { ReplyMethod } from './ackLegality';\n\n// the first ack's stack, passed as the throw cause so a double-ack points to both lines\nexport class AckTrace extends Error {\n public constructor(method: ReplyMethod) {\n super(`${method}() acknowledged this interaction`);\n this.name = 'AckTrace';\n }\n}\n","import { Logger, paint } from '@seedcord/logger';\n\nimport { asError } from '@stops/asError';\nimport { PublishDefault } from '@subscribers/publishDefault';\n\nimport type { ReplyMethod } from './ackLegality';\nimport type { Bus } from '@subscribers/Bus';\nimport type { ResponseOutcome } from '@subscribers/types/Subscriptions';\n\nlet replyLogger: Logger | undefined;\nfunction logger(): Logger {\n replyLogger ??= new Logger('Reply', { channel: 'interactions' });\n return replyLogger;\n}\n\nexport interface ReplyTelemetry {\n readonly bus: Bus;\n readonly interactionId: string;\n}\n\n// the reply verbs plus the autocomplete choices callback, which runs outside the ack state machine\nexport type WriteMethod = ReplyMethod | 'respond';\n\nexport interface ResponseReport {\n readonly routeId: string;\n readonly method: WriteMethod;\n // performance.now() captured before the write began\n readonly startedAt: number;\n readonly outcome: ResponseOutcome;\n readonly messageId: string | null;\n readonly error?: Error;\n}\n\n/** @internal */\nexport function publishResponse(telemetry: ReplyTelemetry, report: ResponseReport): void {\n const durationMs = performance.now() - report.startedAt;\n telemetry.bus[PublishDefault]('responseAttempted', {\n routeId: report.routeId,\n interactionId: telemetry.interactionId,\n method: report.method,\n outcome: report.outcome,\n durationMs,\n messageId: report.messageId,\n ...(report.error && { error: report.error })\n });\n\n // after publish so a throwing sink doesn't reach the publish above\n logger().trace(\n `${paint.mint.bold(report.routeId)} ${report.method} ${report.outcome} ${paint.mute('in')} ${Math.round(durationMs)}ms`\n );\n}\n\nexport async function reportedWrite<Result>(\n telemetry: ReplyTelemetry,\n routeId: string,\n method: WriteMethod,\n write: () => Promise<Result>\n): Promise<Result> {\n const startedAt = performance.now();\n const result = await attemptWrite(telemetry, routeId, method, startedAt, write);\n publishResponse(telemetry, { routeId, method, startedAt, outcome: 'sent', messageId: null });\n return result;\n}\n\n// publishes the failed arm when write() throws, since the caller's success report sits after the write and a throw skips it\nexport async function attemptWrite<Result>(\n telemetry: ReplyTelemetry,\n routeId: string,\n method: WriteMethod,\n startedAt: number,\n write: () => Promise<Result>\n): Promise<Result> {\n try {\n return await write();\n } catch (caught) {\n const error = asError(caught);\n publishResponse(telemetry, { routeId, method, startedAt, outcome: 'failed', messageId: null, error });\n // rethrown raw\n throw caught;\n }\n}\n","import { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\n// shapeshift aggregate errors nest, so the cap bounds the recursion\nconst MAX_DEPTH = 8;\n\ninterface ShapeshiftLike {\n readonly message?: unknown;\n readonly errors?: unknown;\n readonly constraint?: unknown;\n readonly validator?: unknown;\n readonly expected?: unknown;\n readonly given?: unknown;\n}\n\nconst OPERATOR_WORD: Record<string, string> = {\n '<=': 'at most',\n '>=': 'at least',\n '<': 'fewer than',\n '>': 'more than'\n};\n\nconst KIND_WORD: Record<string, string> = {\n string: 'a string',\n number: 'a number',\n boolean: 'a boolean',\n bigint: 'a bigint',\n array: 'a list',\n tuple: 'a list',\n date: 'a date',\n object: 'an object'\n};\n\nfunction asRecord(value: unknown): ShapeshiftLike | null {\n return typeof value === 'object' && value !== null ? value : null;\n}\n\nfunction firstLine(message: unknown): string {\n if (typeof message !== 'string') return 'unknown validation failure';\n return message.split('\\n')[0] ?? message;\n}\n\n// strings over this limit render as a character count\nconst GIVEN_PREVIEW_LIMIT = 40;\n\nfunction gotPhrase(given: unknown): string {\n if (given === undefined) return 'nothing';\n if (given === null) return 'null';\n if (typeof given === 'string') {\n if (given.length === 0) return 'an empty string';\n if (given.length > GIVEN_PREVIEW_LIMIT) return `${given.length} characters`;\n return JSON.stringify(given);\n }\n if (Array.isArray(given)) return given.length === 0 ? 'an empty list' : `${given.length} items`;\n if (typeof given === 'number' || typeof given === 'bigint' || typeof given === 'boolean') return String(given);\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- a null-prototype value has no constructor at runtime\n if (typeof given === 'object') return given.constructor?.name ?? 'an object';\n return typeof given;\n}\n\n// shapeshift constraint strings take the form 'expected.length >= 1' or 'expected <= 16777215'\nfunction needPhrase(expected: string, given: unknown): string | null {\n const bounds = [...expected.matchAll(/expected(\\.length)?\\s*(<=|>=|<|>)\\s*(\\d+)/g)];\n if (bounds.length === 0) return null;\n const phrases = bounds.map(([, lengthPart, operator, limit]) => {\n const word = OPERATOR_WORD[operator ?? ''] ?? operator ?? '';\n if (!lengthPart) return `${word} ${limit}`;\n const unit = typeof given === 'string' ? 'character' : 'item';\n return `${word} ${limit} ${Number(limit) === 1 ? unit : `${unit}s`}`;\n });\n return phrases.join(' and ');\n}\n\nfunction instanceName(expected: unknown): string {\n if (typeof expected === 'function' && expected.name) return expected.name;\n return 'specific class instance';\n}\n\nfunction describeLeaf(record: ShapeshiftLike): string {\n if (typeof record.constraint === 'string') {\n const need = typeof record.expected === 'string' ? needPhrase(record.expected, record.given) : null;\n if (need) return `need ${need}, got ${gotPhrase(record.given)}`;\n return `${firstLine(record.message)}${'given' in record ? ` (got ${gotPhrase(record.given)})` : ''}`;\n }\n if (typeof record.expected === 'function') {\n return `need a ${instanceName(record.expected)}, got ${gotPhrase(record.given)}`;\n }\n if (typeof record.validator === 'string') {\n const kind = KIND_WORD[record.validator.replace(/^s\\./, '').replace(/\\(.*$/, '')];\n if (kind) return `need ${kind}, got ${gotPhrase(record.given)}`;\n return `${firstLine(record.message)}, got ${gotPhrase(record.given)}`;\n }\n return firstLine(record.message);\n}\n\nfunction describeUnion(branches: unknown[], depth: number): string {\n const records: ShapeshiftLike[] = [];\n for (const branch of branches) {\n const record = asRecord(branch);\n if (record) records.push(record);\n }\n const bounded = records.find((record) => typeof record.constraint === 'string');\n if (bounded) return describeLeaf(bounded);\n\n const names: string[] = [];\n let allInstances = records.length > 0;\n for (const record of records) {\n if (typeof record.expected === 'function') names.push(instanceName(record.expected));\n else allInstances = false;\n }\n if (allInstances) {\n return `need a ${[...new Set(names)].join(' or ')}, got ${gotPhrase(records[0]?.given)}`;\n }\n return detailOf(branches[0], depth + 1);\n}\n\n// shapeshift nests errors as [key, inner] tuples\nfunction detailOf(value: unknown, depth: number): string {\n const record = asRecord(value);\n if (!record || depth >= MAX_DEPTH) return firstLine(record?.message);\n\n if (Array.isArray(record.errors) && record.errors.length > 0) {\n const errors = record.errors as unknown[];\n const [first] = errors;\n if (Array.isArray(first)) {\n const [key, inner] = first as [unknown, unknown];\n return `${String(key)}: ${detailOf(inner, depth + 1)}`;\n }\n return describeUnion(errors, depth);\n }\n\n return describeLeaf(record);\n}\n\n// a shapeshift throw becomes an actionable message with the cause kept, while anything else contributes its own message as the detail\nexport function translateSerializationError(\n error: unknown,\n componentClass: string,\n index: number,\n routeId: string\n): SeedcordError<SeedcordErrorCode.ReplyComponentSerialization> {\n const detail = detailOf(error, 0);\n return new SeedcordError(SeedcordErrorCode.ReplyComponentSerialization, [componentClass, index, detail, routeId], {\n cause: error\n });\n}\n","import { TextDisplayBuilder } from '@discordjs/builders';\n\nimport { translateSerializationError } from './translateSerialization';\n\nimport type { ReplyResponse } from '@seedcord/types';\nimport type { APIMessageTopLevelComponent } from 'discord-api-types/v10';\n\nexport interface SerializedReply<TNative = never> {\n readonly components: APIMessageTopLevelComponent[];\n readonly allowedMentions?: ReplyResponse['allowedMentions'];\n readonly files?: ReplyResponse<TNative>['files'];\n}\n\nexport function serializeReply<TNative>(\n response: ReplyResponse<TNative> | string,\n routeId: string\n): SerializedReply<TNative> {\n if (typeof response === 'string') {\n try {\n return { components: [new TextDisplayBuilder().setContent(response).toJSON()] };\n } catch (error) {\n throw translateSerializationError(error, 'TextDisplayBuilder', 0, routeId);\n }\n }\n\n const components = response.components.map((component, index) => {\n try {\n return component.toJSON();\n } catch (error) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- a null-prototype value has no constructor at runtime\n const name = component.constructor?.name;\n throw translateSerializationError(error, !name || name === 'Object' ? 'component' : name, index, routeId);\n }\n });\n\n return {\n components,\n ...(response.allowedMentions && { allowedMentions: response.allowedMentions }),\n ...(response.files && { files: response.files })\n };\n}\n","import { SeedcordErrorCode } from '@seedcord/errors';\nimport { SeedcordError } from '@seedcord/errors/internal';\n\nimport { checkAckLegality, sendTarget } from './ackLegality';\nimport { AckTrace } from './AckTrace';\nimport { attemptWrite, publishResponse } from './responseReport';\nimport { serializeReply } from './serializeReply';\nimport { translateSerializationError } from './translateSerialization';\n\nimport type { AckState, ReplyMethod } from './ackLegality';\nimport type { ReplyTelemetry } from './responseReport';\nimport type { SerializedReply } from './serializeReply';\nimport type { DeferOpts, ReplyResponse, SendOpts } from '@seedcord/types';\nimport type { ResponseOutcome } from '@subscribers/types/Subscriptions';\nimport type { APIModalInteractionResponseCallbackData } from 'discord-api-types/v10';\n\n/** The shape djs modal builders emit from `toJSON()`. */\nexport interface ModalLike {\n toJSON(): APIModalInteractionResponseCallbackData;\n}\n\n/**\n * Tracks acknowledgement state and throws a translated `SeedcordError` on an illegal verb before any\n * transport call. Every verb runs the legality check, calls the transport's wire writer, then updates\n * the state and the ack trace. Each transport binds `TMessage` to its own created-message type and\n * supplies the writers.\n */\nexport abstract class BaseReplySender<TMessage extends { id: string }, TNative = never> {\n private state: AckState;\n // the only ids a targeted edit accepts\n private readonly sent = new Set<string>();\n // the cause carries the first ack's stack so a double-ack reports both lines\n private ackedBy?: AckTrace;\n\n protected constructor(\n protected readonly routeId: string,\n private readonly telemetry: ReplyTelemetry,\n initialState: AckState = 'unacked'\n ) {\n this.state = initialState;\n }\n\n private report(method: ReplyMethod, startedAt: number, outcome: ResponseOutcome, messageId: string | null): void {\n publishResponse(this.telemetry, { routeId: this.routeId, method, startedAt, outcome, messageId });\n }\n\n private async attempt<Result>(\n method: ReplyMethod,\n startedAt: number,\n write: () => Promise<Result>\n ): Promise<Result> {\n return await attemptWrite(this.telemetry, this.routeId, method, startedAt, write);\n }\n\n public async reply(response: ReplyResponse<TNative> | string, opts?: SendOpts): Promise<TMessage> {\n this.checkLegality('reply');\n const startedAt = performance.now();\n const created = await this.attempt('reply', startedAt, () => this.writeReply(response, opts));\n // the callback already acked discord, so record replied before the message guard can throw\n this.transition('reply', 'replied');\n const message = this.remember(this.requireMessage(created, 'reply'));\n this.report('reply', startedAt, 'sent', message.id);\n return message;\n }\n\n public async defer(opts?: DeferOpts): Promise<void> {\n this.checkLegality('defer');\n const startedAt = performance.now();\n await this.attempt('defer', startedAt, () => this.writeDefer(opts));\n this.transition('defer', 'deferred-reply');\n this.report('defer', startedAt, 'sent', null);\n }\n\n public async deferUpdate(): Promise<void> {\n this.checkLegality('deferUpdate');\n const startedAt = performance.now();\n await this.attempt('deferUpdate', startedAt, () => this.writeDeferUpdate());\n this.transition('deferUpdate', 'deferred-update');\n this.report('deferUpdate', startedAt, 'sent', null);\n }\n\n /**\n * After a deferUpdate the state stays deferred-update. Calling this again rewrites. The returned message\n * is the source message, editable only through a bare `update` or `edit`. A targeted `edit` or `delete`\n * of it throws the foreign-target error.\n */\n public async update(response: ReplyResponse<TNative> | string): Promise<TMessage> {\n this.checkLegality('update');\n const startedAt = performance.now();\n // in deferred-update the source message is @original and the ack-legality check above already passed\n if (this.state === 'deferred-update') {\n const edited = await this.attempt('update', startedAt, () => this.editOriginal(response));\n this.report('update', startedAt, 'sent', edited.id);\n return edited;\n }\n const created = await this.attempt('update', startedAt, () => this.writeUpdate(response));\n this.transition('update', 'replied');\n const message = this.remember(this.requireMessage(created, 'update'));\n this.report('update', startedAt, 'sent', message.id);\n return message;\n }\n\n public async followUp(response: ReplyResponse<TNative> | string, opts?: SendOpts): Promise<TMessage> {\n this.checkLegality('followUp');\n const startedAt = performance.now();\n const created = await this.attempt('followUp', startedAt, () => this.writeFollowUp(response, opts));\n const message = this.remember(created);\n this.report('followUp', startedAt, 'sent', message.id);\n return message;\n }\n\n public edit(response: ReplyResponse<TNative> | string): Promise<TMessage>;\n public edit(target: TMessage, response: ReplyResponse<TNative> | string): Promise<TMessage>;\n public async edit(\n targetOrResponse: TMessage | ReplyResponse<TNative> | string,\n maybeResponse?: ReplyResponse<TNative> | string\n ): Promise<TMessage> {\n this.checkLegality('edit');\n const startedAt = performance.now();\n if (maybeResponse === undefined) {\n // justified: the overloads narrow targetOrResponse to a response once maybeResponse is absent\n const edited = await this.attempt('edit', startedAt, () =>\n this.editOriginal(targetOrResponse as ReplyResponse<TNative> | string)\n );\n this.report('edit', startedAt, 'sent', edited.id);\n return edited;\n }\n // justified: the overloads narrow targetOrResponse to a target message once maybeResponse is defined\n const target = targetOrResponse as TMessage;\n if (!this.sent.has(target.id)) {\n throw new SeedcordError(SeedcordErrorCode.ReplyForeignEditTarget, ['edit', target.id, this.routeId]);\n }\n const written = await this.attempt('edit', startedAt, () => this.writeEditTarget(target.id, maybeResponse));\n const message = this.remember(written);\n this.report('edit', startedAt, 'sent', message.id);\n return message;\n }\n\n public delete(): Promise<void>;\n public delete(target: TMessage): Promise<void>;\n public async delete(target?: TMessage): Promise<void> {\n this.checkLegality('delete');\n const startedAt = performance.now();\n if (target === undefined) {\n await this.attempt('delete', startedAt, () => this.writeDeleteOriginal());\n this.report('delete', startedAt, 'sent', null);\n return;\n }\n if (!this.sent.has(target.id)) {\n throw new SeedcordError(SeedcordErrorCode.ReplyForeignEditTarget, ['delete', target.id, this.routeId]);\n }\n await this.attempt('delete', startedAt, () => this.writeDeleteTarget(target.id));\n // evict so a later targeted edit of this id throws foreign\n this.sent.delete(target.id);\n this.report('delete', startedAt, 'sent', null);\n }\n\n /** Routes to the verb the current ack state permits. Every state has a route, so the illegal-ack throw is unreachable. */\n public async send(response: ReplyResponse<TNative> | string, opts?: SendOpts): Promise<TMessage> {\n const target = sendTarget(this.state);\n if (target === 'reply') return await this.reply(response, opts);\n if (target === 'edit') return await this.edit(response);\n return await this.followUp(response, opts);\n }\n\n /** Must be the initial response. */\n public async showModal(modal: ModalLike): Promise<void> {\n this.checkLegality('showModal');\n this.guardModalSource();\n let data: APIModalInteractionResponseCallbackData;\n try {\n data = modal.toJSON();\n } catch (error) {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- a null-prototype modal has no constructor at runtime\n const name = modal.constructor?.name;\n throw translateSerializationError(error, !name || name === 'Object' ? 'modal' : name, 0, this.routeId);\n }\n const startedAt = performance.now();\n await this.attempt('showModal', startedAt, () => this.writeModal(data));\n this.transition('showModal', 'replied');\n this.report('showModal', startedAt, 'sent', null);\n }\n\n protected serialize(response: ReplyResponse<TNative> | string): SerializedReply<TNative> {\n return serializeReply(response, this.routeId);\n }\n\n protected remember(created: TMessage): TMessage {\n this.sent.add(created.id);\n return created;\n }\n\n // a with_response callback always returns the created message. this only trips if the wire says otherwise\n private requireMessage(created: TMessage | undefined, method: 'reply' | 'update'): TMessage {\n if (!created) throw new SeedcordError(SeedcordErrorCode.ReplyCallbackMissingMessage, [method, this.routeId]);\n return created;\n }\n\n private async editOriginal(response: ReplyResponse<TNative> | string): Promise<TMessage> {\n const edited = await this.writeEditOriginal(response);\n // after a deferUpdate the source message is @original, which this interaction did not send\n if (this.state !== 'deferred-update') this.remember(edited);\n return edited;\n }\n\n private checkLegality(method: ReplyMethod): void {\n checkAckLegality(method, this.state, this.routeId, this.ackedBy);\n }\n\n private transition(method: ReplyMethod, state: AckState): void {\n this.state = state;\n this.ackedBy = new AckTrace(method);\n }\n\n // gateway overrides this to reject a modal-submit source\n protected guardModalSource(): void {}\n\n protected abstract writeReply(\n response: ReplyResponse<TNative> | string,\n opts?: SendOpts\n ): Promise<TMessage | undefined>;\n protected abstract writeDefer(opts?: DeferOpts): Promise<void>;\n protected abstract writeDeferUpdate(): Promise<void>;\n protected abstract writeUpdate(response: ReplyResponse<TNative> | string): Promise<TMessage | undefined>;\n protected abstract writeFollowUp(response: ReplyResponse<TNative> | string, opts?: SendOpts): Promise<TMessage>;\n protected abstract writeEditOriginal(response: ReplyResponse<TNative> | string): Promise<TMessage>;\n protected abstract writeEditTarget(targetId: string, response: ReplyResponse<TNative> | string): Promise<TMessage>;\n protected abstract writeDeleteOriginal(): Promise<void>;\n protected abstract writeDeleteTarget(targetId: string): Promise<void>;\n protected abstract writeModal(data: APIModalInteractionResponseCallbackData): Promise<void>;\n}\n","/** @internal */\nexport class FaultThrottle {\n // keyed by core so each bot gets its own window, and the entry is collected with the core\n private static readonly perCore = new WeakMap<object, FaultThrottle>();\n\n /** @internal */\n public static for(core: object): FaultThrottle {\n let throttle = FaultThrottle.perCore.get(core);\n if (!throttle) {\n throttle = new FaultThrottle();\n FaultThrottle.perCore.set(core, throttle);\n }\n return throttle;\n }\n\n private readonly lastReportedAt = new Map<string, number>();\n\n constructor(\n private readonly windowMs = 60_000,\n private readonly now: () => number = () => Date.now()\n ) {}\n\n public shouldReport(key: string): boolean {\n const last = this.lastReportedAt.get(key);\n if (last === undefined) return true;\n if (this.now() - last < this.windowMs) return false;\n\n this.lastReportedAt.delete(key);\n return true;\n }\n\n public markReported(key: string): void {\n this.lastReportedAt.set(key, this.now());\n }\n\n public clear(): void {\n this.lastReportedAt.clear();\n }\n}\n","import { Logger, paint } from '@seedcord/logger';\nimport { timestampFromSnowflake } from '@seedcord/utils';\n\nimport { Notice } from '@stops/Notice';\nimport { Silence } from '@stops/Silence';\nimport { PublishDefault } from '@subscribers/publishDefault';\n\nimport type { InteractionRoutes } from '@src/metadataKeys';\nimport type { Bus } from '@subscribers/Bus';\nimport type { DispatchOutcome } from '@subscribers/types/Subscriptions';\n\nlet dispatchLogger: Logger | undefined;\nfunction logger(): Logger {\n dispatchLogger ??= new Logger('Dispatch', { channel: 'interactions' });\n return dispatchLogger;\n}\n\n/**\n * Classifies a caught stop for `interactionDispatched` so a gate and a\n * handler label the same stop identically.\n *\n * @internal\n */\nexport function outcomeFor(caught: unknown): DispatchOutcome {\n if (caught instanceof Silence) return 'refused';\n if (caught instanceof Notice) return caught.report ? 'failed' : 'refused';\n return 'failed';\n}\n\n/** The values a dispatcher has once its handler chain settles. */\ninterface DispatchReport {\n readonly routeId: string;\n readonly interactionId: string;\n readonly kind: `${InteractionRoutes}`;\n readonly outcome: DispatchOutcome;\n /** True when no route matched and the unhandled default ran. */\n readonly fallback: boolean;\n /** `performance.now()` captured as the dispatch began. */\n readonly startedAt: number;\n /** {@link queuedMsFor} read at the same moment as `startedAt`. */\n readonly queuedMs: number;\n}\n\n/**\n * Discord's interaction creation to now, read from the snowflake. Called at dispatch entry, since\n * a later read would count the handler run into the queue time as well.\n *\n * @internal\n */\nexport function queuedMsFor(interactionId: string): number {\n // telemetry never breaks a dispatch, and BigInt() throws on a malformed id\n try {\n return Date.now() - timestampFromSnowflake(interactionId);\n } catch {\n return 0;\n }\n}\n\nexport function reportDispatch(bus: Bus, report: DispatchReport): void {\n const durationMs = performance.now() - report.startedAt;\n bus[PublishDefault]('interactionDispatched', {\n routeId: report.routeId,\n interactionId: report.interactionId,\n kind: report.kind,\n outcome: report.outcome,\n fallback: report.fallback,\n durationMs,\n queuedMs: report.queuedMs\n });\n\n // after publish so a throwing sink doesn't reach the publish above\n logger().trace(\n `${paint.mint.bold(report.routeId)} ${report.outcome} ${paint.mute('in')} ${Math.round(durationMs)}ms`\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { A as ModalLike, B as storeInteractionRoute, C as Gate, F as areRoutes, G as DecodedParams, I as contextMenuRouteOf, J as Promisable, K as CommandMeta, L as interactionRoutesOf, M as serializeReply, N as RoutableConstructor, R as selectMenuRouteOf, U as decodeFor, V as AnyCustomId, W as prefixOf, X as BuilderComponent, Y as IsNever, _ as pickNotice, c as FocusedField, i as AutocompletableNames, j as SerializedReply, k as BaseReplySender, lt as SlashOptionRegistry, m as PermissionNames, n as PageCursor, o as ChoiceValueOf, r as pageCursor, s as EntryFor, st as OptionKind, t as PAGE_MAX, tt as CommandInjector, v as GateFitsWith, w as GateContextBase, z as storeComponentRoute } from "./cursor-
|
|
2
|
-
import { n as CommandBuilder, r as DeployResult } from "./basic-
|
|
3
|
-
import { A as AckState, B as InteractionRouteKeys, D as Notice, F as PublishDefault, H as MiddlewareMetadataKey, I as CommandMetadataKey, L as EventMetadataKey, M as checkAckLegality, N as sendTarget, O as ReplyTelemetry, P as AckTrace, R as GatedMetadataKey, S as DispatchOutcome, U as SubscribeMetadataKey, V as InteractionRoutes, W as WebhookUrlMetadataKey, _ as Bus, a as PluginCtor, i as PluginArgs, j as ReplyMethod, k as reportedWrite, v as StoredSubscriberCtor, x as DefaultSubscriptions, y as SubscriberRegistration, z as InteractionMetadataKey } from "./Plugin-
|
|
4
|
-
import { n as contextMenuLeaves, t as ContextMenuLeaves } from "./contextMenuLeaves-
|
|
1
|
+
import { A as ModalLike, B as storeInteractionRoute, C as Gate, F as areRoutes, G as DecodedParams, I as contextMenuRouteOf, J as Promisable, K as CommandMeta, L as interactionRoutesOf, M as serializeReply, N as RoutableConstructor, R as selectMenuRouteOf, U as decodeFor, V as AnyCustomId, W as prefixOf, X as BuilderComponent, Y as IsNever, _ as pickNotice, c as FocusedField, i as AutocompletableNames, j as SerializedReply, k as BaseReplySender, lt as SlashOptionRegistry, m as PermissionNames, n as PageCursor, o as ChoiceValueOf, r as pageCursor, s as EntryFor, st as OptionKind, t as PAGE_MAX, tt as CommandInjector, v as GateFitsWith, w as GateContextBase, z as storeComponentRoute } from "./cursor-C77xH5QT.mjs";
|
|
2
|
+
import { n as CommandBuilder, r as DeployResult } from "./basic-Dng__Ena.mjs";
|
|
3
|
+
import { A as AckState, B as InteractionRouteKeys, D as Notice, F as PublishDefault, H as MiddlewareMetadataKey, I as CommandMetadataKey, L as EventMetadataKey, M as checkAckLegality, N as sendTarget, O as ReplyTelemetry, P as AckTrace, R as GatedMetadataKey, S as DispatchOutcome, U as SubscribeMetadataKey, V as InteractionRoutes, W as WebhookUrlMetadataKey, _ as Bus, a as PluginCtor, i as PluginArgs, j as ReplyMethod, k as reportedWrite, v as StoredSubscriberCtor, x as DefaultSubscriptions, y as SubscriberRegistration, z as InteractionMetadataKey } from "./Plugin-qRc7Ch4g.mjs";
|
|
4
|
+
import { n as contextMenuLeaves, t as ContextMenuLeaves } from "./contextMenuLeaves-COzDYa6c.mjs";
|
|
5
5
|
import "reflect-metadata";
|
|
6
6
|
import { ContextMenuCommandBuilder, SlashCommandBuilder } from "@discordjs/builders";
|
|
7
7
|
import { ChannelType } from "discord-api-types/v10";
|
|
@@ -13,23 +13,14 @@ import { DevChannel, SeedcordCliEvents, SeedcordFrameworkEvents } from "@seedcor
|
|
|
13
13
|
declare function setBotColor(color: BotColor | undefined): void;
|
|
14
14
|
//#endregion
|
|
15
15
|
//#region src/gates/runGates.d.ts
|
|
16
|
-
/**
|
|
17
|
-
* Receives each gate's name and how long its check ran, in ms. A combinator (`and`/`or`) reports once
|
|
18
|
-
* under its joined name.
|
|
19
|
-
*/
|
|
20
16
|
type GateObserver = (gateName: string, elapsedMs: number) => void;
|
|
21
17
|
declare function routeIdOf(handlerCtor: object): string | null;
|
|
22
|
-
/**
|
|
23
|
-
* Runs each gate's check in order, so the first refusal propagates to the dispatcher boundary. An effect
|
|
24
|
-
* gate's commit runs once the whole set passes. When `observe` is given, each check is timed and reported,
|
|
25
|
-
* commits excluded.
|
|
26
|
-
*/
|
|
27
18
|
declare function runGates(gates: readonly Gate<GateContextBase>[], ctx: GateContextBase, observe?: GateObserver): Promise<void>;
|
|
28
19
|
declare function runHandlerGates(handlerCtor: object, ctx: GateContextBase, routeId?: string, observe?: GateObserver): Promise<void>;
|
|
29
20
|
//#endregion
|
|
30
21
|
//#region src/gates/slowGate.d.ts
|
|
31
22
|
/**
|
|
32
|
-
*
|
|
23
|
+
* collects each gate check's elapsed time for one dispatch. `report` warns once when the checks sum
|
|
33
24
|
* past the threshold, naming the total, the route, and each gate's share.
|
|
34
25
|
*/
|
|
35
26
|
interface SlowGateMonitor {
|
|
@@ -39,32 +30,18 @@ interface SlowGateMonitor {
|
|
|
39
30
|
declare function slowGateMonitor(): SlowGateMonitor | undefined;
|
|
40
31
|
//#endregion
|
|
41
32
|
//#region src/miscellaneous/guarded.d.ts
|
|
42
|
-
/**
|
|
43
|
-
* A backing record for a generated accessor. Null-prototype, on a plain object a key named `__proto__` sets
|
|
44
|
-
* the store's prototype and adds no entry.
|
|
45
|
-
*
|
|
46
|
-
* @internal
|
|
47
|
-
*/
|
|
48
33
|
declare function accessorStore<Value>(): Record<string, Value>;
|
|
49
|
-
/** Empties a store in place, keeping the reference the accessor's Proxy wraps. @internal */
|
|
50
34
|
declare function clearStore(store: Record<string, unknown>): void;
|
|
51
|
-
/**
|
|
52
|
-
* Wraps a generated accessor's backing record so a read of an absent key throws. Handler modules import before
|
|
53
|
-
* startup fills the record, and an unguarded read there returns `undefined` and renders as an empty string.
|
|
54
|
-
*
|
|
55
|
-
* @internal
|
|
56
|
-
*/
|
|
57
35
|
declare function guardedAccessor<Value>(accessor: string, storage: Record<string, Value>): Record<string, Value>;
|
|
58
36
|
//#endregion
|
|
59
37
|
//#region src/miscellaneous/emojiConfig.d.ts
|
|
60
|
-
/** Narrows a configured emoji value to the `[name, guildId]` form. @internal */
|
|
61
38
|
declare function isEmojiTuple(value: unknown): value is readonly [string, string];
|
|
62
39
|
//#endregion
|
|
63
40
|
//#region src/commands/slashRouteLeaves.d.ts
|
|
64
41
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
42
|
+
* dedupes route keys since the same builder appears once per guild.
|
|
43
|
+
* these come from the same {@link routeLeavesOf} that `seedcord codegen` reads, so the boot-time
|
|
44
|
+
* check compares against the generated registry's keys.
|
|
68
45
|
*
|
|
69
46
|
* @internal
|
|
70
47
|
*/
|
|
@@ -94,11 +71,7 @@ interface RawHot {
|
|
|
94
71
|
send(event: string, data?: unknown): void;
|
|
95
72
|
on(event: string, cb: (data: unknown) => void): void;
|
|
96
73
|
}
|
|
97
|
-
/**
|
|
98
|
-
* Wraps a raw vite hot object as a typed {@link DevChannel}.
|
|
99
|
-
*
|
|
100
|
-
* @internal
|
|
101
|
-
*/
|
|
74
|
+
/** @internal */
|
|
102
75
|
declare function wrapHot<TSend, TRecv>(hot: RawHot): DevChannel<TSend, TRecv>;
|
|
103
76
|
//#endregion
|
|
104
77
|
//#region src/notices/index.d.ts
|
|
@@ -150,25 +123,21 @@ declare class HasDangerousPermissions extends Notice {
|
|
|
150
123
|
declare function asError(caught: unknown): Error;
|
|
151
124
|
//#endregion
|
|
152
125
|
//#region src/stops/NoticeCard.d.ts
|
|
153
|
-
/**
|
|
154
|
-
* Built fresh inside a {@link Notice}'s `render` to back its ComponentsV2 reply. The title renders as
|
|
155
|
-
* an h3 line with the description on the next line.
|
|
156
|
-
*/
|
|
157
126
|
declare class NoticeCard extends BuilderComponent<'container'> {
|
|
158
127
|
constructor(description: string, title?: string);
|
|
159
128
|
}
|
|
160
129
|
//#endregion
|
|
161
130
|
//#region src/customId/routing.d.ts
|
|
162
131
|
/**
|
|
163
|
-
*
|
|
132
|
+
* route decorators store a handler's customId defs here, so the component base can decode
|
|
164
133
|
* against them at runtime.
|
|
165
134
|
*
|
|
166
135
|
* @internal
|
|
167
136
|
*/
|
|
168
137
|
declare const ComponentDefsKey: unique symbol;
|
|
169
138
|
/**
|
|
170
|
-
*
|
|
171
|
-
* passing different
|
|
139
|
+
* the phantom a component handler base carries. a route decorator constrains its argument to this, so
|
|
140
|
+
* passing different defs to the decorator and the handler's generic is a compile error. never set at runtime.
|
|
172
141
|
*
|
|
173
142
|
* @internal
|
|
174
143
|
*/
|
|
@@ -182,7 +151,7 @@ interface DecodedComponentRoute {
|
|
|
182
151
|
params: Record<string, unknown>;
|
|
183
152
|
}
|
|
184
153
|
/**
|
|
185
|
-
*
|
|
154
|
+
* throws `CustomIdHandlerRouteMissing` when the class has no stored defs. a drifted or corrupt wire
|
|
186
155
|
* throws `StaleCustomId` or `InvalidCustomId`.
|
|
187
156
|
*
|
|
188
157
|
* @internal
|
|
@@ -245,38 +214,22 @@ type MemberGetter<Route extends keyof SlashOptionRegistry, Lens extends OptionLe
|
|
|
245
214
|
type SlashOptions<Route extends keyof SlashOptionRegistry, Lens extends OptionLens> = Getter<Route, Lens, 'string', 'getString'> & Getter<Route, Lens, 'integer', 'getInteger'> & Getter<Route, Lens, 'number', 'getNumber'> & Getter<Route, Lens, 'boolean', 'getBoolean'> & Getter<Route, Lens, 'user', 'getUser'> & Getter<Route, Lens, 'channel', 'getChannel'> & Getter<Route, Lens, 'role', 'getRole'> & Getter<Route, Lens, 'mentionable', 'getMentionable'> & Getter<Route, Lens, 'attachment', 'getAttachment'> & MemberGetter<Route, Lens>;
|
|
246
215
|
//#endregion
|
|
247
216
|
//#region src/reply/flags.d.ts
|
|
248
|
-
/** IsComponentsV2 is unconditional, every framework reply is v2. */
|
|
249
217
|
declare function sendFlags(opts?: SendOpts): number;
|
|
250
|
-
/** A deferral carries no content, so only Ephemeral applies. */
|
|
251
218
|
declare function deferFlags(opts?: DeferOpts): number;
|
|
252
219
|
//#endregion
|
|
253
220
|
//#region src/reply/translateSerialization.d.ts
|
|
254
|
-
/**
|
|
255
|
-
* Translates a shapeshift throw into an actionable message, keeping the original as `cause`. Any other
|
|
256
|
-
* throw contributes its message as the detail.
|
|
257
|
-
*/
|
|
258
221
|
declare function translateSerializationError(error: unknown, componentClass: string, index: number, routeId: string): SeedcordError<SeedcordErrorCode.ReplyComponentSerialization>;
|
|
259
222
|
//#endregion
|
|
260
223
|
//#region src/subscribers/FaultThrottle.d.ts
|
|
261
|
-
/**
|
|
262
|
-
* Drops duplicate fault reports inside a fixed window, so a recurring fault (a database outage on a
|
|
263
|
-
* hot path) reports once per window and never floods the webhook.
|
|
264
|
-
*
|
|
265
|
-
* @internal
|
|
266
|
-
*/
|
|
224
|
+
/** @internal */
|
|
267
225
|
declare class FaultThrottle {
|
|
268
226
|
private readonly windowMs;
|
|
269
227
|
private readonly now;
|
|
270
228
|
private static readonly perCore;
|
|
271
|
-
/**
|
|
272
|
-
* The throttle for one bot instance.
|
|
273
|
-
*
|
|
274
|
-
* @internal
|
|
275
|
-
*/
|
|
229
|
+
/** @internal */
|
|
276
230
|
static for(core: object): FaultThrottle;
|
|
277
231
|
private readonly lastReportedAt;
|
|
278
232
|
constructor(windowMs?: number, now?: () => number);
|
|
279
|
-
/** Evicts the entry for this key if it has aged out. */
|
|
280
233
|
shouldReport(key: string): boolean;
|
|
281
234
|
markReported(key: string): void;
|
|
282
235
|
clear(): void;
|