Skip to content

Deprecate <ControllerName>:stateChange in favor of :stateChanged#8187

Open
mcmire wants to merge 5 commits intomainfrom
deprecate-state-change-event
Open

Deprecate <ControllerName>:stateChange in favor of :stateChanged#8187
mcmire wants to merge 5 commits intomainfrom
deprecate-state-change-event

Conversation

@mcmire
Copy link
Contributor

@mcmire mcmire commented Mar 11, 2026

Explanation

Since the :stateChange event was added to BaseController, we have added a guideline which suggests that engineers use past tense for all event names. This commit updates BaseController to align with that guideline. To achieve backward compatibility, we add a new event, :stateChanged, rather than replacing the existing event. We deprecate subscribing to or delegating :stateChange by adding some custom ESLint rules.

References

We are about to add the :cacheUpdate to BaseDataService here, so I thought I'd deprecate BaseController:stateChange so we can add BaseDataService:cacheUpdated instead.

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Touches BaseController’s core event surface: it now emits an additional state event and updates typings/linting, which could affect downstream consumers and event expectations despite backward compatibility.

Overview
BaseController now publishes a new ${ControllerName}:stateChanged event (and registers its initial payload) alongside the existing ${ControllerName}:stateChange, and exports the new ControllerStateChangedEvent type while marking ControllerStateChangeEvent as deprecated.

Repo-wide guidance is updated to prefer :stateChanged, and ESLint now flags subscribing to or delegating :stateChange via a custom no-restricted-syntax selector rule (with corresponding eslint-suppressions.json updates). Tests and docs are adjusted to account for the extra publish calls and the new event name.

Written by Cursor Bugbot for commit 635f6df. This will update automatically on new commits. Configure here.

@mcmire mcmire mentioned this pull request Mar 11, 2026
4 tasks
@mcmire mcmire force-pushed the deprecate-state-change-event branch from dbd3929 to d8d71e5 Compare March 11, 2026 21:04
@mcmire mcmire changed the title Deprecate BaseController:stateChange in favor of :stateChanged Deprecate <ControllerName>:stateChange in favor of :stateChanged Mar 11, 2026
Since the `:stateChange` event was added to `BaseController`, we have
added a guideline asking engineers to use past tense for all event
names. This commit updates BaseController to align with that guideline.
To achieve backward compatibility, we add a new event, `:stateChanged`,
rather than replacing the existing event. We deprecate `:stateChange` by
adding some custom ESLint rules.
@mcmire mcmire force-pushed the deprecate-state-change-event branch from d8d71e5 to 41daada Compare March 12, 2026 18:51
@mcmire mcmire marked this pull request as ready for review March 12, 2026 19:04
@mcmire mcmire requested review from a team as code owners March 12, 2026 19:04
// replaces the rule entirely rather than merging arrays.
'no-restricted-syntax': [
'error',
...getNoRestrictedSyntaxEntries(typescript),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Feels like there ought to be a better way to do this...

expect(messengerSpy).toHaveBeenNthCalledWith(
// 1. AccountsController:stateChange
2,
expect(messengerSpy).toHaveBeenCalledWith(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The name of this test indicates that all we care about is that the accountAdded event is published, so I not only fixed the test but changed it to reflect that.

expect(messengerSpy).toHaveBeenNthCalledWith(
// 1. AccountsController:stateChange
2,
expect(messengerSpy).toHaveBeenCalledWith(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Similar story here.

accountsController.state.internalAccounts.selectedAccount,
).toStrictEqual(mockNonEvmAccount.id);

expect(messengerSpy.mock.calls).toHaveLength(2); // state change and then selectedAccountChange
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Similar story; based on the test name it seems all we care about is that the selectedEvmAccountChange event is not published.


// check the 3rd call since the 2nd one is for the
// event stateChange
// Some of these calls are for state changes
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since there is a new state change event it changes the number of expected events.

>['type'] extends MessengerEvents<ControllerMessenger>['type']
? ControllerMessenger
: never
: ControllerStateChangedEvent<
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Controllers must at least support :stateChange or :stateChanged. (We don't want to require that controllers support both :stateChange and :stateChanged, so we can't use ControllerEvents here anymore.)

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

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