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

Road to 1.0 #244

Closed
7 tasks done
jorgebucaran opened this issue Jun 25, 2017 · 66 comments
Closed
7 tasks done

Road to 1.0 #244

jorgebucaran opened this issue Jun 25, 2017 · 66 comments
Milestone

Comments

@jorgebucaran
Copy link
Owner

jorgebucaran commented Jun 25, 2017

@nitin42
Copy link

nitin42 commented Jun 27, 2017

  • Recomposing components (like lodash) for expressing state updates
  • Recycling of DOM nodes (performance benefits)
  • Controlled Components
  • SSR
  • Lifecycle hooks

Although all these may increase the lib size but they can be dispatched through separate packages like InfernoJS does ?

@jorgebucaran
Copy link
Owner Author

jorgebucaran commented Jun 27, 2017

@nitin42

  • Lifecycle events already exist. Maybe they can be improved? Do you have any suggestions?

  • SSR. There are several ad-hoc solutions. See also: https://github.com/hyperapp/hyperapp-server for a WIP. Not sure if I should wait for SSR to release 1.0. I think not, but what do you think?

  • Controlled Components. You can create your own custom tags controlled components already.

  • Recycling of DOM nodes and recomposing components. How do you mean? lol We are doing this one! I've updated the todo list. /cc @ngryman

@nitin42
Copy link

nitin42 commented Jun 27, 2017

Oh! I really wanted to work on hyperapp and right now I am going through the Elm Architecture doc. Where can I start ?

From recycling of DOM nodes I meant to say that re-using the dom nodes upon their disposal.

@nitin42
Copy link

nitin42 commented Jun 27, 2017

Or I can work on the website ? This will also led me to understand the core concepts and the design principles of the lib by writing about the api and their functionality. Let me know what you think !

@jorgebucaran
Copy link
Owner Author

Where can I start ?

I think here is a good place to start.

Or I can work on the website?

Be my guest! 👍

@nitin42
Copy link

nitin42 commented Jun 27, 2017

Ok so I will be rendering the docs on web. Meanwhile I will go through the link you provided and will start contributing !

@nitin42
Copy link

nitin42 commented Jun 29, 2017

Is there something on (HyperApp core) which I can hack? Other discussions are already on 🔥 ! I am interested in investing my time by working on HyperApp but don't know where to start. Like cli tool discussion does not have an answer and I feel growing that discussion further is unneeded. Same goes for other discussions. Anything ?

@lukejacksonn
Copy link
Contributor

@nitin42 you could try build an app with HyperApp; find a limitation and try improve it or find something that you find writing over and over again and try abstract that process out to a custom element or mixin?

Or help build out functionality of example applications such as the Hacker News PWA. So we can get it up on https://hnpwa.com/

@nitin42
Copy link

nitin42 commented Jun 29, 2017

HNPWA seems a good idea!!

@nitin42
Copy link

nitin42 commented Jun 29, 2017

I could implement :

  • PWA
  • Comparing lighthouse scores
  • Offline caching
  • Cross browser
  • Web page test
  • App shell architecture

I think I should start working!

@zaceno
Copy link
Contributor

zaceno commented Jun 29, 2017

Should we use Github's "milestone" feature for 1.0? Not sure how it works, but this seems like the sort of use case they made that feature for.

@andrewiggins
Copy link

@jbucaran What's the plan for the relationship between picodom and hyperapp? If hyperapp wants to eventually consume picodom as a dependency, should that be part of 1.0 milestone?

@jorgebucaran
Copy link
Owner Author

jorgebucaran commented Jul 25, 2017

@andrewiggins At this point both vdom engines are the same, but I presume they might eventually begin to differ since both have different "core values". HyperApp is opinionated about state management, while picodom isn't.

I also don't want to consume picodom in hyperapp, but it might happen. The probability is very low though.

@brandonros
Copy link

brandonros commented Aug 9, 2017

Why do we need both actions and events?

Take this really vanilla app:

app({
  state: {
    images: []
  },
  view: function(state) {
    return h('div', {}, state.images.map(function(image) {
      return h('img', {src: 'images/' + image.url});
    }));
  },
  actions: {
    updateImages: function(state, actions, data) {
      state.images = data;

      return state;
    }
  },
  events: {
    updateImages: function(state, actions, images) {
      actions.updateImages(images);
    }
  }
});

setTimeout(function() {
  emit('updateImages', []);
}, 5000);

This is cool, but why not allow this:

app({
  state: {
    images: []
  },
  view: function(state) {
    return h('div', {}, state.images.map(function(image) {
      return h('img', {src: 'images/' + image.url});
    }));
  },
  actions: {
    updateImages: function(state, actions, data) {
      state.images = data;

      return state;
    }
  }
});

setTimeout(function() {
  emit('action', {name: 'updateImages', data: []});
}, 5000);

@jorgebucaran
Copy link
Owner Author

jorgebucaran commented Aug 9, 2017

@brandonros Why do we need both actions and events?

Architecture

I think the separation is important from an architecture point of view.

  • Actions: You call us.
    • We receive your request and update the state on your behalf.
  • Events: We call you.
    • You can attach one or more handlers to the same event.

