Skip to content

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

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

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

Conversation

@mcmire
Copy link
Copy Markdown
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 maintain backward compatibility, we add a new event, :stateChanged, rather than replacing the existing event. We also 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 state publication path by emitting an additional event and expanding event typing, which could impact any controller/messenger wiring and listener assumptions. Backward compatibility is maintained, but consumers may see extra publishes and new lint failures when using :stateChange.

Overview
Adds a new state update event name across controllers. BaseController now emits and registers initial payloads for both ${Controller}:stateChange and the new ${Controller}:stateChanged, and introduces/export ControllerStateChangedEvent while marking ControllerStateChangeEvent as deprecated.

Guides and nudges consumers to migrate. Controller guidelines/docs are updated to prefer :stateChanged, tests are updated to validate both events (and adjust expectations for additional publishes), and ESLint adds a custom no-restricted-syntax rule to flag subscribing to or delegating :stateChange (with new suppressions where needed).

Written by Cursor Bugbot for commit 5d5e0df. 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
expect(messengerSpy).toHaveBeenNthCalledWith(
// 1. AccountsController:stateChange
2,
expect(messengerSpy).toHaveBeenCalledWith(
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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.)

cursoragent and others added 2 commits March 31, 2026 02:32
…leOptions

The getNoRestrictedSyntaxEntries function was redundant with the
pre-existing collectExistingRuleOptions helper. It was also less
robust: it used '?? []' instead of an Array.isArray guard, meaning it
would throw a TypeError if an upstream config ever set the rule to a
non-array value (e.g. 'off' or 0).

Replace the call site with collectExistingRuleOptions('no-restricted-syntax',
[typescript]) and remove the now-unused helper.

Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
Copy link
Copy Markdown

@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 1 potential issue.

Fix All in Cursor

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

hmalik88
hmalik88 previously approved these changes Mar 31, 2026
Copy link
Copy Markdown
Contributor

@hmalik88 hmalik88 left a comment

Choose a reason for hiding this comment

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

Approved for accounts.

cryptodev-2s
cryptodev-2s previously approved these changes Mar 31, 2026
@mcmire mcmire dismissed stale reviews from cryptodev-2s and hmalik88 via 737783d March 31, 2026 19:32
Copy link
Copy Markdown
Contributor

@cryptodev-2s cryptodev-2s left a comment

Choose a reason for hiding this comment

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

LGTM!

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.

4 participants