Open
Description
If we want more parts of the system to be able to access more parts of controllers and services, then this means that the number of actions these objects will have to register will grow. Currently, creating an action that merely delegates to a method on the "messageable" requires three steps:
- An action type must be defined
- The action type must be added to the list of
${Controller}Actions
or${Service}Actions
- A handler for the action must be registered in the controller which calls the method
If we can provide a way to group the methods that the developer wants to expose into a single type and register them as action handlers in bulk, then any time the developer wants to change the set of exposed methods, they only have to go to one place.
Acceptance Criteria
- A function should exist that takes an object, and a list of methods on the object, and its messenger, and registers action handlers for the methods on the messenger
- A utility type should exist that takes a list of method names and creates a type union of action types
(Original PR description)
Motivation
- Currently, we manually enumerate each individual
registerActionHandler
call in controller constructors (example). We should have a DRY-er way of doing this. - Most handlers for controller internal actions are simply public controller class methods bound to the controller instance.
Proof of concept
// TODO: Expand into base-controller utility function that batch registers action handlers.
#registerActionHandlers() {
const methodsExcludedFromMessenger = [
'constructor',
'messagingSystem',
'setProvider',
'provider',
'ipfsGateway',
'chainId',
];
getKnownPropertyNames<keyof this>(Object.getPrototypeOf(this)).forEach(
(method) => {
if (
((key: keyof this): key is AssetsContractControllerMethodName =>
!methodsExcludedFromMessenger.find((e) => e === key) &&
typeof this[key] === 'function')(method)
) {
this.messagingSystem.registerActionHandler(
`${name}:${method}`,
// TODO: Write a generic for-loop implementation that iterates over an input union type in tandem with the input array.
// @ts-expect-error Both assigned argument and assignee parameter are using the entire union type for `method` instead of the type for the current element
this[method].bind(this),
);
}
},
);
}
Acceptance Criteria
- MVP: Write a function that...
- a) Accepts a list of public controller class fields and methods that should be excluded from being registered as action handlers.
constructor
andmessagingSystem
should be included by default.
- b) Iterates over a list of public controller methods, and binds them to the controller instance.
- c) Registers these bound methods as action handlers for the corresponding internal messenger actions.
- This iteration is correctly typed.
- a) Accepts a list of public controller class fields and methods that should be excluded from being registered as action handlers.
- Stretch: Better handling for exceptions.
- a) Accepts a map of action names and handlers which are exceptions to the general rule that each class method corresponds to an action handler.
- b) Register these exceptions to the
messagingSystem
as well.