@seedcord/core 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/{Bus-BvF4VShN.mjs → Bus-BVwmKc-A.mjs} +36 -17
  2. package/dist/Bus-BVwmKc-A.mjs.map +1 -0
  3. package/dist/Pluggable-Cf5-WWmW.mjs +280 -0
  4. package/dist/Pluggable-Cf5-WWmW.mjs.map +1 -0
  5. package/dist/Pluggable-DFNUIlJM.d.mts +148 -0
  6. package/dist/{Plugin-D9ykXA5g.mjs → Plugin-C6oMqWf8.mjs} +7 -3
  7. package/dist/Plugin-C6oMqWf8.mjs.map +1 -0
  8. package/dist/{Plugin-CQ9IEj5X.d.mts → Plugin-CG9pWbPF.d.mts} +2 -2
  9. package/dist/{cursor-BANzac53.d.mts → cursor-BcRfmTSo.d.mts} +26 -72
  10. package/dist/{cursor-CuoA9cRh.mjs → cursor-GBUYz3jk.mjs} +378 -30
  11. package/dist/cursor-GBUYz3jk.mjs.map +1 -0
  12. package/dist/{index-rt8rZg4d.d.mts → index-ZzdQafFv.d.mts} +2 -2
  13. package/dist/index.d.mts +77 -19
  14. package/dist/index.mjs +186 -19
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/internal.index.d.mts +11 -5
  17. package/dist/internal.index.mjs +8 -455
  18. package/dist/internal.index.mjs.map +1 -1
  19. package/dist/node-internal.index.d.mts +6 -133
  20. package/dist/node-internal.index.mjs +15 -472
  21. package/dist/node-internal.index.mjs.map +1 -1
  22. package/dist/node.index.d.mts +2 -0
  23. package/dist/node.index.mjs +256 -0
  24. package/dist/node.index.mjs.map +1 -0
  25. package/dist/{phases-hBxMCD2V.d.mts → phases-F8yvPd60.d.mts} +104 -72
  26. package/dist/plugin.index.d.mts +1 -1
  27. package/dist/plugin.index.mjs +1 -1
  28. package/dist/publishDefault-D826XXDQ.mjs +14 -0
  29. package/dist/publishDefault-D826XXDQ.mjs.map +1 -0
  30. package/dist/{slashRouteLeaves-De1SxqnX.mjs → slashRouteLeaves-CbYRwqMY.mjs} +10 -2
  31. package/dist/slashRouteLeaves-CbYRwqMY.mjs.map +1 -0
  32. package/dist/{subscribers-wnMyNYZd.mjs → subscribers-CGGQkUfM.mjs} +2 -2
  33. package/dist/{subscribers-wnMyNYZd.mjs.map → subscribers-CGGQkUfM.mjs.map} +1 -1
  34. package/package.json +14 -8
  35. package/dist/Bus-BvF4VShN.mjs.map +0 -1
  36. package/dist/Plugin-D9ykXA5g.mjs.map +0 -1
  37. package/dist/cursor-CuoA9cRh.mjs.map +0 -1
  38. package/dist/slashRouteLeaves-De1SxqnX.mjs.map +0 -1
@@ -1,300 +1,22 @@
1
- import { D as contextMenuLeaves, S as SubscribeMetadataKey, c as Subscriber, f as BuilderComponent, h as CommandMetadataKey, i as PublishDefault, n as busLoggerOf, r as registrationFor } from "./Bus-BvF4VShN.mjs";
2
- import { t as CommandInjector } from "./subscribers-wnMyNYZd.mjs";
1
+ import { D as SubscribeMetadataKey, M as contextMenuLeaves, a as RegisterSubscriber, b as CommandMetadataKey, c as VerifyWebhooks, f as Subscriber, i as RegisterDefaults, n as busLoggerOf, o as RegisteredCount, r as registrationFor, s as UnregisterSubscriber } from "./Bus-BVwmKc-A.mjs";
2
+ import { t as CommandInjector } from "./subscribers-CGGQkUfM.mjs";
3
+ import { t as PublishDefault } from "./publishDefault-D826XXDQ.mjs";
3
4
  import { n as StartupPhase, t as ShutdownPhase } from "./phases-BauKJOTT.mjs";
4
5
  import { t as getDevChannel } from "./devChannel-CQU7hq7Q.mjs";
5
- import { n as pluginLoggerOf, r as resolvedLifecycleSpecOf } from "./Plugin-D9ykXA5g.mjs";
6
- import { t as slashRouteLeaves } from "./slashRouteLeaves-De1SxqnX.mjs";
6
+ import { n as isCommandClass, t as slashRouteLeaves } from "./slashRouteLeaves-CbYRwqMY.mjs";
7
7
  import { t as HmrModuleHandler } from "./HmrModuleHandler-9AUfKXRl.mjs";
8
+ import { i as settleWithin, n as shutdownOf, r as assertNodeVersion } from "./Pluggable-Cf5-WWmW.mjs";
8
9
  import { SlashCommandBuilder } from "@discordjs/builders";
9
10
  import { SeedcordErrorCode, paint } from "@seedcord/errors";
10
- import { FRAMEWORK_CHANNELS, Logger } from "@seedcord/logger";
11
+ import { Logger } from "@seedcord/logger";
11
12
  import { Routes } from "discord-api-types/v10";
12
- import { SeedcordAggregateError, SeedcordError } from "@seedcord/errors/internal";
13
+ import { SeedcordError } from "@seedcord/errors/internal";
13
14
  import { formatFilePath } from "@seedcord/utils";
14
15
  import { Envapter } from "envapt";
15
16
  import { resolve } from "node:path";
16
17
  import { createServer } from "node:http";
17
18
  import { traverseDirectory } from "@seedcord/utils/node";
18
19
 
