Skip to content

refactor!: remove global context, update command/event attachment#59

Merged
vrdons merged 3 commits intomainfrom
remove_context
Mar 8, 2026
Merged

refactor!: remove global context, update command/event attachment#59
vrdons merged 3 commits intomainfrom
remove_context

Conversation

@vrdons
Copy link
Member

@vrdons vrdons commented Mar 8, 2026

BREAKING CHANGE: The global context module has been removed. Commands and events must now access the client and logger via instance properties after being attached. The prefix option is now a function. Update your usage accordingly.

BREAKING CHANGE: The global context module has been removed. Commands
and events must now access the client and logger via instance properties
after being attached. The `prefix` option is now a function. Update your
usage accordingly.
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces significant architectural refactorings aimed at enhancing the modularity, flexibility, and maintainability of the framework. The core change involves decoupling commands and events from a global context, requiring them to be explicitly attached to a client instance. This shift, along with a more dynamic prefix handling and an improved module loading system, provides greater control and clarity over component lifecycles and dependencies. The changes also include updates to the build process and internationalization features to support these architectural improvements.

Highlights

  • Global Context Removal: The global context module (src/context.ts) has been entirely removed, eliminating the setClient and clearClient functions. Commands and events now access client and logger instances via dedicated attach methods, promoting explicit dependency injection and improving modularity.
  • Updated Command and Event Attachment: Commands and events (CommandBuilder, EventBuilder) no longer rely on a global client. Instead, they feature an attach(client: Client) method, which binds them to a specific client instance. A new Command class has been introduced as a simplified wrapper for CommandBuilder.
  • Prefix Option as a Function: The prefix option in the client configuration has been refactored from a static string or object to a dynamic function (PrefixFn). This function now receives a Context object, allowing for more flexible and context-aware prefix determination.
  • Enhanced Module Loading System: The Client now includes a more robust registerExport mechanism capable of handling various module export types, including CommandBuilder, EventBuilder, and factory functions, streamlining how commands and events are discovered and initialized.
  • Improved Internationalization (i18n) Handling: The Context object now dynamically determines the default language using a new getDefaultLang client option, which can be a custom function. i18n keys in event handlers have been updated to a nested format (e.g., error:command.notfound).
  • Build Process and Type Definition Improvements: The build script now includes a dist directory cleanup and minification. Type definition generation has been enhanced with tsc-alias and a new script to create CJS-specific type definitions (.d.cts files), improving compatibility for different module systems.
