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

discussion: Roadmap #152

Closed
3 tasks
yoshuawuyts opened this issue Jul 10, 2016 · 19 comments
Closed
3 tasks

discussion: Roadmap #152

yoshuawuyts opened this issue Jul 10, 2016 · 19 comments

Comments

@yoshuawuyts
Copy link
Member

yoshuawuyts commented Jul 10, 2016

Sharing a bit of a higher level overview currently only in my brain so all
y'all know what's going on:

3.0 Use CPS

  • get nested effects and error / value propagation
  • streamline view api
  • trim bytes by making yo-yoify applicable

3.1 Performance

  • add request animation frame to cap updates and better handle burst updates
  • provide standalone bundles for inclusion in codepen and the like

3.2 Plugins

  • app.use() API (oh god)

3.2.1 fix path triggers

  • fix the send(location:href) call

3.3 Custom async paradigms

  • provide wrap hooks so alternative async implementations become
    first-class citizens (e.g. choo-pull, choo-xstream, choo-rxjs, etc.)

4.0 Routing

  • upgrade sheet-router to handle hash routes by default; would make
    handling routes a complete no-brainer (it can be a bit tricky rn when using
    both hashes and normal routes)
  • update sheet-router to no longer use route()

4.1 Components

This is where we add one of the last large feature additions: choo/component.

  • add choo/component based on nanocomponent
  • replace const with var, all the way down

5.0 polish mode

I think at this point choo is quite stable. The syntax will probably not
change; we'll just keep making things smaller and faster.

  • switch over to nanomorph
  • allow querystrings to become part of routes
  • remove on-load from choo/html now that it's part of choo/component
  • remove prev from elements as nobody uses it anyway
  • change stack trace callback to keep history inside hooks

5.1 / 6.0 threads

  • use threaded effect and reducer execution using webworkers

Goals not (yet) bound to roadmap

  • look into trimming all .forEach() and .map() calls and replacing them
    with ES3 equivalents - speed and less array allocations ftw
  • get (dev)tools out there that can visualize all action calls and lay
    them out visually - would make debugging silky smooth
  • add a whole bunch of benchmarks so we know how choo is doing compared
    to itself
@YerkoPalma
Copy link
Member

YerkoPalma commented Jul 12, 2016

Should choo include some way to write plugins and/or mixins? I'm thinking in other frameworks that allow to write some sort of custom extensions, like Vue does

@yoshuawuyts
Copy link
Member Author

yoshuawuyts commented Jul 12, 2016

@YerkoPalma maybe? I wonder what kind of functionality you'd like to see that cannot be done with any of the existing / proposed hooks

edit: or perhaps plugins could be like a way of registering multiple handlers on the hooks? -ghmmmm - basically becomes sugar then, but that might be kinda nice hey

edit: hmmmmm, I'm quite liking this - would def mess with the internals butttt, could do stuff like:

const devtools = require('choo-devtools')
const pull = require('choo-pull-stream')
const log = require('choo-log')
const choo = require('choo')

const app = choo()

app.use(devtools())
app.use(pull())
app.use(log())

const tree = app.start()
document.body.appendChild(tree)

@YerkoPalma
Copy link
Member

@yoshuawuyts haha yeah. I was thinking something like that. The plugins/addons/mixins or whatever you call it could allow to.

  • Wrap some other libraries:
const chooFire = require('choo-fire')

// Wrap some firebase bindings and stuff
const app = choo()
app.use(chooFire)
  • Extend the actual choo schema
// extend just the model
app.model({
  state: {}
  style: { // this is a new one
    color: 'blue'
  }
})

// add a new function
app.test(avaChoo)
  • Replace some of the actual libraries used by choo (? I'm not pretty sure about this one 😄 )
// use flux as state manager
app.use(flux)

So, what do you think? are those good use cases? Is this be too hard to achieve?

@yoshuawuyts
Copy link
Member Author

@YerkoPalma hmm, so one of the things I like about choo is that we focus on modularity; once something is built it shouldn't be hard to break out. As a design pattern I'd prefer people create as many standalone widgets / sdks / purely functional components that reduce the need of glue as much as possible. I feel like extending the choo schema or adding methods might work against that goal.

Any customizations currently go through the hooks in const app = choo(); with possibly more hooks being added in #145 and #155. I feel that by improving the experience of using that functionality we might make it more pleasant to extend; but we must also steer clear of making it easy to modify choo - I really want to keep choo as dispensible as possible, not making people go down the road again of tying into a sticky framework that's hard to break out of.

Does that make sense?

@YerkoPalma
Copy link
Member

I totally miss the async wrapper idea, it sounds good 👍 Well, thats why I was asking, I think that plugins are needed when the library is like a blackbox, but whene is easy to hack the core I guess they are not useful. If I found myself with a real world use case I'll let you know.

@shama
Copy link
Member

shama commented Jul 12, 2016

Just a friendly reminder plugins == peer dependencies and is why I down voted :)

