-
Notifications
You must be signed in to change notification settings - Fork 200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor!: module to api and module config #943
refactor!: module to api and module config #943
Conversation
I'm a bit confused on what the intent is of this addition. Is my understanding correct that we're currently in a sort of 'hybrid state' where we can register modules both the old and the new way? Regardless, a showcase/reference implementation is useful indeed. Probably needless to say, but I would prefer to refactor the configuration for all modules before releasing |
Well this PR is just to demonstrate how it would look and get some feedback (hence draft PR). If we think this is a good approach I'll update this PR to refactor all modules to the new format with config. However I won't immediately remove the old way, I'd like to do that in a separate PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really nice! Just let some comments, mainly on usability.
// Api | ||
dependencyManager.registerContextScoped(CredentialsModule) | ||
dependencyManager.registerContextScoped(CredentialsApi) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am still not the biggest fan of these register function names. I think that registerContextScoped
is a bit ambiguous and does not tell me when to use this method in the context of AFJ.
aliassing it to something like: registerPublicApi
or whatever fits better might be worth it to make writing external plugins a lot easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point. What I'm not sure about is that we're not sure yet what types of components people want to register. Maybe we can come up with a set of components, but it would need to cover all cases.
registerApi
for the api instead ofregisterContextScoped
registerStatelessService
instead ofregisterSingleton
registerInstance
stays as is
We would still need another name for the registerContextScoped
if you have something that is not an API but needs to be unique per context. Do you like this direction better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this makes it a lot easier to understand. Maybe for the registerContextScoped
without an api and needs to be unique, we can use registerStatefulService
? I believe that that is what you want to register, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll raise it during the WG call and gather some more input on this. If we agree we want to change something, I'll raise another PR
autoAcceptCredentials: AutoAcceptCredential | ||
} | ||
|
||
export class CredentialsModuleConfig { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awesome! Way more clear which properties from the agent config are with that module.
Just more curious, how do we deal with configuration shared between modules, if it ever occurs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. I think either declare it in both modules and provide it twice, or one module can depend on the configuration of the other module (if they are dependant on each other).
E.g. the outOfBandModule can depend on the autoAcceptConnections
from the ConnectionsModule
(as you can't use the oob module without the connections module). Does that make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that makes sense. Is it obvious to the user that the autoAcceptConnections
from the ConnectionsModule
will be used in the outOfBandModule
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure. We could add it to the documentation of the out of band module. So in the receiveInvitation method documentation we can mention it will use the autoAcceptConnections
property from the connections module config to determine whether to auto accept the config.
I've added the config of each module as a public readonly property to the api class, which means it's public api and makes sense it can be used by other modules.
So agent.connections.config
is a public property that exposes the config of the connections module
5141660
to
20c35d0
Compare
Codecov Report
@@ Coverage Diff @@
## 0.3.0-pre #943 +/- ##
=============================================
+ Coverage 87.13% 87.28% +0.14%
=============================================
Files 539 562 +23
Lines 13086 13272 +186
Branches 2244 2142 -102
=============================================
+ Hits 11403 11584 +181
- Misses 1587 1684 +97
+ Partials 96 4 -92
Continue to review full report at Codecov.
|
20c35d0
to
a9c7716
Compare
Signed-off-by: Timo Glastra <timo@animo.id>
b6f3256
to
55b94ac
Compare
Signed-off-by: Timo Glastra <timo@animo.id>
55b94ac
to
b555236
Compare
Signed-off-by: Timo Glastra <timo@animo.id>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice stuff in here! Also a good idea to mark stuff with @deprecated
. However, do we have any backwards compatibility with the agent config from before?
What do you mean exactly with |
Well, you added a deprecation notice like so: /**
* @deprecated use indyLedgers from the `LedgerModuleConfig` class
*/
public get indyLedgers() {
return this.initConfig.indyLedgers ?? []
} This would mean that this is still works and will get the value from the initConfig. Is that correct? |
Yes, currently all values still come from the init config. This is mainly because there's no way to configure the internal modules yet. So the main init config is the easiest to make sure it keeps working, but already allowing custom config for custom modules. I'm still not sure what the best approach is for internal module configuration. My thoughts were to maybe allow to define the module yourself and we'll only register it internally with default config if you don't provide the module. Without custom config the connections module is registerd internally and auto accept connections will have default value false. const agent = new Agent({
modules: {
}
}) If i register it, it won't be registered internally and we'll use the config as passed by the user. const agent = new Agent({
connections: new ConnectionsModule({
autoAcceptConnections: true
})
}) But maybe there's other / better appraoches? |
I quite like this approach and I think that we should do it like that. One thing that might become slightly annoying here is that shared configuration, I don't think it will happen a lot so it might just be ignored for now. One quick fix that I have for that is to do it like so: const agent = new Agent({
config: {
autoAcceptConnections: true
},
connections: new ConnectionsModule()
}) We can create some cool type that infers the TBH I prefer your method, but maybe this can give some inspiration for another solution that fixes every problem :) |
Merging as only failing test is BBS+ test |
Signed-off-by: Timo Glastra <timo@animo.id> BREAKING CHANGE: All module api classes have been renamed from `XXXModule` to `XXXApi`. A module now represents a module plugin, and is separate from the API of a module. If you previously imported e.g. the `CredentialsModule` class, you should now import the `CredentialsApi` class
Signed-off-by: Timo Glastra <timo@animo.id> BREAKING CHANGE: All module api classes have been renamed from `XXXModule` to `XXXApi`. A module now represents a module plugin, and is separate from the API of a module. If you previously imported e.g. the `CredentialsModule` class, you should now import the `CredentialsApi` class
Signed-off-by: Timo Glastra <timo@animo.id> BREAKING CHANGE: All module api classes have been renamed from `XXXModule` to `XXXApi`. A module now represents a module plugin, and is separate from the API of a module. If you previously imported e.g. the `CredentialsModule` class, you should now import the `CredentialsApi` class
Signed-off-by: Timo Glastra <timo@animo.id> BREAKING CHANGE: All module api classes have been renamed from `XXXModule` to `XXXApi`. A module now represents a module plugin, and is separate from the API of a module. If you previously imported e.g. the `CredentialsModule` class, you should now import the `CredentialsApi` class Signed-off-by: Ariel Gentile <gentilester@gmail.com>
Extracts all modules to a separate module class and rename all previous module classes to
XXXApi
. For now the module is still internal and takes config from the agent config, but it shows how custom module configuration works. This is one step closer to configurable modules.Basically how you'd use it (if we have full modularization):
The credentials api can then depend on it like this:
@karimStekelenburg @blu3beri @genaris @2byrds @JamesKEbert Thoughts? If we can agree on the approach for configuration, I can update it for all modules. We can still keep it in init config (so there won't be much breaking changes for now). But from then on it will be trivial to start extracting modules out of core