Changelog
  • .npmignore
    • Added '.prettierrc' to ignored files.
    • Ensured a newline at the end of the file.
  • examples/basic_client/commands/ping.cjs
    • Added a new example command 'ping' demonstrating the new Command class and context usage.
  • examples/basic_client/events/ready.cjs
    • Renamed from ready.js to ready.cjs.
    • Converted to CommonJS module format.
    • Updated to export the EventBuilder instance as the default export.
  • examples/basic_client/index.js
    • Updated client configuration to use a function for the prefix option.
    • Removed direct usage of arox.setClient and arox.clearClient.
    • Removed an inline command definition, relying on the new module loading system.
    • Added includePaths to specify directories for commands and events.
  • examples/basic_client/locales/en-US/error.json
    • Refactored i18n error keys from flat (command.notfound) to nested (command.notfound).
  • package-lock.json
    • Updated package version from 0.1.2-beta.1 to 0.1.2-beta.2.
    • Added tsc-alias and its associated dependencies (anymatch, array-union, binary-extensions, chokidar, commander, dir-glob, fsevents, get-tsconfig, globby, ignore, is-binary-path, mylas, normalize-path, path-type, plimit-lit, queue-lit, readdirp, resolve-pkg-maps, slash).
  • package.json
    • Updated package version from 0.1.2-beta.1 to 0.1.2-beta.2.
    • Added imports field for type aliases.
    • Refined exports field to specify separate type definitions for CommonJS (.d.cts) and ES Modules (.d.ts).
    • Modified build:dts script to include tsc-alias and a new createCjsTypes.js script for comprehensive type generation.
    • Added tsc-alias as a development dependency.
  • scripts/build.js
    • Added a step to recursively remove the dist directory before building.
    • Enabled minify option for esbuild output.
  • scripts/createCjsTypes.js
    • Added a new script to generate dist/index.d.cts for CommonJS type definitions.
  • src/context.ts
    • Removed the global context module, including currentClient, setClient, and clearClient.
  • src/events/interaction.ts
    • Exported the EventBuilder instance as the default export.
    • Updated i18n key format from error.command.notfound to error:command.notfound.
    • Removed explicit ctx.locale = interaction.locale assignment, relying on the new getDefaultLang mechanism.
  • src/events/message.ts
    • Exported the EventBuilder instance as the default export.
    • Modified prefix access to be a function call context.client.prefix(new Context(...)).
    • Updated i18n key format from error.command.notfound to error:command.notfound.
  • src/events/ready.ts
    • Exported the EventBuilder instance as the default export.
  • src/index.ts
    • Removed the export of the now-deleted context.js module.
    • Added export of utils/index.js.
  • src/structures/builder/Command.ts
    • Removed dependency on global currentClient.
    • Introduced private fields (#client, #logger, #attached) to manage client instance internally.
    • Added an attach method to explicitly bind the command to a Client instance.
    • Introduced a new Command class to simplify command definition, allowing onMessage and onInteraction to be passed directly in the constructor.
  • src/structures/builder/Context.ts
    • Defined InteractionContextJSON and MessageContextJSON interfaces for structured context data.
    • Updated toJSON methods to return the newly defined InteractionContextJSON or MessageContextJSON types.
    • Implemented dynamic locale initialization using the client's getDefaultLang option.
  • src/structures/builder/Event.ts
    • Removed dependency on global currentClient.
    • Introduced private fields (#client, #logger) to manage client instance internally.
    • Added an attach method to explicitly bind the event to a Client instance.
  • src/structures/core/Client.ts
    • Removed calls to setClient and clearClient.
    • Updated the prefix property to be a PrefixFn type.
    • Added getDefaultLang option to client configuration for dynamic locale resolution.
    • Implemented registerModuleExports and registerExport methods for a flexible module loading system, supporting various export types.
    • Updated includePaths resolution to handle both absolute and relative paths.
  • src/utils/Files.ts
    • Extended getFiles utility to include .cjs and .mjs file extensions during file discovery.
  • src/utils/logger/ILogger.ts
    • Updated the description for LogLevel.None from 'An unknown or uncategorized level' to 'An uncategorized level'.
  • src/utils/logger/Logger.ts
    • Updated type definitions for logger methods to use LoggerValues (derived from Parameters<Console['log']>).
  • src/utils/util.ts
    • Removed the getPrefix utility function.
    • Added allowedLocales array and toAllowedLocale function for locale validation.
    • Introduced getDefaultLang function to determine the appropriate locale based on interaction or message context.
  • tsconfig.json
    • Removed the path alias for @context.
  • types/client.d.ts
    • Removed FrameworkPaths and PrefixOptions interfaces.
    • Introduced PrefixFn and GetDefaultLangFn types for more flexible prefix and language handling.
    • Added AttachableExport, ModuleExport, and ModuleExportFactory types to support the new modular loading system.
  • types/logger.d.ts
    • Added Console import for type definitions.
    • Defined LoggerValues type as Parameters<Console['log']> for logger method arguments.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@vrdons
Copy link
Member Author

vrdons commented Mar 8, 2026

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a major and beneficial refactoring by removing the global client context, which makes the architecture cleaner and more robust. Commands and events are now explicitly attached to the client instance. The module loading system has been significantly improved to be more flexible and extensible, supporting various export patterns including factory functions. Additionally, the project's dual CJS/ESM package support has been enhanced. My review includes a few suggestions, mainly concerning a potential infinite recursion in the new module loader and a misconfiguration in package.json.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a major and well-executed refactor that removes the global client context, replacing it with a more robust attachment system for commands and events. This significantly improves the framework's design, making it more modular and testable. The changes are consistent across the codebase, and the new APIs for creating commands and handling modules are a great improvement. I've found a few issues to address: a potential infinite recursion bug in the new module loader, some unreachable code, and a bug in one of the updated examples. Overall, this is excellent work.

Comment on lines 76 to 80
if (ctx.isMessage()) {
return toAllowedLocale(ctx.data.guild?.preferredLocale) ?? Locale.EnglishUS;
}
return Locale.EnglishUS;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The type of ctx is Context<ChatInputCommandInteraction | Message>, which means ctx.isInteraction() or ctx.isMessage() will always be true within this function. The final if (ctx.isMessage()) block and the subsequent return statement are structured in a way that makes the final return unreachable. This can be simplified.

	return toAllowedLocale(ctx.data.guild?.preferredLocale) ?? Locale.EnglishUS;
}

vrdons added 2 commits March 8, 2026 12:53
Add MAX_EXPORT_FACTORY_DEPTH constant and enforce it in registerExport
to prevent infinite recursion when registering export factories. Rename
messages.ts to lang.ts and update imports. Remove unused prefix log and
package.json imports field.
@vrdons vrdons merged commit f848868 into main Mar 8, 2026
5 checks passed
@vrdons vrdons deleted the remove_context branch March 8, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant