phosphorjs / phosphor

The PhosphorJS Library
BSD 3-Clause "New" or "Revised" License
1.04k stars 166 forks source link

Tokens that extend other tokens #448

Closed jasongrout closed 4 years ago

jasongrout commented 4 years ago

@ellisonbg, @afshin, @blink1073, and I ran into a situation today where we wanted to introduce a token that would extend another token. In other words, (the object registered with) token B implements the interface of (the object registered with) token A, plus some extra stuff. Normal plugins would require token A, but some might require token B. It would be nice if the dependency injection framework could register that token B could be served to those requesting token A.

It just occurred to me that you could probably do this by writing a single activation function that is essentially memoized (first call runs and creates the system object, second or later calls just return some stored object), and register that activation function with both token A and token B. Or you could just have token B registered in a plugin, and write a new plugin for token A that requires token B and just returns it.

So this issue is about whether we should have an explicit pattern for registering tokens/interfaces that extend other tokens/interfaces. Or perhaps this issue is just documenting a pattern for doing so in the existing framework.

vidartf commented 4 years ago

I've been using this pattern for lab extensions:

// File defining tokens
import {TokenA} from 'amodule';
import {Token} from '@phosphor/...';

export interface TokenB extends TokenA {
  myProp: string;
}

export const TokenB = new Token(...);
// File defining plugins
import {TokenA, activateA} from 'amodule';
import {TokenB} from 'bmodule/lib/tokens';

const MyPluginB = {
  provides: TokenB;
  activate: (...) => {
    const A = activateA(...);
    A.myProp = 'foo!';
    return A;
  }
}

const MyPluginA = {
  provides: TokenA;
  requires: [TokenB];
  activate: (..., B: TokenB) => {
    return B;
  }
}

export {MyPluginA, MyPluginB};
ellisonbg commented 4 years ago

Vidar, very nice! It seems our system already supports this. Let's leave the issue open so we can document this in our extension author documentation.

On Thu, Oct 31, 2019 at 3:04 AM Vidar Tonaas Fauske < notifications@github.com> wrote:

I've been using this pattern for lab extensions:

// File defining tokensimport {TokenA} from 'amodule';import {Token} from '@phosphor/...'; export interface TokenB extends TokenA { myProp: string; } export const TokenB = new Token(...); // File defining pluginsimport {TokenA, activateA} from 'amodule';import {TokenB, activateB} from 'bmodule'; const MyPluginB = { provides: TokenB; activate: (...) => { const A = activateA(...); A.myProp = 'foo!'; return A; } } const MyPluginA = { provides: TokenA; requires: [TokenB]; activate: (..., B: TokenB) => { return B; } } export {MyPluginA, MyPluginB};

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/phosphorjs/phosphor/issues/448?email_source=notifications&email_token=AAAGXUGBKOMNCJTL5IJ7GQDQRKUS7A5CNFSM4JGRKRL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOECXFMJI#issuecomment-548296229, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAGXUD2MI4RU6FTBSE4QFLQRKUS7ANCNFSM4JGRKRLQ .

-- Brian E. Granger

Principal Technical Program Manager, AWS AI Platform (brgrange@amazon.com) On Leave - Professor of Physics and Data Science, Cal Poly @ellisonbg on GitHub

ellisonbg commented 4 years ago

Missed this issue is on phosphor - can close it here and we will open one to track the JupyterLab documentation on this.

On Thu, Oct 31, 2019 at 9:28 AM Brian Granger ellisonbg@gmail.com wrote:

Vidar, very nice! It seems our system already supports this. Let's leave the issue open so we can document this in our extension author documentation.

On Thu, Oct 31, 2019 at 3:04 AM Vidar Tonaas Fauske < notifications@github.com> wrote:

I've been using this pattern for lab extensions:

// File defining tokensimport {TokenA} from 'amodule';import {Token} from '@phosphor/...'; export interface TokenB extends TokenA { myProp: string; } export const TokenB = new Token(...); // File defining pluginsimport {TokenA, activateA} from 'amodule';import {TokenB, activateB} from 'bmodule'; const MyPluginB = { provides: TokenB; activate: (...) => { const A = activateA(...); A.myProp = 'foo!'; return A; } } const MyPluginA = { provides: TokenA; requires: [TokenB]; activate: (..., B: TokenB) => { return B; } } export {MyPluginA, MyPluginB};

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/phosphorjs/phosphor/issues/448?email_source=notifications&email_token=AAAGXUGBKOMNCJTL5IJ7GQDQRKUS7A5CNFSM4JGRKRL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOECXFMJI#issuecomment-548296229, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAGXUD2MI4RU6FTBSE4QFLQRKUS7ANCNFSM4JGRKRLQ .

-- Brian E. Granger

Principal Technical Program Manager, AWS AI Platform (brgrange@amazon.com) On Leave - Professor of Physics and Data Science, Cal Poly @ellisonbg on GitHub

-- Brian E. Granger

Principal Technical Program Manager, AWS AI Platform (brgrange@amazon.com) On Leave - Professor of Physics and Data Science, Cal Poly @ellisonbg on GitHub

vidartf commented 4 years ago

Just a thought, it might be helpful if a single plugin could have provides be an array. That could help eliminate some boiler code from the example above. I haven't thought through the consequences of that fully though.

sccolbert commented 4 years ago

That should be fairly easy to do.

On Sun, Nov 3, 2019 at 5:19 PM Vidar Tonaas Fauske notifications@github.com wrote:

Just a thought, it might be helpful if a single plugin could have provides be an array. That could help eliminate some boiler code from the example above. I haven't thought through the consequences of that fully though.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/phosphorjs/phosphor/issues/448?email_source=notifications&email_token=AABBQSOEYPLYDITSU4OZ2QDQR5L6TA5CNFSM4JGRKRL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEC57SSY#issuecomment-549189963, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABBQSJMF2UQOGGVLTVNOGDQR5L6TANCNFSM4JGRKRLQ .