lab.js icon indicating copy to clipboard operation
lab.js copied to clipboard

Plugin methods

Open FelixHenninger opened this issue 1 year ago • 3 comments

FelixHenninger avatar Aug 22 '22 15:08 FelixHenninger

Hej @jdpigeon , I've attempted to add your template in 06ae4e1e0b3f740bb1c9debd61a374f58363a74c -- if you have a moment, I'd super-appreciate your feedback! Overall, I really like the pattern and think that it could be a good model for components, too. That being said:

  • TS doesn't like that we define a type, make it completely optional, and then don't use any of the methods in the reference/default Plugin implementation. I think that this is minor, and have silenced that error for now.
  • The template literal types don't seem to play well with generics -- it looks like they need a hard-coded set of events they would be able to see, which I think wouldn't work well with the remaining code. Then again, hard-coding a set of method names would have the same effect. I would like to write Plugin<C, E> implements EventHandler<E | PluginEvent, C, any> but TS admonishes that A class can only implement an object type or intersection of object types with statically known members. ts(2422). I tried shuffling around the types a bit, and defining an fully generic interface, but I couldn't get things to work.

If we could make this work, I think it would be awesome, but right now I'm not fully convinced, but also not sure if the fallback is any better. Do you have thoughts?

FelixHenninger avatar Aug 23 '22 09:08 FelixHenninger

After playing around some more, let me maybe add a more concrete example. Here's what works:

type EventHandlerClass<E, T> = {
  [key in `on${Capitalize<EventName>}`]?: (whatever: T) => void
}

Here's what I would like to do:

type EventHandlerClass<E, T> = {
  [key in `on${Capitalize<E>}`]?: (whatever: T) => void
}

Notice the change in Capitalize<E> vs. Capitalize<EventName>. Playground here

FelixHenninger avatar Aug 23 '22 09:08 FelixHenninger

Ahhh, it does appear that there's a limitation to that pattern, and I don't think there's going to be a way around that one.

Is it really important for Plugins to be able to handle new events that go beyond those in the standard Component life cycle (+ plugin:prepare, etc.)? Our custom plugins only ever handle 'prepare' 'run' and 'end'.

If you do want to keep that flexibility open, I don't think it's a bad pattern to allow plugins to receive a generic string event name for the handle function, and still have the defaults used to populate the built-in methods. playground

jdpigeon avatar Aug 24 '22 16:08 jdpigeon