Skip to content
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

Extended "plugin" interface #24

Open
spion-h4 opened this issue Apr 3, 2019 · 3 comments
Open

Extended "plugin" interface #24

spion-h4 opened this issue Apr 3, 2019 · 3 comments

Comments

@spion-h4
Copy link
Collaborator

spion-h4 commented Apr 3, 2019

We can extend the plugin interface in a backward compatible way to support several application phases:

  1. Support app.initialize(). Once all plugins are loaded, the initialize method can be called. This method will in turn call every plugin which returned a method called initialize from its construction function. The method can return a promise.

  2. Support app.terminate(). Similar to initialize but it will shut all plugins down. Analogously to initialize it will call a termination method on all plugins that have one

My main doubt about this design is how to make it clear which things go where, especially the config vs initialization phases. Perhaps we could support passing an object to load() in addition to a function - if an object is passed, it has to at least have an initialize method (that can return a promise), and it can optionally have a configuration getter that returns the env variables specs (once loaded it will be replaced with a cached property) as well as a terminate method (that can return a promise)

@spion-h4 spion-h4 changed the title Plugin interface Extended "plugin" interface Apr 3, 2019
@spion-h4
Copy link
Collaborator Author

spion-h4 commented Apr 5, 2019

new Load method:

loadConfigurable({ configure(app:App):void; create(app:App) => void})

Not sure if good idea to give access to the entire app in configure. Maybe just envaridator?

@spion
Copy link
Contributor

spion commented Apr 8, 2019

If its just envaridator, you'd probably need this interface:

interface ConfigururablePlugin<T, U> {
  configure(env: Envaridator):T;
  create(app: App, config:T):U;
}

@spion-h4
Copy link
Collaborator Author

spion-h4 commented Apr 9, 2019

Another alternative making it easier to fetch this

class EnvConfig extends AppSingleton {
  protected env = this.getSingleton(Envaridator);
}

class App {
  addConfigurablePlugin(item) {
    this.getSingleton(item.envConfig);
    this.uninitialized.push(item.create);
  }
  addPlugin(item) {
    this.uninitialized.push(item);
  }
  setupPlugins() {
    this.uninitialized.forEach(item => this.getSingleton(item));
  }
}

Plugin:

class MyEnvConfig extends EnvConfig {
  myvar1 = this.env.register('name', {...})
  myvar2 = this.env.register('othername', {...})
  myvar3 = this.env.register('thirdname', {...})
}

let ConfigurablePlugin = {
  config: MyEnvConfig, 
  create: app => {
    let serviceInstallName = app.getSingleton(MyEnvConfig).serviceName.value;
    app.getSingleton(RPCServiceRegistry).add(serviceInstallNamevalue, MyService)
  }
};

App:

class MyApp extends App {
  setupPlugins() {
    this.addPlugin(z);
    this.addConfigurablePlugin(ConfigurablePlugin);
  }

  // Maybe instead:
  // app.overrideSingleton(Envaridator, TestEnvaridator); 
  // where validate is always OK?
  initializeForTests() {
    this.setupPlugins()
    this.loadPlugins();
  }

  start() {
    this.setupPlugins();
    this.getSingleton(Envaridator).validateEnv();
    this.loadPlugins();
  }

  help() {
    this.getSingleton(Envaridator).showHelpSomething()
  }
}

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

No branches or pull requests

2 participants