virello 0.1.0 → 0.1.1
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/BREAKING_CHANGES.md +19 -0
- package/README.md +15 -15
- package/docs/console-logging.md +25 -25
- package/docs/engine.md +8 -8
- package/docs/sharding-recovery.md +3 -3
- package/docs/sharding-scaling.md +2 -2
- package/docs/sharding-stats.md +3 -3
- package/examples/README.md +12 -12
- package/examples/bot.ts +2 -2
- package/examples/client.ts +4 -4
- package/examples/commands/ping.ts +1 -1
- package/examples/commands/shard.ts +2 -2
- package/examples/commands/stats.ts +2 -2
- package/examples/config.ts +1 -1
- package/examples/contracts.ts +1 -1
- package/examples/coordinator.ts +1 -1
- package/examples/engine/live.ts +3 -3
- package/examples/engine/offline.ts +2 -2
- package/examples/host.ts +1 -1
- package/examples/listeners/ready.ts +2 -2
- package/examples/logging.ts +1 -1
- package/examples/offline.ts +2 -2
- package/examples/registration.ts +2 -2
- package/examples/shutdown.ts +1 -1
- package/examples/stats.ts +1 -1
- package/package.json +2 -2
- package/src/commands/checks/containers/Entry.ts +3 -3
- package/src/commands/registration/computeDifferences/option/channelTypes.ts +1 -1
- package/src/commands/registration/computeDifferences/option/type.ts +2 -2
- package/src/commands/registration/computeDifferences/options.ts +3 -3
- package/src/commands/types.ts +1 -1
- package/src/core/Container.ts +5 -5
- package/src/core/client/{RiloClient.ts → VirelloClient.ts} +24 -19
- package/src/core/config/extensions.ts +1 -1
- package/src/core/index.ts +1 -1
- package/src/core/lifecycle/Extension.ts +5 -5
- package/src/core/loading/constants.ts +1 -1
- package/src/core/logging/LoggerLike.ts +5 -5
- package/src/core/logging/console.ts +9 -9
- package/src/core/logging/format.ts +3 -3
- package/src/core/runtime.ts +1 -1
- package/src/engine/gateway/GatewayShard.ts +2 -2
- package/src/engine/rest/RestClient.ts +2 -1
- package/src/events/events.ts +74 -59
- package/src/extensions/localisation/extension.ts +2 -2
- package/src/extensions/patternCommands/extension.ts +2 -2
- package/src/extensions/scheduledTasks/backends/RedisBackend.ts +1 -1
- package/src/extensions/scheduledTasks/extension.ts +2 -2
- package/src/extensions/scheduledTasks/types/TaskTypes.ts +1 -1
- package/src/extensions/services/extension.ts +2 -2
- package/src/extensions/subcommands/extension.ts +2 -2
- package/src/index.ts +1 -1
- package/src/public/client.ts +2 -2
- package/src/sharding/client/Link.ts +5 -5
- package/src/sharding/client/gateway.ts +1 -1
- package/src/sharding/coordinator/Coordinator.ts +4 -4
- package/src/sharding/manager/Manager.ts +6 -6
- package/src/sharding/stats.ts +1 -1
- package/src/sharding/types.ts +3 -3
- package/src/utilities/collections/bitfield/BitField.ts +1 -1
- package/src/utilities/decorators/module-decorators.ts +1 -1
- package/src/utilities/discord/pagination/PaginatedMessage.ts +10 -10
- package/src/utilities/discord/pagination/Pagination.ts +1 -1
- package/src/utilities/discord/snowflake/Snowflake.ts +5 -5
- package/src/utilities/parsing/strategies/FlagUnorderedStrategy.ts +1 -1
- package/src/utilities/result/Option.ts +2 -2
- package/src/utilities/result/Result.ts +3 -3
package/src/events/events.ts
CHANGED
|
@@ -26,7 +26,7 @@ import type { Option } from "../utilities/result/index";
|
|
|
26
26
|
import type { InteractionHandler } from "./interactions/interactionHandler";
|
|
27
27
|
import type { Listener } from "./listener";
|
|
28
28
|
|
|
29
|
-
/** Discord and
|
|
29
|
+
/** Discord and Virello event names. ClientEvents supplies each event’s argument tuple. */
|
|
30
30
|
export const Events = {
|
|
31
31
|
// #region Discord.js base events
|
|
32
32
|
/** Alias of the discord.js ApplicationCommandPermissionsUpdate event. Its payload follows discord.js ClientEvents. */
|
|
@@ -184,7 +184,7 @@ export const Events = {
|
|
|
184
184
|
WebhooksUpdate: DJSEvents.WebhooksUpdate as const,
|
|
185
185
|
// #endregion Discord.js base events
|
|
186
186
|
|
|
187
|
-
// #region
|
|
187
|
+
// #region Virello events
|
|
188
188
|
// Message commands chain
|
|
189
189
|
/** A non-bot message enters prefix parsing. */
|
|
190
190
|
PreMessageParsed: "preMessageParsed" as const,
|
|
@@ -329,7 +329,7 @@ export const Events = {
|
|
|
329
329
|
/** A context-menu command attempt finished, with success state and duration. */
|
|
330
330
|
ContextMenuCommandFinish: "contextMenuCommandFinish" as const,
|
|
331
331
|
|
|
332
|
-
// #endregion
|
|
332
|
+
// #endregion Virello events
|
|
333
333
|
} as const;
|
|
334
334
|
|
|
335
335
|
/** Module metadata attached to an error event. */
|
|
@@ -604,192 +604,207 @@ export interface AutocompleteInteractionPayload {
|
|
|
604
604
|
* Local key alias for the typed event augmentation.
|
|
605
605
|
* @internal
|
|
606
606
|
*/
|
|
607
|
-
declare const
|
|
607
|
+
declare const VirelloEvents: typeof Events;
|
|
608
608
|
|
|
609
|
-
/** Add
|
|
609
|
+
/** Add Virello events to the discord.js event map. */
|
|
610
610
|
declare module "discord.js" {
|
|
611
611
|
/** Framework event argument tuples. Listen using Events constants. */
|
|
612
612
|
interface ClientEvents {
|
|
613
|
-
// #region
|
|
613
|
+
// #region Virello load cycle events
|
|
614
614
|
/** A module was removed after successful cleanup. */
|
|
615
|
-
[
|
|
615
|
+
[VirelloEvents.ModuleUnloaded]: [
|
|
616
|
+
store: ModuleStore<Module>,
|
|
617
|
+
module: Module,
|
|
618
|
+
];
|
|
616
619
|
/** A module finished activation and entered its store. */
|
|
617
|
-
[
|
|
620
|
+
[VirelloEvents.ModuleLoaded]: [store: ModuleStore<Module>, module: Module];
|
|
618
621
|
|
|
619
622
|
/** A listener’s run method threw or rejected. */
|
|
620
|
-
[
|
|
623
|
+
[VirelloEvents.ListenerError]: [
|
|
624
|
+
error: unknown,
|
|
625
|
+
payload: ListenerErrorPayload,
|
|
626
|
+
];
|
|
621
627
|
/** A command’s application-registration hook failed. */
|
|
622
|
-
[
|
|
628
|
+
[VirelloEvents.CommandApplicationCommandRegistryError]: [
|
|
623
629
|
error: unknown,
|
|
624
630
|
command: Command,
|
|
625
631
|
];
|
|
626
632
|
/** Application command registration is starting. */
|
|
627
|
-
[
|
|
633
|
+
[VirelloEvents.ApplicationCommandRegistriesInitialising]: [];
|
|
628
634
|
/** The registration pass completed, with the registry map and elapsed milliseconds. */
|
|
629
|
-
[
|
|
635
|
+
[VirelloEvents.ApplicationCommandRegistriesRegistered]: [
|
|
630
636
|
registries: Map<string, ApplicationCommandRegistry>,
|
|
631
637
|
timeTaken: number,
|
|
632
638
|
];
|
|
633
639
|
/** One global or guild command list was replaced; a null guild ID means global. */
|
|
634
|
-
[
|
|
640
|
+
[VirelloEvents.ApplicationCommandRegistriesBulkOverwrite]: [
|
|
635
641
|
result: Collection<Snowflake, ApplicationCommand>,
|
|
636
642
|
guildId: string | null,
|
|
637
643
|
];
|
|
638
644
|
/** A global or guild bulk overwrite failed; a null guild ID means global. */
|
|
639
|
-
[
|
|
645
|
+
[VirelloEvents.ApplicationCommandRegistriesBulkOverwriteError]: [
|
|
640
646
|
error: unknown,
|
|
641
647
|
guildId: string | null,
|
|
642
648
|
];
|
|
643
649
|
|
|
644
650
|
/** A non-bot message enters prefix parsing. */
|
|
645
|
-
[
|
|
651
|
+
[VirelloEvents.PreMessageParsed]: [message: Message];
|
|
646
652
|
/** A message contains only the bot mention prefix. */
|
|
647
|
-
[
|
|
653
|
+
[VirelloEvents.MentionPrefixOnly]: [message: Message];
|
|
648
654
|
/** No configured or mention prefix matched the message. */
|
|
649
|
-
[
|
|
655
|
+
[VirelloEvents.NonPrefixedMessage]: [message: Message];
|
|
650
656
|
/** A message prefix matched, before command-name parsing. */
|
|
651
|
-
[
|
|
657
|
+
[VirelloEvents.PrefixedMessage]: [
|
|
658
|
+
message: Message,
|
|
659
|
+
prefix: string | RegExp,
|
|
660
|
+
];
|
|
652
661
|
|
|
653
662
|
/** No command name followed the matched prefix. */
|
|
654
|
-
[
|
|
663
|
+
[VirelloEvents.UnknownMessageCommandName]: [
|
|
655
664
|
payload: UnknownMessageCommandNamePayload,
|
|
656
665
|
];
|
|
657
666
|
/** The parsed message command name was not found. */
|
|
658
|
-
[
|
|
667
|
+
[VirelloEvents.UnknownMessageCommand]: [
|
|
668
|
+
payload: UnknownMessageCommandPayload,
|
|
669
|
+
];
|
|
659
670
|
/** A matched command has no messageRun handler. */
|
|
660
|
-
[
|
|
671
|
+
[VirelloEvents.CommandDoesNotHaveMessageCommandHandler]: [
|
|
661
672
|
payload: CommandDoesNotHaveMessageCommandHandler,
|
|
662
673
|
];
|
|
663
674
|
/** A message command is ready for precondition checks. */
|
|
664
|
-
[
|
|
675
|
+
[VirelloEvents.PreMessageCommandRun]: [
|
|
676
|
+
payload: PreMessageCommandRunPayload,
|
|
677
|
+
];
|
|
665
678
|
|
|
666
679
|
/** Message command preconditions returned a denial. */
|
|
667
|
-
[
|
|
680
|
+
[VirelloEvents.MessageCommandDenied]: [
|
|
668
681
|
error: UserError,
|
|
669
682
|
payload: MessageCommandDeniedPayload,
|
|
670
683
|
];
|
|
671
684
|
/** Message command preconditions passed; argument preparation and execution follow. */
|
|
672
|
-
[
|
|
685
|
+
[VirelloEvents.MessageCommandAccepted]: [
|
|
673
686
|
payload: MessageCommandAcceptedPayload,
|
|
674
687
|
];
|
|
675
688
|
|
|
676
689
|
/** A prepared message command is about to run. */
|
|
677
|
-
[
|
|
690
|
+
[VirelloEvents.MessageCommandRun]: [
|
|
678
691
|
message: Message,
|
|
679
692
|
command: Command,
|
|
680
693
|
payload: MessageCommandRunPayload,
|
|
681
694
|
];
|
|
682
695
|
/** A message command resolved successfully; the payload includes its result and duration. */
|
|
683
|
-
[
|
|
696
|
+
[VirelloEvents.MessageCommandSuccess]: [
|
|
697
|
+
payload: MessageCommandSuccessPayload,
|
|
698
|
+
];
|
|
684
699
|
/** The message-command run phase threw or rejected. Argument preparation failures are reported through ListenerError. */
|
|
685
|
-
[
|
|
700
|
+
[VirelloEvents.MessageCommandError]: [
|
|
686
701
|
error: unknown,
|
|
687
702
|
payload: MessageCommandErrorPayload,
|
|
688
703
|
];
|
|
689
704
|
/** A message command attempt finished, with success state and duration. */
|
|
690
|
-
[
|
|
705
|
+
[VirelloEvents.MessageCommandFinish]: [
|
|
691
706
|
message: Message,
|
|
692
707
|
command: Command,
|
|
693
708
|
payload: MessageCommandFinishPayload,
|
|
694
709
|
];
|
|
695
710
|
|
|
696
711
|
/** Sending the message command’s typing indicator failed. */
|
|
697
|
-
[
|
|
712
|
+
[VirelloEvents.MessageCommandTypingError]: [
|
|
698
713
|
error: Error,
|
|
699
714
|
payload: MessageCommandTypingErrorPayload,
|
|
700
715
|
];
|
|
701
716
|
|
|
702
717
|
/** One extension lifecycle hook completed successfully. */
|
|
703
|
-
[
|
|
718
|
+
[VirelloEvents.ExtensionLoaded]: [
|
|
704
719
|
hook: "setup" | "beforeLogin" | "afterLogin",
|
|
705
720
|
name: string | undefined,
|
|
706
721
|
];
|
|
707
722
|
|
|
708
723
|
/** An interaction handler’s parse method returned an Option without throwing. */
|
|
709
|
-
[
|
|
724
|
+
[VirelloEvents.InteractionHandlerParseSuccess]: [
|
|
710
725
|
option: Option<unknown>,
|
|
711
726
|
payload: InteractionHandlerParseSuccess,
|
|
712
727
|
];
|
|
713
728
|
/** A handler accepted an interaction with Some; its parsed value is included. */
|
|
714
|
-
[
|
|
729
|
+
[VirelloEvents.InteractionHandlerParseSome]: [
|
|
715
730
|
option: Option.Some<unknown>,
|
|
716
731
|
payload: InteractionHandlerParseSome,
|
|
717
732
|
];
|
|
718
733
|
/** A handler skipped an interaction with None. */
|
|
719
|
-
[
|
|
734
|
+
[VirelloEvents.InteractionHandlerParseNone]: [
|
|
720
735
|
option: Option.None,
|
|
721
736
|
payload: InteractionHandlerParseNone,
|
|
722
737
|
];
|
|
723
738
|
/** A handler’s parse method threw or rejected. */
|
|
724
|
-
[
|
|
739
|
+
[VirelloEvents.InteractionHandlerParseError]: [
|
|
725
740
|
error: unknown,
|
|
726
741
|
payload: InteractionHandlerParseError,
|
|
727
742
|
];
|
|
728
743
|
/** An accepted interaction handler’s run method threw or rejected. */
|
|
729
|
-
[
|
|
744
|
+
[VirelloEvents.InteractionHandlerError]: [
|
|
730
745
|
error: unknown,
|
|
731
746
|
payload: InteractionHandlerError,
|
|
732
747
|
];
|
|
733
748
|
|
|
734
749
|
/** An autocomplete interaction enters command lookup. */
|
|
735
|
-
[
|
|
750
|
+
[VirelloEvents.PossibleAutocompleteInteraction]: [
|
|
736
751
|
interaction: AutocompleteInteraction,
|
|
737
752
|
];
|
|
738
753
|
/** A command’s autocomplete handler threw or rejected. */
|
|
739
|
-
[
|
|
754
|
+
[VirelloEvents.CommandAutocompleteInteractionError]: [
|
|
740
755
|
error: unknown,
|
|
741
756
|
payload: AutocompleteInteractionPayload,
|
|
742
757
|
];
|
|
743
758
|
/** A command’s autocomplete handler completed successfully. */
|
|
744
|
-
[
|
|
759
|
+
[VirelloEvents.CommandAutocompleteInteractionSuccess]: [
|
|
745
760
|
payload: AutocompleteInteractionPayload,
|
|
746
761
|
];
|
|
747
762
|
|
|
748
763
|
// Chat input command chain
|
|
749
764
|
/** A slash interaction enters command lookup. */
|
|
750
|
-
[
|
|
765
|
+
[VirelloEvents.PossibleChatInputCommand]: [
|
|
751
766
|
interaction: ChatInputCommandInteraction,
|
|
752
767
|
];
|
|
753
768
|
/** No local command matched the slash interaction. */
|
|
754
|
-
[
|
|
769
|
+
[VirelloEvents.UnknownChatInputCommand]: [
|
|
755
770
|
payload: UnknownChatInputCommandPayload,
|
|
756
771
|
];
|
|
757
772
|
/** The matched command has no slash handler. */
|
|
758
|
-
[
|
|
773
|
+
[VirelloEvents.CommandDoesNotHaveChatInputCommandHandler]: [
|
|
759
774
|
payload: CommandDoesNotHaveChatInputCommandHandlerPayload,
|
|
760
775
|
];
|
|
761
776
|
/** A slash command is ready for precondition checks. */
|
|
762
|
-
[
|
|
777
|
+
[VirelloEvents.PreChatInputCommandRun]: [
|
|
763
778
|
payload: PreChatInputCommandRunPayload,
|
|
764
779
|
];
|
|
765
780
|
|
|
766
781
|
/** The slash command’s preconditions denied the invocation. */
|
|
767
|
-
[
|
|
782
|
+
[VirelloEvents.ChatInputCommandDenied]: [
|
|
768
783
|
error: UserError,
|
|
769
784
|
payload: ChatInputCommandDeniedPayload,
|
|
770
785
|
];
|
|
771
786
|
/** The slash command’s preconditions passed. */
|
|
772
|
-
[
|
|
787
|
+
[VirelloEvents.ChatInputCommandAccepted]: [
|
|
773
788
|
payload: ChatInputCommandAcceptedPayload,
|
|
774
789
|
];
|
|
775
790
|
|
|
776
791
|
/** An accepted slash handler is about to run. */
|
|
777
|
-
[
|
|
792
|
+
[VirelloEvents.ChatInputCommandRun]: [
|
|
778
793
|
interaction: ChatInputCommandInteraction,
|
|
779
794
|
command: ChatInputCommand,
|
|
780
795
|
payload: ChatInputCommandRunPayload,
|
|
781
796
|
];
|
|
782
797
|
/** A slash handler completed, with its return value and duration. */
|
|
783
|
-
[
|
|
798
|
+
[VirelloEvents.ChatInputCommandSuccess]: [
|
|
784
799
|
payload: ChatInputCommandSuccessPayload,
|
|
785
800
|
];
|
|
786
801
|
/** A slash command attempt threw or rejected. */
|
|
787
|
-
[
|
|
802
|
+
[VirelloEvents.ChatInputCommandError]: [
|
|
788
803
|
error: unknown,
|
|
789
804
|
payload: ChatInputCommandErrorPayload,
|
|
790
805
|
];
|
|
791
806
|
/** A slash command attempt finished, with success state and duration. */
|
|
792
|
-
[
|
|
807
|
+
[VirelloEvents.ChatInputCommandFinish]: [
|
|
793
808
|
interaction: ChatInputCommandInteraction,
|
|
794
809
|
command: ChatInputCommand,
|
|
795
810
|
payload: ChatInputCommandFinishPayload,
|
|
@@ -797,55 +812,55 @@ declare module "discord.js" {
|
|
|
797
812
|
|
|
798
813
|
// Context menu command chain
|
|
799
814
|
/** A context-menu interaction enters command lookup. */
|
|
800
|
-
[
|
|
815
|
+
[VirelloEvents.PossibleContextMenuCommand]: [
|
|
801
816
|
interaction: ContextMenuCommandInteraction,
|
|
802
817
|
];
|
|
803
818
|
/** No local command matched the context-menu interaction. */
|
|
804
|
-
[
|
|
819
|
+
[VirelloEvents.UnknownContextMenuCommand]: [
|
|
805
820
|
payload: UnknownContextMenuCommandPayload,
|
|
806
821
|
];
|
|
807
822
|
/** The matched command has no context-menu handler. */
|
|
808
|
-
[
|
|
823
|
+
[VirelloEvents.CommandDoesNotHaveContextMenuCommandHandler]: [
|
|
809
824
|
payload: CommandDoesNotHaveContextMenuCommandHandlerPayload,
|
|
810
825
|
];
|
|
811
826
|
/** A context-menu command is ready for precondition checks. */
|
|
812
|
-
[
|
|
827
|
+
[VirelloEvents.PreContextMenuCommandRun]: [
|
|
813
828
|
payload: PreContextMenuCommandRunPayload,
|
|
814
829
|
];
|
|
815
830
|
|
|
816
831
|
/** The context-menu command’s preconditions denied the invocation. */
|
|
817
|
-
[
|
|
832
|
+
[VirelloEvents.ContextMenuCommandDenied]: [
|
|
818
833
|
error: UserError,
|
|
819
834
|
payload: ContextMenuCommandDeniedPayload,
|
|
820
835
|
];
|
|
821
836
|
/** The context-menu command’s preconditions passed. */
|
|
822
|
-
[
|
|
837
|
+
[VirelloEvents.ContextMenuCommandAccepted]: [
|
|
823
838
|
payload: ContextMenuCommandAcceptedPayload,
|
|
824
839
|
];
|
|
825
840
|
|
|
826
841
|
/** An accepted context-menu handler is about to run. */
|
|
827
|
-
[
|
|
842
|
+
[VirelloEvents.ContextMenuCommandRun]: [
|
|
828
843
|
interaction: ContextMenuCommandInteraction,
|
|
829
844
|
command: ContextMenuCommand,
|
|
830
845
|
payload: ContextMenuCommandRunPayload,
|
|
831
846
|
];
|
|
832
847
|
/** A context-menu handler completed, with its return value and duration. */
|
|
833
|
-
[
|
|
848
|
+
[VirelloEvents.ContextMenuCommandSuccess]: [
|
|
834
849
|
payload: ContextMenuCommandSuccessPayload,
|
|
835
850
|
];
|
|
836
851
|
/** A context-menu command attempt threw or rejected. */
|
|
837
|
-
[
|
|
852
|
+
[VirelloEvents.ContextMenuCommandError]: [
|
|
838
853
|
error: unknown,
|
|
839
854
|
payload: ContextMenuCommandErrorPayload,
|
|
840
855
|
];
|
|
841
856
|
/** A context-menu command attempt finished, with success state and duration. */
|
|
842
|
-
[
|
|
857
|
+
[VirelloEvents.ContextMenuCommandFinish]: [
|
|
843
858
|
interaction: ContextMenuCommandInteraction,
|
|
844
859
|
command: ContextMenuCommand,
|
|
845
860
|
payload: ContextMenuCommandFinishPayload,
|
|
846
861
|
];
|
|
847
862
|
|
|
848
|
-
// #endregion
|
|
863
|
+
// #endregion Virello load cycle events
|
|
849
864
|
|
|
850
865
|
// #region Termination
|
|
851
866
|
/** Additional event names may supply arbitrary arguments. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { VirelloClient } from "../../core/client/VirelloClient";
|
|
2
2
|
import { Extension } from "../../core/lifecycle/Extension";
|
|
3
3
|
import { container } from "../../core/modules/index";
|
|
4
4
|
import { LocaleManager } from "./index";
|
|
@@ -9,7 +9,7 @@ export class LocaleExtension extends Extension {
|
|
|
9
9
|
* Register translation resources and helpers during client construction.
|
|
10
10
|
* @param client - Client being configured.
|
|
11
11
|
*/
|
|
12
|
-
static override setup(client:
|
|
12
|
+
static override setup(client: VirelloClient): void {
|
|
13
13
|
container.i18n = new LocaleManager(
|
|
14
14
|
client.options.extensions?.localisation || undefined,
|
|
15
15
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { VirelloClient } from "../../core/client/VirelloClient";
|
|
2
2
|
import { Extension } from "../../core/lifecycle/Extension";
|
|
3
3
|
import { loadListeners, PatternCommandStore } from "./index";
|
|
4
4
|
/** Built-in extension for regex message commands. Configure it through client.options.extensions. */
|
|
@@ -7,7 +7,7 @@ export class PatternExtension extends Extension {
|
|
|
7
7
|
* Register regex message commands during client construction.
|
|
8
8
|
* @param client - Client being configured.
|
|
9
9
|
*/
|
|
10
|
-
static override setup(client:
|
|
10
|
+
static override setup(client: VirelloClient): void {
|
|
11
11
|
client.modules.register(new PatternCommandStore());
|
|
12
12
|
loadListeners();
|
|
13
13
|
}
|
|
@@ -32,7 +32,7 @@ export class RedisBackend implements TaskBackend {
|
|
|
32
32
|
constructor(
|
|
33
33
|
private readonly options: TaskSchedulerOptions & { redis_url: string },
|
|
34
34
|
) {
|
|
35
|
-
const prefix = `
|
|
35
|
+
const prefix = `virello:tasks:v1:{${encodeURIComponent(options.queue ?? "scheduled-tasks")}}`;
|
|
36
36
|
this.keys = [`${prefix}:jobs`, `${prefix}:due`, `${prefix}:leases`];
|
|
37
37
|
}
|
|
38
38
|
async connect(): Promise<void> {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { VirelloClient } from "../../core/client/VirelloClient";
|
|
2
2
|
import { Extension } from "../../core/lifecycle/Extension";
|
|
3
3
|
import { container } from "../../core/modules/index";
|
|
4
4
|
import { loadListeners, TaskScheduler, TaskStore } from "./index";
|
|
@@ -10,7 +10,7 @@ export class TasksExtension extends Extension {
|
|
|
10
10
|
* Register scheduled task execution during client construction.
|
|
11
11
|
* @param client - Client being configured.
|
|
12
12
|
*/
|
|
13
|
-
static override setup(client:
|
|
13
|
+
static override setup(client: VirelloClient): void {
|
|
14
14
|
const options = client.options.extensions?.scheduledtasks || {};
|
|
15
15
|
const tasks = new TaskScheduler(options);
|
|
16
16
|
container.tasks = tasks;
|
|
@@ -157,7 +157,7 @@ export interface RepeatedTask {
|
|
|
157
157
|
options: TaskOptions;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
/** Augment
|
|
160
|
+
/** Augment virello with your task names and payloads. */
|
|
161
161
|
export interface Tasks {}
|
|
162
162
|
/** Task names declared in the augmentable Tasks interface. */
|
|
163
163
|
export type TaskName = keyof Tasks;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { VirelloClient } from "../../core/client/VirelloClient";
|
|
2
2
|
import { Extension } from "../../core/lifecycle/Extension";
|
|
3
3
|
import { Services } from "./index";
|
|
4
4
|
/** Built-in extension for shared service modules. Configure it through client.options.extensions. */
|
|
@@ -7,7 +7,7 @@ export class ServicesExtension extends Extension {
|
|
|
7
7
|
* Register shared service modules during client construction.
|
|
8
8
|
* @param client - Client being configured.
|
|
9
9
|
*/
|
|
10
|
-
static override setup(client:
|
|
10
|
+
static override setup(client: VirelloClient): void {
|
|
11
11
|
client.services = new Services();
|
|
12
12
|
client.modules.register(client.services.store);
|
|
13
13
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { VirelloClient } from "../../core/client/VirelloClient";
|
|
2
2
|
import { Extension } from "../../core/lifecycle/Extension";
|
|
3
3
|
import { loadListeners, loadPreconditions } from "./index";
|
|
4
4
|
/** Built-in extension for subcommand dispatch and checks. Configure it through client.options.extensions. */
|
|
@@ -7,7 +7,7 @@ export class SubcommandsExtension extends Extension {
|
|
|
7
7
|
* Register subcommand dispatch and checks during client construction.
|
|
8
8
|
* @param client - Client being configured.
|
|
9
9
|
*/
|
|
10
|
-
static override setup(client:
|
|
10
|
+
static override setup(client: VirelloClient): void {
|
|
11
11
|
loadPreconditions();
|
|
12
12
|
const options = client.options.extensions?.subcommands;
|
|
13
13
|
if (options !== false && options?.logErrors !== false) loadListeners();
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Virello client, modules, commands, events, extensions, and shared helpers. The separate engine API is available from virello/engine.
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
5
|
import "./core/runtime";
|
package/src/public/client.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Create the
|
|
2
|
+
* Create the Virello Discord client, access shared services, and configure framework logging.
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
5
|
import "../core/runtime";
|
|
6
6
|
|
|
7
7
|
export { type Container, container } from "../core/Container";
|
|
8
|
-
export * from "../core/client/
|
|
8
|
+
export * from "../core/client/VirelloClient";
|
|
9
9
|
export * from "../core/logging/index";
|
|
10
10
|
export { version } from "../version";
|
|
@@ -36,14 +36,14 @@ export interface ShardConfig {
|
|
|
36
36
|
assignmentPollIntervalMs?: number;
|
|
37
37
|
maxDisconnectedLifetimeMs?: number;
|
|
38
38
|
}
|
|
39
|
-
/** Called only by
|
|
39
|
+
/** Called only by VirelloClient; ordinary clients never read transport credentials or open connections. */
|
|
40
40
|
export function shardConfig(): ShardConfig | undefined {
|
|
41
|
-
const input = process.env.
|
|
41
|
+
const input = process.env.VIRELLO_SHARD;
|
|
42
42
|
if (input === undefined) return undefined;
|
|
43
43
|
if (!process.send || !process.connected)
|
|
44
44
|
throw new ShardError(
|
|
45
45
|
"CONFIG",
|
|
46
|
-
"
|
|
46
|
+
"VIRELLO_SHARD is reserved for ShardManager-owned Bun IPC children.",
|
|
47
47
|
);
|
|
48
48
|
if (Buffer.byteLength(input) > 8192)
|
|
49
49
|
throw new ShardError("CONFIG", "Invalid managed shard configuration.");
|
|
@@ -83,7 +83,7 @@ interface Lifecycle {
|
|
|
83
83
|
logger: LoggerLike;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
/** Typed messaging on one managed
|
|
86
|
+
/** Typed messaging on one managed VirelloClient. Handlers run local registered code only. */
|
|
87
87
|
export class ShardLink extends ShardMessenger {
|
|
88
88
|
private readonly handlers = new Map<string, Handler>();
|
|
89
89
|
private readonly active = new Map<string, Active>();
|
|
@@ -111,7 +111,7 @@ export class ShardLink extends ShardMessenger {
|
|
|
111
111
|
};
|
|
112
112
|
private dormantReason?: string;
|
|
113
113
|
/**
|
|
114
|
-
* Created by
|
|
114
|
+
* Created by VirelloClient. Use client.sharding to register handlers and send requests.
|
|
115
115
|
* @internal
|
|
116
116
|
*/
|
|
117
117
|
public constructor(
|
|
@@ -2,7 +2,7 @@ import { type Client, WebSocketManager } from "discord.js";
|
|
|
2
2
|
import { ShardError } from "../types";
|
|
3
3
|
|
|
4
4
|
/** discord.js 14 adapter: retire its whole gateway manager to discard cached shard count/session resume data.
|
|
5
|
-
* Keep the
|
|
5
|
+
* Keep the VirelloClient, modules, REST client and application listeners alive across dormant assignments.
|
|
6
6
|
* The exported WebSocketManager's lifecycle methods are private in its TypeScript declarations.
|
|
7
7
|
*/
|
|
8
8
|
export class ManagedGateway {
|
|
@@ -424,7 +424,7 @@ export class ShardCoordinator {
|
|
|
424
424
|
if (this.transition)
|
|
425
425
|
return new Response("Coordinator draining shards", { status: 503 });
|
|
426
426
|
const connectionId = crypto.randomUUID();
|
|
427
|
-
const host = this.hosts.get(request.headers.get("x-
|
|
427
|
+
const host = this.hosts.get(request.headers.get("x-virello-worker") ?? "");
|
|
428
428
|
if (
|
|
429
429
|
!host ||
|
|
430
430
|
!tokenMatches(request.headers.get("authorization"), host.token)
|
|
@@ -443,7 +443,7 @@ export class ShardCoordinator {
|
|
|
443
443
|
return new Response("Unauthorized", { status: 401 });
|
|
444
444
|
}
|
|
445
445
|
if (request.method === "HEAD") {
|
|
446
|
-
const instance = request.headers.get("x-
|
|
446
|
+
const instance = request.headers.get("x-virello-instance");
|
|
447
447
|
if (!identifier.allows(instance))
|
|
448
448
|
return new Response(null, { status: 400 });
|
|
449
449
|
const reason = this.sessions.has(`${host.id}/${instance}`)
|
|
@@ -451,7 +451,7 @@ export class ShardCoordinator {
|
|
|
451
451
|
: "";
|
|
452
452
|
return new Response(null, {
|
|
453
453
|
status: reason ? 409 : 204,
|
|
454
|
-
headers: { "x-
|
|
454
|
+
headers: { "x-virello-reason": reason },
|
|
455
455
|
});
|
|
456
456
|
}
|
|
457
457
|
const reject = (status: number, reason: string, text: string) => {
|
|
@@ -493,7 +493,7 @@ export class ShardCoordinator {
|
|
|
493
493
|
"native_upgrade_required",
|
|
494
494
|
"Native WebSocket upgrade required",
|
|
495
495
|
);
|
|
496
|
-
const instance = request.headers.get("x-
|
|
496
|
+
const instance = request.headers.get("x-virello-instance");
|
|
497
497
|
if (!identifier.allows(instance))
|
|
498
498
|
return reject(400, "invalid_identity", "Invalid identity");
|
|
499
499
|
if (this.sessions.has(`${host.id}/${instance}`))
|
|
@@ -354,8 +354,8 @@ export class ShardManager extends ShardMessenger {
|
|
|
354
354
|
method: "HEAD",
|
|
355
355
|
headers: {
|
|
356
356
|
authorization: `Bearer ${this.options.token}`,
|
|
357
|
-
"x-
|
|
358
|
-
"x-
|
|
357
|
+
"x-virello-worker": this.options.id,
|
|
358
|
+
"x-virello-instance": this.instance,
|
|
359
359
|
},
|
|
360
360
|
redirect: "error",
|
|
361
361
|
signal: AbortSignal.any([
|
|
@@ -380,7 +380,7 @@ export class ShardManager extends ShardMessenger {
|
|
|
380
380
|
"CONFIG",
|
|
381
381
|
"Coordinator admission endpoint is unavailable; check the URL and framework versions.",
|
|
382
382
|
);
|
|
383
|
-
const reason = response.headers.get("x-
|
|
383
|
+
const reason = response.headers.get("x-virello-reason");
|
|
384
384
|
return reason === "host_already_connected"
|
|
385
385
|
? reason
|
|
386
386
|
: "coordinator_unavailable";
|
|
@@ -391,8 +391,8 @@ export class ShardManager extends ShardMessenger {
|
|
|
391
391
|
perMessageDeflate: false,
|
|
392
392
|
headers: {
|
|
393
393
|
authorization: `Bearer ${this.options.token}`,
|
|
394
|
-
"x-
|
|
395
|
-
"x-
|
|
394
|
+
"x-virello-worker": this.options.id,
|
|
395
|
+
"x-virello-instance": this.instance,
|
|
396
396
|
},
|
|
397
397
|
});
|
|
398
398
|
this.socket = socket;
|
|
@@ -641,7 +641,7 @@ export class ShardManager extends ShardMessenger {
|
|
|
641
641
|
env: {
|
|
642
642
|
...process.env,
|
|
643
643
|
...this.options.env,
|
|
644
|
-
|
|
644
|
+
VIRELLO_SHARD: encode(
|
|
645
645
|
{
|
|
646
646
|
shard: null,
|
|
647
647
|
count: this.count,
|
package/src/sharding/stats.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Client } from "discord.js";
|
|
|
3
3
|
import { ShardError, type ShardStats, type ShardStatsResult } from "./types";
|
|
4
4
|
|
|
5
5
|
// Internal RPC uses the usual coordinator routing, ownership checks and request limits.
|
|
6
|
-
export const statsRequest = "
|
|
6
|
+
export const statsRequest = "virello:stats";
|
|
7
7
|
const nonnegative = type("number >= 0");
|
|
8
8
|
const count = type("number.integer >= 0");
|
|
9
9
|
const schema = type({
|
package/src/sharding/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LoggerLike } from "../core/logging/LoggerLike";
|
|
2
2
|
|
|
3
|
-
/** Add named { input, output } request contracts by augmenting
|
|
3
|
+
/** Add named { input, output } request contracts by augmenting virello. Inputs and outputs must be plain JSON values. */
|
|
4
4
|
export interface ShardRequests {}
|
|
5
5
|
/** Names declared in ShardRequests. */
|
|
6
6
|
export type ShardRequestName = keyof ShardRequests & string;
|
|
@@ -211,7 +211,7 @@ export interface ShardCoordinatorOptions {
|
|
|
211
211
|
sessionStartLimit?: ShardSessionLimit;
|
|
212
212
|
/** Message, buffer, concurrency, and deadline limits. Omitted fields use ShardLimits defaults. */
|
|
213
213
|
limits?: ShardLimits;
|
|
214
|
-
/** Logger to reuse without taking ownership. Defaults to an owned
|
|
214
|
+
/** Logger to reuse without taking ownership. Defaults to an owned Virello console logger. */
|
|
215
215
|
logger?: LoggerLike;
|
|
216
216
|
}
|
|
217
217
|
/** Child crash recovery settings. Delays use exponential backoff with jitter. */
|
|
@@ -267,7 +267,7 @@ export interface ShardManagerOptions {
|
|
|
267
267
|
maxDisconnectedLifetimeMs?: number;
|
|
268
268
|
/** Optional minimum local process pool, including standby capacity. Must fit the host's configured maxShards. */
|
|
269
269
|
processCount?: number;
|
|
270
|
-
/** Logger to reuse without taking ownership. Defaults to an owned
|
|
270
|
+
/** Logger to reuse without taking ownership. Defaults to an owned Virello console logger. */
|
|
271
271
|
logger?: LoggerLike;
|
|
272
272
|
}
|
|
273
273
|
/** Copy of one local process slot’s latest supervisor state. */
|
|
@@ -26,7 +26,7 @@ const originalApplicationCommandToProxy = new WeakMap<
|
|
|
26
26
|
CommandTarget<Command>
|
|
27
27
|
>();
|
|
28
28
|
|
|
29
|
-
/** Decorator function that applies given options to any
|
|
29
|
+
/** Decorator function that applies given options to any Virello module */
|
|
30
30
|
export function ApplyOptions<T extends Module.Options>(
|
|
31
31
|
optionsOrFn: T | ((parameters: ApplyOptionsCallbackParameters) => T),
|
|
32
32
|
): ClassDecorator {
|