19
- //#region src/node/assertNodeVersion.ts
20
- const RANGE = new RegExp(String.raw`^>=(\d+)(?:\.(\d+))?`);
21
- const VERSION = /^v?(\d+)\.(\d+)/;
22
- const SPACES = /\s/g;
23
- /** @internal */
24
- function assertNodeVersion(range, running) {
25
- const required = RANGE.exec(range.replaceAll(SPACES, ""));
26
- const current = VERSION.exec(running);
27
- if (!required || !current) return;
28
- const [, requiredMajor, requiredMinor = "0"] = required;
29
- const [, currentMajor, currentMinor] = current;
30
- if (Number(currentMajor) > Number(requiredMajor) || Number(currentMajor) === Number(requiredMajor) && Number(currentMinor) >= Number(requiredMinor)) return;
31
- throw new SeedcordError(SeedcordErrorCode.UnsupportedNodeVersion, [range, running]);
32
- }
33
-
34
- //#endregion
35
- //#region src/node/Lifecycle/withTimeout.ts
36
- async function raceTimer(work, timeoutMs, onTimeout) {
37
- let timer;
38
- try {
39
- await Promise.race([work, new Promise((resolve, reject) => {
40
- timer = setTimeout(() => onTimeout(resolve, reject), timeoutMs);
41
- })]);
42
- } finally {
43
- if (timer) clearTimeout(timer);
44
- }
45
- }
46
- function withTimeout(name, run, timeoutMs) {
47
- return raceTimer(run(), timeoutMs, (_, reject) => {
48
- reject(new SeedcordError(SeedcordErrorCode.LifecycleTaskTimeout, [name, timeoutMs]));
49
- });
50
- }
51
- function settleWithin(work, timeoutMs) {
52
- return raceTimer(work, timeoutMs, (resolve) => resolve());
53
- }
54
-
55
- //#endregion
56
- //#region src/node/Lifecycle/CoordinatedLifecycle.ts
57
- var CoordinatedLifecycle = class {
58
- phaseOrder;
59
- phaseEnum;
60
- logger;
61
- tasksMap = /* @__PURE__ */ new Map();
62
- constructor(loggerName, phaseOrder, phaseEnum) {
63
- this.phaseOrder = phaseOrder;
64
- this.phaseEnum = phaseEnum;
65
- this.logger = new Logger(loggerName, { channel: "lifecycle" });
66
- this.phaseOrder.forEach((phase) => this.tasksMap.set(phase, []));
67
- }
68
- addTask(phase, taskName, task, timeoutMs) {
69
- if (!this.canAddTask()) return;
70
- const tasks = this.tasksMap.get(phase);
71
- if (!tasks) throw new SeedcordError(SeedcordErrorCode.LifecycleUnknownPhase, [phase]);
72
- tasks.push({
73
- name: taskName,
74
- task,
75
- timeout: timeoutMs
76
- });
77
- this.logger.debug(`${paint.italic("Added")} ${this.getTaskType()} task ${paint.sky.bold(taskName)} to phase ${paint.iris.bold(this.phaseEnum[phase])}`);
78
- }
79
- removeTask(phase, taskName) {
80
- if (!this.canRemoveTask()) return false;
81
- const tasks = this.tasksMap.get(phase);
82
- if (!tasks) return false;
83
- const initialLength = tasks.length;
84
- const filteredTasks = tasks.filter((task) => task.name !== taskName);
85
- this.tasksMap.set(phase, filteredTasks);
86
- const removed = initialLength !== filteredTasks.length;
87
- if (removed) this.logger.debug(`${paint.italic("Removed")} ${this.getTaskType()} task ${paint.sky.bold(taskName)} from phase ${paint.iris.bold(this.phaseEnum[phase])}`);
88
- return removed;
89
- }
90
- async runPhase(phase) {
91
- const tasks = this.tasksMap.get(phase) ?? [];
92
- if (tasks.length === 0) {
93
- this.logger.trace(`No tasks to run in phase ${paint.iris.bold(this.phaseEnum[phase])}`);
94
- return;
95
- }
96
- this.logger.debug(`${paint.amber.bold("Running")} ${this.getTaskType()} phase ${paint.iris.bold(this.phaseEnum[phase])} with ${paint.sky.bold(String(tasks.length))} tasks`);
97
- const reasons = (await this.executeTasksInPhase(phase, tasks)).reduce((rejected, result) => {
98
- if (result.status === "rejected") rejected.push(result.reason);
99
- return rejected;
100
- }, []);
101
- if (reasons.length > 0) throw new SeedcordAggregateError(SeedcordErrorCode.LifecyclePhaseFailures, reasons, [this.phaseEnum[phase], reasons.length]);
102
- this.logger.debug(`Phase ${paint.iris.bold(this.phaseEnum[phase])} ${paint.mint.bold("completed successfully")}`);
103
- }
104
- async runTaskWithTimeout(phase, task) {
105
- this.logger.trace(`${paint.italic("Starting")} task ${paint.sky.bold(task.name)} in phase ${paint.iris.bold(this.phaseEnum[phase])}`);
106
- try {
107
- await withTimeout(task.name, task.task, task.timeout);
108
- this.logger.trace(`${paint.italic("Completed")} task ${paint.sky.bold(task.name)} in phase ${paint.iris.bold(this.phaseEnum[phase])}`);
109
- } catch (error) {
110
- if (this.isAborted()) return;
111
- this.logger.error(`${paint.italic("Failed")} task ${paint.sky.bold(task.name)} in phase ${paint.iris.bold(this.phaseEnum[phase])}:`, error);
112
- throw error;
113
- }
114
- }
115
- isAborted() {
116
- return false;
117
- }
118
- };
119
-
120
- //#endregion
121
- //#region src/node/Lifecycle/CoordinatedShutdown.ts
122
- const PHASE_ORDER$1 = [
123
- 1,
124
- 2,
125
- 3,
126
- 4
127
- ];
128
- const LOG_FLUSH_DELAY_MS = 3e3;
129
- var CoordinatedShutdown = class extends CoordinatedLifecycle {
130
- isShuttingDown = false;
131
- hasShutdown = false;
132
- exitCode = 0;
133
- onSigTerm = null;
134
- onSigInt = null;
135
- startupGate;
136
- constructor() {
137
- super("Shutdown", PHASE_ORDER$1, ShutdownPhase);
138
- this.registerSignalHandlers();
139
- }
140
- canAddTask() {
141
- return true;
142
- }
143
- canRemoveTask() {
144
- return true;
145
- }
146
- getTaskType() {
147
- return "shutdown";
148
- }
149
- async executeTasksInPhase(phase, tasks) {
150
- const promises = tasks.map((task) => this.runTaskWithTimeout(phase, task));
151
- return Promise.allSettled(promises);
152
- }
153
- registerSignalHandlers() {
154
- this.onSigTerm = () => {
155
- this.logger.info(`Received ${paint.amber.bold("SIGTERM")} signal`);
156
- this.run(0);
157
- };
158
- this.onSigInt = () => {
159
- this.logger.info(`Received ${paint.amber.bold("SIGINT")} signal`);
160
- this.run(0);
161
- };
162
- process.on("SIGTERM", this.onSigTerm);
163
- process.on("SIGINT", this.onSigInt);
164
- }
165
- /** @internal */
166
- removeSignalHandlers() {
167
- if (this.onSigTerm) {
168
- process.off("SIGTERM", this.onSigTerm);
169
- this.onSigTerm = null;
170
- }
171
- if (this.onSigInt) {
172
- process.off("SIGINT", this.onSigInt);
173
- this.onSigInt = null;
174
- }
175
- }
176
- /** @internal run() awaits this so boot finishes registering its dispose tasks first */
177
- gateOnStartup(settled) {
178
- this.startupGate = settled;
179
- }
180
- addTask(phase, taskName, task, timeoutMs = 5e3) {
181
- super.addTask(phase, taskName, task, timeoutMs);
182
- }
183
- removeTask(phase, taskName) {
184
- return super.removeTask(phase, taskName);
185
- }
186
- async run(exitCode = 0, exitProcess = true) {
187
- this.removeSignalHandlers();
188
- if (this.hasShutdown || this.isShuttingDown) {
189
- this.logger.warn("Shutdown sequence already ran or is in progress");
190
- return;
191
- }
192
- this.isShuttingDown = true;
193
- this.exitCode = exitCode;
194
- this.logger.info(`${paint.amber.bold("Starting")} coordinated shutdown with exit code ${paint.sky.bold(exitCode)}`);
195
- try {
196
- if (this.startupGate) await this.startupGate;
197
- const failures = [];
198
- for (const phase of PHASE_ORDER$1) try {
199
- await this.runPhase(phase);
200
- } catch (error) {
201
- failures.push(error);
202
- }
203
- if (failures.length > 0) this.logger.error(`${paint.coral.bold("Coordinated shutdown failed")}`, ...failures);
204
- else this.logger.info(`${paint.mint.bold("Coordinated shutdown completed")} successfully`);
205
- } finally {
206
- this.hasShutdown = true;
207
- if (exitProcess) {
208
- this.logger.debug(`${paint.coral.bold("Exiting")} process with code ${paint.sky.bold(this.exitCode)}`);
209
- setTimeout(() => {
210
- process.exit(this.exitCode);
211
- }, LOG_FLUSH_DELAY_MS);
212
- } else {
213
- this.logger.debug(`${paint.amber.bold("Skipping")} process exit (dev mode)`);
214
- this.isShuttingDown = false;
215
- }
216
- }
217
- }
218
- };
219
-
220
- //#endregion
221
- //#region src/node/Lifecycle/CoordinatedStartup.ts
222
- const PHASE_ORDER = [
223
- 1,
224
- 2,
225
- 3
226
- ];
227
- var CoordinatedStartup = class extends CoordinatedLifecycle {
228
- isStartingUp = false;
229
- hasStarted = false;
230
- constructor() {
231
- super("Startup", PHASE_ORDER, StartupPhase);
232
- }
233
- addTask(phase, taskName, task, timeoutMs = 1e4) {
234
- super.addTask(phase, taskName, task, timeoutMs);
235
- }
236
- canAddTask() {
237
- if (this.hasStarted) throw new SeedcordError(SeedcordErrorCode.LifecycleAddAfterCompletion);
238
- if (this.isStartingUp) throw new SeedcordError(SeedcordErrorCode.LifecycleAddDuringRun);
239
- return true;
240
- }
241
- canRemoveTask() {
242
- if (this.isStartingUp) throw new SeedcordError(SeedcordErrorCode.LifecycleRemoveDuringRun);
243
- return true;
244
- }
245
- getTaskType() {
246
- return "startup";
247
- }
248
- async executeTasksInPhase(phase, tasks) {
249
- const promises = tasks.map((task) => this.runTaskWithTimeout(phase, task));
250
- return Promise.allSettled(promises);
251
- }
252
- async run() {
253
- if (this.hasStarted) {
254
- this.logger.warn("Startup sequence has already completed");
255
- return;
256
- }
257
- if (this.isStartingUp) {
258
- this.logger.warn("Startup sequence already in progress");
259
- return;
260
- }
261
- this.isStartingUp = true;
262
- this.logger.info(`${paint.mint.bold("Starting")} coordinated startup sequence`);
263
- try {
264
- for (const phase of PHASE_ORDER) {
265
- if (!this.isStartingUp) {
266
- this.logger.warn("Startup sequence aborted");
267
- return;
268
- }
269
- await this.runPhase(phase);
270
- }
271
- this.hasStarted = true;
272
- this.logger.info(`${paint.mint.bold("Coordinated startup completed")} successfully`);
273
- } catch (error) {
274
- if (!this.isStartingUp) {
275
- this.logger.warn("Startup sequence aborted during error handling");
276
- return;
277
- }
278
- this.logger.error(`${paint.coral.bold("Coordinated startup failed")}`);
279
- throw error;
280
- } finally {
281
- this.isStartingUp = false;
282
- }
283
- }
284
- isAborted() {
285
- return !this.isStartingUp;
286
- }
287
- abort() {
288
- if (!this.isStartingUp) return;
289
- this.isStartingUp = false;
290
- this.logger.warn("Aborting coordinated startup sequence");
291
- }
292
- get isReady() {
293
- return this.hasStarted;
294
- }
295
- };
296
-
297
- //#endregion
298
20
  //#region src/node/HealthResponder.ts