Now, you can also create custom events, in which case you are responsible for calling yourself, but they also work in the same way as the default events.

Return Values

Actions return a partial state or a thunk, or maybe just call several other actions. Actions can be async functions too.

Events reduce over some data by successively calling each event handler of the specified event.

Consider the following example.

const emit = app({
  events: {
    someEvent: [
      (state, actions, data) => data + 1,
      (state, actions, data) => data + 1,
      (state, actions, data) => data + 1
    ]
  }
})

And this is the result of firing someEvent with some data.

console.log(
  emit("someEvent", 10)
) // => 13

One-to-many

An event can have more than one callback associated with it.

myEvent: [handler1, handler2, handler3]

An action is always a single call.


These are some of my thoughts. I am sure that:

setTimeout(function() {
	emit('action', {name: 'updateImages', data: []});
}, 5000);

Would be interesting, and we can consider the implications of making emit work in both ways, allowing you also to emit default events.

@brandonros
Copy link

@jbucaran I think it the time it took you to write this response, you could have made emit('action', {name: 'updateImages', data: []}); work. :)

@jorgebucaran
Copy link
Owner Author

jorgebucaran commented Aug 9, 2017

@brandonros It didn't take so long and this is good documentation for subscribers too! :)

So, what about this:

const Sender = emit => ({
  events: {
    send(state, actions, { name, data }) {
      return actions[name](data)
    }
  }
})

const emit = app({ 
  mixins: [Sender]
})

Then use it to call actions directly outside your app.

emit("send", { name: "updateImages", data: [...] })

Making it work for action might be possible too, but would require some "hacking" since action is one of the default events.

@brandonros
Copy link

brandonros commented Aug 12, 2017

@jbucaran Thank you for taking the time to supply that example. I appreciate that and I hope it helps somebody else.

I've got one more "idea" that I came up with using this, just playing around with it.

I really don't like having to set up Browserify or Webpack or all of that crap. I'm trying to avoid Babel + JSX as well, just for exercise.

Back in the jQuery days, I used to do a lot of:

$('body').html('<div>a really big <span>html string</span></div>')

I saw you guys had the ability to use the (html`html string here`), but that requires Browserify.

Is it possible to get compiled/ported so you can just include a page, and then call h(html('long string')) or something similar?

@brandonros
Copy link

I just spent 15 minutes trying to figure out why the "load" event isn't working.

Your codepad says it is 'init' instead of load. Please update the docs. https://github.com/hyperapp/hyperapp/blob/master/docs/events.md

@andyrj
Copy link
Contributor

andyrj commented Aug 12, 2017

Load is in 0.11 which should be out anytime now... Master is ahead of npm publish by a bit.

@brandonros
Copy link

brandonros commented Aug 12, 2017

Thunks do not work and when I try to install it to help debug to provide more information (all I can get is a minified version), I get rollup.config.js not found

Edit: I see what you mean about master. Can you put the rollup.config.js in the repo please?

Edit: I was trying to build an old version. Ignore, thanks!

@andyrj
Copy link
Contributor

andyrj commented Aug 12, 2017

I recall someone else running into that when npm installing the package from master git repo. I have always had to make local copy and create a symlink in node_modules to the local repo to test newest version. Hopefully 0.11 will be out soon.

@Swizz
Copy link
Contributor

Swizz commented Aug 12, 2017

@brandonros As h implement the normalised hyperscript representation, that allow you to use hyperscript-helpers. That allow you to use an elm like syntax to create your virtual dom node.

import { h, app } from "hyperapp"
import helpers from "hyperscript-helpers"

const { div, h1 } = helpers(h)

app({
  state: {
    title: "Hi.",
  },
  view: state => 
    div(null, [
      h1(null, state.title)
    ])
})

I am also working on my own implementation, to create a more optimised (tree shaking, right h call) experience for Hyperapp and Picodom users.

@jorgebucaran
Copy link
Owner Author

jorgebucaran commented Sep 20, 2017

Webpack... bundles are huge

They can get bigger than rollup if you are bundling a ton of modules, but that's because of how webpack works.

[webpack] work by wrapping each module in a function, putting them in a bundle with a browser-friendly implementation of require, and evaluating them one-by-one. That’s great if you need things like on-demand loading, but otherwise it’s a bit of a waste, and it gets worse if you have lots of modules.

and

If you need code-splitting, or you have lots of static assets, or you’re building something with lots of CommonJS dependencies, Webpack is a better choice. If your codebase is ES2015 modules and you’re making something to be used by other people, you probably want Rollup.

Source

Also:

[webpack] ...at runtime, each of those module functions is evaluated in turn to populate the module cache. This architecture has lots of advantages — it makes it possible to implement advanced features like code-splitting and on-demand loading, and hot module replacement (HMR).

Source

@selfup
Copy link
Contributor

selfup commented Sep 20, 2017

Webpack is fine ❤️ . I use it and the API is straightforward.

@corysimmons Let's try to be a bit more civil 😛

Also scope hoisting has helped a ton! My boilerplate counter is only 2kb gzipped using webpack, So bundles being very large might not apply so much anymore.

Let's not blame JS fatigue on a single library 🙏


Otherwise, I wonder if this should be a Mixin (official Mixin) or in core 🤔

Moving lazy loading talk

Separate issue: #379

@corysimmons
Copy link

Yeah I'm toxic. Bye guys.

@jorgebucaran
Copy link
Owner Author

@corysimmons Whoa, I just said: "that's not very nice man" because you went on a little off-topic rant blasting webpack.

And now you left the organization too? I don't get it, were you expecting anyone to support you on this or pretend you didn't say anything?

@okwolf
Copy link
Contributor

okwolf commented Sep 20, 2017

  • Optimize patch?

@jorgebucaran is this referring to what #378 would do to help fix #373?

@jorgebucaran
Copy link
Owner Author

@okwolf Nope, #373 came up just recently. Optimize patch involves rewriting the patch function.

The objective is to rewrite it in less code and make it faster at the same time. 🏇💥

@okwolf
Copy link
Contributor

okwolf commented Sep 20, 2017

The objective is to rewrite it in less code and make it faster at the same time. 🏇💥

@jorgebucaran I understand how to measure code size, but what metric are we using to determine performance in this instance?

@jorgebucaran
Copy link
Owner Author

We use js-framework-benchmark.

@vladshcherbin
Copy link

An interesting project to put on a test, will there be SSR support in 1.0 or this feature is not on a roadmap?

@jorgebucaran
Copy link
Owner Author

@vladshcherbin Thanks! Hyperapp now provides automatic SSR hydration out of the box since 0.14.0.

@vladshcherbin
Copy link

@jorgebucaran yeah, I've seen hydration in the docs.

I mean, when a user requests a page, how do you generate html for this page on server (using node for example), is there any demo/repo of this?

@jorgebucaran
Copy link
Owner Author

jorgebucaran commented Oct 14, 2017

@vladshcherbin Entirely up to you to handle. If I was worried about SEO and time-to-interactive in a large-ish app, I would just send the HTML to the client and let Hyperapp hydrate it.

Is there any demo/repo of this?

SSR is not my cup of tea, so I haven't been interested in making a demo or repo, but we hydrate pre-rendered HTML at work using Hyperapp already, so it works.

Maybe @andyrj, @SkaterDad or @zaceno can comment about Hyperapp and SSR in general. 🙏

@zaceno
Copy link
Contributor

zaceno commented Oct 14, 2017

Sorry I'm no SSR-er either. Don't know how it works even in principle. But I'm curious to learn :)

@zaceno
Copy link
Contributor

zaceno commented Oct 14, 2017

One thing I do know works, is: setting up a fake browser environment in node using jsdom or undom (well undom has a bug atm, but anyway), and then running hyperapp server-side, and serialize the fake dom into html.

That would be server-side rendering with hyperapp, in my estimation. But I'm not sure that's what we're talking about.

@maxholman
Copy link

@zaceno @vladshcherbin - I've been playing with hyperapp/ssr/jsdom recently. I've thrown my discoveries and a working demo into a repo - https://github.com/maxholman/hyperapp-ssr-jsdom-example

@jorgebucaran
Copy link
Owner Author

@zaceno That would be server-side rendering with hyperapp, in my estimation. But I'm not sure that's what we're talking about.

That's pretty much it! :)

@zaceno
Copy link
Contributor

zaceno commented Oct 14, 2017

@jorgebucaran really?! And then what? You just serve up the plain HTML? Or hydrate it into a client side instance (which sounds like a lot of extra work for no extra benefit). I rhink I just haven't understood the point of SSR... Why not just use PHP then? (Not being sarcastic. Just explaining what it is I don't get)

@AlexanderChen1989
Copy link

@jorgebucaran is there a way to Log state updates and action information to the console?

@okwolf
Copy link
Contributor

okwolf commented Oct 15, 2017

@AlexanderChen1989 there's an official logger, although it's in the shop right now, getting a tune-up for compatibility with > 0.12.1 Hyperapp (post mixins). It will definitely be released before 1.0.

@AlexanderChen1989
Copy link

@okwolf how can i implement old events like behavior? i have read new source code, but cannot find events like function

@jorgebucaran
Copy link
Owner Author

@AlexanderChen1989 What were you trying to do exactly? Depending on what you are doing the solution may be different now that there are no custom events.

@AlexanderChen1989
Copy link

im curious how to implement logger?

@jorgebucaran
Copy link
Owner Author

@AlexanderChen1989 Here.

@AlexanderChen1989
Copy link

@jorgebucaran good idea, thanks

@okwolf
Copy link
Contributor

okwolf commented Dec 16, 2017

This issue is pretty far out of date with what is actually being worked on for 1.0.0 now.

What should we do?

@jorgebucaran
Copy link
Owner Author

jorgebucaran commented Dec 17, 2017

Hmm, I want to merge #497 before I publish 1.0 and before I publish 1.0 I want to publish 0.18.0 so people that need it right now can start using it.

EDIT: I'll close here when 1.0 is officially out.

@jorgebucaran
Copy link
Owner Author

Closing in favor of #507! 🎁 🎉🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests