Closed FlorianWendelborn closed 7 years ago
@dodekeract This would open the gates to hell, can we trust people will not create entangled plugins that depend on other plugins?
I like this proposal though. Currently hyperapp expects a clunky router
property if you want to use it. Using something like app({ ..., plugins })
would generalize the concept, making things feel more "right". The router is just another plugin.
app({
view,
reducers,
effects,
plugins: [router, devtools, debugger, ...]
})
If we move forward with this, however, I'd find it more useful if HyperApp still provided the router out of the box.
The same is going to be true for toString
, whenever that lands.
About everything, no. As about hooks to be array - good idea. About the onRender
- pretty good. Actually exactly that hook is kinda very specific and very important point for the whole application. And in my case with mich
/chika
it is main thing.
This would open the gates to hell, can we trust people will not create entangled plugins that depend on other plugins? — @jbucaran
People can and will do that. We're providing everything that's important out-of-the-box though, so we don't suffer from the same problems react has with react
+ redux
+ react-router
+ react-redux
+ react-redux-router
.
HyperApp still provided the router out of the box. — @jbucaran
I'm not suggesting to change that. It'd just work a bit different internally.
About everything, no. — @tunnckoCore
Can you provide any reasons/concerns why you don't like this? I think it makes the whole router
thing less magical and embraces the data-flow that hyperapp already has.
Actually, no so. But okey, how they will be called? more specifically when and where? Don't know, not sure enough. But yea, router seems like a plugin in any way.
@tunnckoCore Once on the beginning of the application start. Plugins may then decide to register subscriptions
, add effects
& reducers
and subscribe to hooks. That allows them to do everything they need to do while embracing the state-management of hyperapp.
Right now, we really have no way to open up app(options)
to userland other than what options
has: reducers, effects, subscriptions, etc. In order to make the router work with app
we added a special router
prop, but @dodekeract's proposal raises this to a new level.
If we move forward with this, router would be just a plugin, which we happen to ship out of the box with this repo, but a plugin nevertheless.
I wonder what other stuff we can make with plugins? 🤔 Perhaps someone out there might come up with a plugin that helps to create domain specific kind of apps. Games, socket-based apps, etc.
@jbucaran a socket.io integration would be trivial to do with this. Basically everything that's possible to do with the normal hyperapp workflow should be possible as a plugin.
Interesting.
Exactly. Why not just then use/compose multiple apps()? If we expose the whole options object to plugins, then why not just use multiple apps :D Don't know.
The very big and main thing for me to externalize the state management. One good Elm-like state management - and actually when i think a bit did it. There's only barracks
currently. But we can do it smaller of course. Also that nested
actions is kinda cool feature.
I was wondering, does it have to be app({ plugins })
?
Just a wild and random thought: what do you think about this: app(options, ...plugins)
?
So:
app({
view,
reducers,
effects
}, router, devtools, debugger)
For comparison:
app({
view,
reducers,
effects,
plugins: [router, devtools, debugger, ...]
})
@tunnckoCore that's actually what I did at dodekeract/hyperapp-router. It looks odd though.
@jbucaran That syntax would imply that hyperapp is fine with multiple apps too. Not sure if that makes sense to do. :)
The Idea
A middleware API could be used to easily add a
logger
,time-travelling-debugger
or arouter
to any hyperapp project. It would provide a single point where a plugin can attach to everything it needs to.Plugins themselves are just a function that will be called as soon as hyperapp starts (basically like a subscription). They will then be able to add
reducers
,effects
,hooks
andsubscriptions
.What should be exposed to a plugin?
hooks
, useful for stuff like a loggereffects
, already used by the router foractions.setLocation
reducers
, since they allow model-accesssubscriptions
, can be used to register events. E.g.window.addEventListener('popstate')
To prevent this from becoming an unpredictable mess I'm suggesting a convention that all plugins only use their own namespace. With nested actions that's already possible. E.g.:
Further changes
Router needs a way to interact with the view, so a
onRender
hook would be a good start. Hooks need to be an array, since multiple plugins may want to listen to them.Router rewrite
I'm also proposing that the router shares state with the rest of the application and uses the normal hyperapp lifecycle. (subscribes to subs, adds some effects, reducers, hooks, etc.)
Moving this information to the model has some really good side-effects:
model.router.params.id
in your effects and reducers, which greatly simplifies the actions bound to the viewMeta
As usual I added :+1: and :-1: so it's easy to vote if you don't want to leave a comment. Ultimately the vote won't decide what we do though. It's just an additional thing to consider.