299
21
  const HTTP_OK = 200;
300
22
  const DEFAULT_HEALTH_CHECK_PATH = "/health";
@@ -385,181 +107,6 @@ var HealthCheck = class HealthCheck {
385
107
  }
386
108
  };
387
109
 
388
- //#endregion
389
- //#region src/node/Pluggable.ts
390
- const RESERVED_KEYS = new Set(FRAMEWORK_CHANNELS);
391
- /**
392
- * Base class for a plugin host, a transport `Seedcord` class.
393
- *
394
- * You attach plugins while configuring the bot. Within one startup phase, their `init()` calls run
395
- * one after another in attach order.
396
- */
397
- var Pluggable = class Pluggable {
398
- /** @see {@link CoordinatedShutdown} */
399
- shutdown;
400
- /** @see {@link CoordinatedStartup} */
401
- startup;
402
- isInitialized = false;
403
- startFailed = false;
404
- plugins = [];
405
- pluginLogger = new Logger("Plugins", { channel: "plugins" });
406
- attachments = [];
407
- completedInits = /* @__PURE__ */ new Set();
408
- disposePhases = /* @__PURE__ */ new Set();
409
- pluginTasksRegistered = false;
410
- static isInstantiated = false;
411
- static liveShutdown;
412
- constructor(shutdown, startup) {
413
- assertNodeVersion(">=24.11", process.version);
414
- if (Pluggable.isInstantiated) {
415
- shutdown.removeSignalHandlers();
416
- throw new SeedcordError(SeedcordErrorCode.CoreSingletonViolation);
417
- }
418
- Pluggable.isInstantiated = true;
419
- Pluggable.liveShutdown = shutdown;
420
- this.shutdown = shutdown;
421
- this.startup = startup;
422
- }
423
- /** @internal */
424
- async init() {
425
- if (this.isInitialized) return this;
426
- if (this.startFailed) throw new SeedcordError(SeedcordErrorCode.LifecycleRestartAfterFailure);
427
- this.registerPluginTasks();
428
- const startupSettled = Promise.withResolvers();
429
- this.shutdown.gateOnStartup(startupSettled.promise);
430
- try {
431
- await this.startup.run();
432
- } catch (caught) {
433
- await this.rollback();
434
- throw caught;
435
- } finally {
436
- startupSettled.resolve();
437
- }
438
- this.isInitialized = true;
439
- return this;
440
- }
441
- /** @internal codegen reads these to emit the `Core` augmentation */
442
- get pluginKeys() {
443
- return this.attachments.map((attachment) => attachment.key);
444
- }
445
- /** @internal so the next host can construct */
446
- static reset() {
447
- Pluggable.liveShutdown?.removeSignalHandlers();
448
- Pluggable.liveShutdown = void 0;
449
- Pluggable.isInstantiated = false;
450
- }
451
- /**
452
- * Attaches a plugin under `key`. Read the instance back as `core[key]`. `seedcord codegen`
453
- * writes the `Core` augmentation that types it there.
454
- *
455
- * Startup runs each plugin's `init()` in attach order within its phase.
456
- *
457
- * Attaching a plugin whose `transport` or `runtime` differs from this host fails to compile.
458
- * Your constructor takes `CoreBase` as its first parameter (you don't need to pass it though).
459
- * A narrower one fails to compile here.
460
- *
461
- * @param key - Also the channel the plugin logs on. Reserved channel names throw.
462
- * @param args - Whatever your constructor takes after the host.
463
- * @throws A **SeedcordError** if you attach after the bot has started. A taken or reserved key throws too.
464
- * @example
465
- * ```ts
466
- * seedcord.attach('db', Mongoose, { uri: 'mongodb://...', name: 'seedcord', dir: ... });
467
- * ```
468
- */
469
- attach(key, Plugin, ...args) {
470
- if (this.isInitialized) throw new SeedcordError(SeedcordErrorCode.CorePluginAfterInit);
471
- if (RESERVED_KEYS.has(key)) throw new SeedcordError(SeedcordErrorCode.CorePluginReservedChannel, [key]);
472
- if (key in this) throw new SeedcordError(SeedcordErrorCode.CorePluginKeyExists, [key]);
473
- const instance = new Plugin(this, ...args);
474
- pluginLoggerOf(instance).setChannel(key);
475
- this.plugins.push(instance);
476
- this.attachments.push({
477
- key,
478
- instance
479
- });
480
- return Object.assign(this, { [key]: instance });
481
- }
482
- registerPluginTasks() {
483
- if (this.pluginTasksRegistered) return;
484
- this.pluginTasksRegistered = true;
485
- const groups = /* @__PURE__ */ new Map();
486
- for (const attachment of this.attachments) {
487
- const phase = resolvedLifecycleSpecOf(attachment.instance).init.phase;
488
- const group = groups.get(phase) ?? [];
489
- group.push(attachment);
490
- groups.set(phase, group);
491
- }
492
- for (const [phase, group] of groups) {
493
- if (phase === 3) continue;
494
- const budget = group.reduce((sum, a) => sum + resolvedLifecycleSpecOf(a.instance).init.timeout, 0);
495
- this.startup.addTask(phase, "plugins-init", () => this.runInits(group), budget);
496
- }
497
- this.registerReadyTask(groups.get(3) ?? []);
498
- }
499
- async runInits(group) {
500
- for (const attachment of group) {
501
- const { key, instance } = attachment;
502
- const spec = resolvedLifecycleSpecOf(instance);
503
- pluginLoggerOf(instance).utils.initialization(key, "start");
504
- await withTimeout(`Plugin (${key})`, () => instance.init(), spec.init.timeout);
505
- pluginLoggerOf(instance).utils.initialization(key, "end");
506
- this.completedInits.add(attachment);
507
- if (instance.dispose) this.registerDisposeTask(spec.dispose.phase);
508
- }
509
- }
510
- registerReadyTask(readyInits) {
511
- const steps = this.attachments.reduce((acc, a) => {
512
- const ready = a.instance.ready?.bind(a.instance);
513
- if (ready) acc.push({
514
- key: a.key,
515
- run: ready,
516
- timeout: resolvedLifecycleSpecOf(a.instance).ready.timeout
517
- });
518
- return acc;
519
- }, []);
520
- if (readyInits.length === 0 && steps.length === 0) return;
521
- const budget = readyInits.reduce((sum, a) => sum + resolvedLifecycleSpecOf(a.instance).init.timeout, 0) + steps.reduce((sum, step) => sum + step.timeout, 0);
522
- this.startup.addTask(3, "plugins-ready", async () => {
523
- await this.runInits(readyInits);
524
- for (const step of steps) await withTimeout(`Plugin:${step.key}:ready`, step.run, step.timeout);
525
- }, budget);
526
- }
527
- registerDisposeTask(phase) {
528
- if (this.disposePhases.has(phase)) return;
529
- this.disposePhases.add(phase);
530
- const budget = this.attachments.reduce((sum, a) => {
531
- const spec = resolvedLifecycleSpecOf(a.instance);
532
- return a.instance.dispose && spec.dispose.phase === phase ? sum + spec.dispose.timeout : sum;
533
- }, 0);
534
- this.shutdown.addTask(phase, "plugins-dispose", () => this.runDisposals(phase), budget);
535
- }
536
- async runDisposals(phase) {
537
- const failures = [];
538
- await this.disposeCompleted(phase, (caught) => failures.push(caught));
539
- if (failures.length === 1) throw failures[0];
540
- if (failures.length > 1) throw new SeedcordAggregateError(SeedcordErrorCode.PluginDisposeFailures, failures, [failures.length]);
541
- }
542
- async disposeCompleted(phase, onError) {
543
- for (const attachment of [...this.attachments].reverse()) {
544
- if (!this.completedInits.has(attachment)) continue;
545
- const dispose = attachment.instance.dispose?.bind(attachment.instance);
546
- if (!dispose) continue;
547
- const spec = resolvedLifecycleSpecOf(attachment.instance);
548
- if (phase !== void 0 && spec.dispose.phase !== phase) continue;
549
- try {
550
- await withTimeout(`Plugin:${attachment.key}:dispose`, dispose, spec.dispose.timeout);
551
- } catch (caught) {
552
- onError(caught);
553
- }
554
- }
555
- }
556
- async rollback() {
557
- this.startFailed = true;
558
- await this.disposeCompleted(void 0, (caught) => this.pluginLogger.warn("rollback dispose failed", caught));
559
- this.completedInits.clear();
560
- }
561
- };
562
-
563
110
  //#endregion