@yoshuawuyts
Copy link
Member Author

yoshuawuyts commented Jul 12, 2016

@shama ah yeah, that's a solid point. What do you think of using .use() to streamline the usage of certain wrappers / handlers like in this example? It wouldn't expose new functionality, mostly drop handlers inside or an array rather than needing to combine them manually in the app() call.

I think to some extent peer dependencies can't be avoided, but I'm 100% with you that they should leak as little as possible into the application logic itself

@shama
Copy link
Member

shama commented Jul 13, 2016

@yoshuawuyts My primary worry is plugins creating flavored elements; elements that only work with some choo plugin enabled. My secondary worry is the ecosystem creating choo plugins which could have been just regular modules accessible to everyone.

Plugins by their nature are convenient and is why every framework implements an API for it. But my goal has been to try something different then what everyone else currently does. I want to see if a client side ecosystem can be built without peer deps.

Just my 2 cents, but what if we tried to achieve the individual desired app behaviors (logger, devtools, etc) without a plugin system first. Then fallback to implementing a plugin API if the behavior is useful and deemed impossible without it?

@ahdinosaur
Copy link
Collaborator

in case this helps anyone's thinking:

the approach i'm taking with the very similar project inu is that an inu app is really just a data structure, so it's possible to create plugin-y things with a function that takes your new flavored app and returns a plain inu app. for example, a function that takes choo models and returns an inu app would be awesome. 😄 in theory (awaiting more empirical experiments), this means that if you do want to make a re-usable micro-app in some sugary flavor (or maybe you like spicy), you just need to use your special function before you export the common flavor, so no peer dependencies! same goes for developer features like logging or devtools, they are just a function you call on the top-level app before starting it.

@toddself
Copy link
Contributor

I just added an unbound agenda item for investigating using webworkers to move as much logic off main-thread as possible.

Right now there are no libraries that ship with an off-thread renderer implementation (rumor has it that angular2's webworker is mostly abandoned and might not make the ng2 cutoff).

This is something I think we could really accomplish. We'd have to make some changes to morphdom to help us enable this -> the ability to extract a diff of the dom (which is actually provided via global/document in the web worker context) and then applying that dom patch to the real dom.

Ideally I'll have some time in the future to start seeing how this could be added to morphdom. We might have bubble up some of this implementation from yo-yo, but this also means the entire TCBY ecosystem could hook into this feature!

@YerkoPalma
Copy link
Member

I really like the idea of using web workers in choo by default (or as an option). I'm just trying to develop something to make a pwa with choo, and in my research I found the pokedex.org app which is exactly what I was looking for. In the post about pokedex the author describes how he used web workers to manage the diff between the dom, so that app and specially the post, might be a good place to start looking at

@yoshuawuyts yoshuawuyts mentioned this issue Jul 31, 2016
24 tasks
@toddself
Copy link
Contributor

@YerkoPalma I have talked to @nolanlawson a few times re: web workers and choo (and he has said he's looking into choo a little!).

I know there was some hacking done for the pokedex stuff in terms of the diffing; might be interesting to see if we could use the same serialization format for morphdom that he implemented for vdom.

But it might be worthwhile to see if he has any suggestions of recommendations about this topic :)

@nolanlawson
Copy link

Yeah this is a super under-researched area, but I did implement vdom-serialized-patch as a solution for virtual-dom anyway.

Best advice I can give is that you need to architect it such that the perf gains of multithreading are not outweighed by the cost of serializing and sending messages to the worker. I wrote about this a bit but to sum up:

  1. Send stringified JSON in postMessage()
  2. Batch the messages
  3. Make the messages as small as possible

Also this works best when basically the entire app lives inside the web worker because otherwise you are sending messages back and forth from the worker to the main thread constantly.

There's also some research from Parashuram and from Chris Thoburn.

@timwis
Copy link
Member

timwis commented Jan 7, 2017

remove prev from elements as nobody uses it anyway

You mean removing it from views? I have definitely used it and there are a few cases where that's the only way to accomplish something, particularly simulating lifecycle stuff. Would examples help?

@yoshuawuyts
Copy link
Member Author

yoshuawuyts commented Jan 7, 2017 via email

@aknuds1
Copy link
Contributor

aknuds1 commented Jan 7, 2017

@yoshuawuyts You mean removing the prev argument to render functions? I use it sometimes, for example to compute diffs between previous and current state in order to update D3 graphs.

@yoshuawuyts
Copy link
Member Author

yoshuawuyts commented Jan 9, 2017 via email

@yoshuawuyts
Copy link
Member Author

lmao, we're diverging so much from this rn - current status https://github.com/yoshuawuyts/playground-nanoframework

@yoshuawuyts
Copy link
Member Author

Pretty much everything on the roadmap is done. Closing because choo@5 will introduce a new API. See #425 for the merged PR. Thanks!

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

8 participants