Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ When adding or updating controllers in packages, follow these guidelines:
- Controller classes should extend `BaseController`.
- Controllers should not be stateless; if a controller does not have state, it should be a service.
- The controller should define a public messenger type.
- All messenger actions and events should be publicly defined. The default set should include the `:getState` action and `:stateChange` event.
- All messenger actions and events should be publicly defined. The default set should include the `:getState` action and `:stateChanged` event.
- All actions and events the messenger uses from other controllers and services should also be declared in the messenger type.
- Controllers should initialize state by combining default and provided state. Provided state should be optional.
- The constructor should take `messenger` and `state` options at a minimum.
Expand Down
36 changes: 18 additions & 18 deletions docs/code-guidelines/controller-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class FooController extends BaseController</* ... */> {

## Provide a default representation of state

Each controller needs a default representation in order to fully initialize itself when [receiving a partial representation of state](#accept-an-optional-partial-representation-of-state). A default representation of state is also useful when testing interactions with a controller's `*:stateChange` event.
Each controller needs a default representation in order to fully initialize itself when [receiving a partial representation of state](#accept-an-optional-partial-representation-of-state). A default representation of state is also useful when testing interactions with a controller's `*:stateChanged` event.

A function which returns this default representation should be defined and exported. It should be called `getDefault${ControllerName}State`.

Expand Down Expand Up @@ -226,7 +226,7 @@ const fooController = new FooController({

If the recipient controller uses a messenger, however, the callback pattern is unnecessary. Using the messenger not only aligns the controller with `BaseController`, but also reduces the number of options that consumers need to remember in order to use the controller:

✅ **The constructor subscribes to the `BarController:stateChange` event**
✅ **The constructor subscribes to the `BarController:stateChanged` event**

```typescript
/* === This repo: packages/foo-controller/src/FooController.ts === */
Expand All @@ -247,7 +247,7 @@ class FooController extends BaseController<
constructor({ messenger /*, ... */ }, { messenger: FooControllerMessenger }) {
super({ messenger /* ... */ });

messenger.subscribe('BarController:stateChange', (state) => {
messenger.subscribe('BarController:stateChanged', (state) => {
// do something with the state
});
}
Expand Down Expand Up @@ -280,7 +280,7 @@ const fooControllerMessenger = new Messenger<
parent: rootMessenger,
});
rootMessenger.delegate({
events: ['BarController:stateChange'],
events: ['BarController:stateChanged'],
messenger: fooControllerMessenger,
});
const fooController = new FooController({
Expand Down Expand Up @@ -541,16 +541,16 @@ type FooControllerGetStateAction = ControllerGetStateAction<
>;
```

## Define the `*:stateChange` event using the `ControllerStateChangeEvent` utility type
## Define the `*:stateChanged` event using the `ControllerStateChangedEvent` utility type

Each controller needs a type for its `*:stateChange` event. The `ControllerStateChangeEvent` utility type from the `@metamask/base-controller` package should be used to define this type.
Each controller needs a type for its `*:stateChanged` event. The `ControllerStateChangedEvent` utility type from the `@metamask/base-controller` package should be used to define this type.

The name of this type should be `${ControllerName}StateChangeEvent`.
The name of this type should be `${ControllerName}StateChangedEvent`.

```typescript
import type { ControllerStateChangeEvent } from '@metamask/base-controller';
import type { ControllerStateChangedEvent } from '@metamask/base-controller';

type FooControllerStateChangeEvent = ControllerStateChangeEvent<
type FooControllerStateChangedEvent = ControllerStateChangedEvent<
'FooController',
FooControllerState
>;
Expand Down Expand Up @@ -890,7 +890,7 @@ This type should include:
- This should always include `${controllerName}GetStateAction`
- Actions imported from other controllers that the controller calls (i.e., _external actions_)
- Events defined and exported by the controller that it publishes and expects consumers to subscribe to (i.e., _internal events_)
- This should always include `${controllerName}StateChangeEvent`
- This should always include `${controllerName}StateChangedEvent`
- Events imported from other controllers that the controller subscribes to (i.e., _external events_)

The name of this type should be `${ControllerName}Messenger`.
Expand Down Expand Up @@ -923,7 +923,7 @@ export type AllowedActions =
| ApprovalControllerAddApprovalRequestAction
| ApprovalControllerAcceptApprovalRequestAction;

export type SwapsControllerStateChangeEvent = ControllerStateChangeEvent<
export type SwapsControllerStateChangedEvent = ControllerStateChangedEvent<
'SwapsController',
SwapsControllerState
>;
Expand All @@ -934,7 +934,7 @@ export type SwapsControllerSwapCreatedEvent = {
};

export type SwapsControllerEvents =
| SwapsControllerStateChangeEvent
| SwapsControllerStateChangedEvent
| SwapsControllerSwapCreatedEvent;

export type AllowedEvents =
Expand Down Expand Up @@ -1045,7 +1045,7 @@ class GasFeeController extends BaseController</* ... */> {
// ...

messenger.subscribe(
'NetworkController:stateChange',
'NetworkController:stateChanged',
(networkControllerState) => {
this.#updateGasFees(networkControllerState.selectedNetworkClientId);
},
Expand All @@ -1054,9 +1054,9 @@ class GasFeeController extends BaseController</* ... */> {
}
```

One way to fix this is to check if the other controller (the one being subscribed to) has a more suitable, granular event for the data being acted upon. For instance, `NetworkController` has a `networkDidChange` event which can be used in place of `NetworkController:stateChange` if the subscribing controller needs to know when the network has been switched:
One way to fix this is to check if the other controller (the one being subscribed to) has a more suitable, granular event for the data being acted upon. For instance, `NetworkController` has a `networkDidChange` event which can be used in place of `NetworkController:stateChanged` if the subscribing controller needs to know when the network has been switched:

✅ **`NetworkController:networkDidChange` is used instead of `NetworkController:stateChange`**
✅ **`NetworkController:networkDidChange` is used instead of `NetworkController:stateChanged`**

```typescript
class GasFeeController extends BaseController</* ... */> {
Expand Down Expand Up @@ -1098,7 +1098,7 @@ class TokensController extends BaseController</* ... */> {
let selectedAccount = accountsController.internalAccounts.selectedAccount;

messenger.subscribe(
'AccountsController:stateChange',
'AccountsController:stateChanged',
(newAccountsControllerState) => {
if (newAccountsControllerState.selectedAccount !== selectedAccount) {
this.#updateTokens(
Expand All @@ -1125,7 +1125,7 @@ class NftController extends BaseController/*<...>*/ {
);

messenger.subscribe(
'PreferencesController:stateChange',
'PreferencesController:stateChanged',
(newPreferencesControllerState) => {
if (
preferencesControllerState.ipfsGateway !== newPreferencesControllerState.ipfsGateway,
Expand Down Expand Up @@ -1190,7 +1190,7 @@ class NftController extends BaseController /*<...>*/ {
// ...

messenger.subscribe(
'PreferencesController:stateChange',
'PreferencesController:stateChanged',
({ ipfsGateway, openSeaEnabled, isIpfsGatewayEnabled }) => {
this.#updateNfts(ipfsGateway, openSeaEnabled, isIpfsGatewayEnabled);
},
Expand Down
Loading
Loading