564
111
  //#region src/node/subscribers/SubscriberLoader.ts
565
112
  var SubscriberLoader = class {
@@ -585,14 +132,14 @@ var SubscriberLoader = class {
585
132
  async init() {
586
133
  if (this.isInitialized) return;
587
134
  this.isInitialized = true;
588
- this.bus.registerDefaults();
135
+ this.bus[RegisterDefaults]();
589
136
  const { directory } = this;
590
137
  if (directory) {
591
138
  busLoggerOf(this.bus).debug(paint.mute(directory));
592
139
  await this.load(directory);
593
- busLoggerOf(this.bus).utils.list([`${paint.iris.bold(this.bus.registeredCount)} subscribers`], paint.mint.bold("Loaded"), "debug");
140
+ busLoggerOf(this.bus).utils.list([`${paint.iris.bold(this.bus[RegisteredCount])} subscribers`], paint.mint.bold("Loaded"), "debug");
594
141
  }
595
- if (!Envapter.isTest) await this.bus.verifyWebhooks();
142
+ if (!Envapter.isTest) await this.bus[VerifyWebhooks]();
596
143
  }
597
144
  /** @internal */
598
145
  async onHmr(event) {
@@ -610,10 +157,10 @@ var SubscriberLoader = class {
610
157
  });
611
158
  }
612
159
  registerSubscriber(ctor) {
613
- this.bus.register(registrationFor(ctor));
160
+ this.bus[RegisterSubscriber](registrationFor(ctor));
614
161
  }
615
162
  unregisterSubscriber(ctor, artifacts) {
616
- this.bus.unregister(ctor, artifacts);
163
+ this.bus[UnregisterSubscriber](ctor, artifacts);
617
164
  }
618
165
  getArtifacts(ctor) {
619
166
  return [Reflect.getMetadata(SubscribeMetadataKey, ctor).subscriber];
@@ -655,7 +202,7 @@ var CommandRegistry = class {
655
202
  if (!Envapter.isDevelopment && !Envapter.isTest) return;
656
203
  this.hmrHandler = new HmrModuleHandler({
657
204
  handlersDir: dir,
658
- isHandler: this.isCommandClass.bind(this),
205
+ isHandler: isCommandClass,
659
206
  registerHandler: this.registerCommand.bind(this),
660
207
  unregisterHandler: this.unregisterCommand.bind(this),
661
208
  getArtifacts: this.getArtifacts.bind(this),
@@ -718,16 +265,12 @@ var CommandRegistry = class {
718
265
  }
719
266
  async loadCommands(dir) {
720
267
  await traverseDirectory(dir, (fullPath, rel, mod) => {
721
- for (const exported of Object.values(mod)) if (this.isCommandClass(exported)) {
268
+ for (const exported of Object.values(mod)) if (isCommandClass(exported)) {
722
269
  this.registerCommand(exported, rel);
723
270
  this.hmrHandler?.trackHandler(fullPath, exported);
724
271
  }
725
272
  });
726
273
  }
727
- isCommandClass(obj) {
728
- if (typeof obj !== "function") return false;
729
- return obj.prototype instanceof BuilderComponent && Reflect.hasMetadata(CommandMetadataKey, obj);
730
- }
731
274
  registerCommand(ctor, rel) {
732
275
  const meta = Reflect.getMetadata(CommandMetadataKey, ctor);
733
276
  if (!meta) return;
@@ -819,5 +362,5 @@ function deployedPayload(result) {
819
362
  assertNodeVersion(">=24.11", process.version);
820
363
 
821
364
  //#endregion
822
- export { CommandRegistry, CoordinatedShutdown, CoordinatedStartup, HealthCheck, HealthResponder, Pluggable, ShutdownPhase, StartupPhase, SubscriberLoader, settleWithin };
365
+ export { CommandRegistry, HealthCheck, HealthResponder, ShutdownPhase, StartupPhase, SubscriberLoader, settleWithin, shutdownOf };
823
366
  //# sourceMappingURL=node-internal.index.mjs.map