-
Notifications
You must be signed in to change notification settings - Fork 21
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
proposal: await dependencies inside component function #31
Comments
Obviously, since we can't use ..
await pull('moment') // just load
await pull('events', node) // subscribe
.. Eventually people could trivially replace (the former) with the real |
This is similar to the async render discussion. If you either fetch data or code, you still need to render something back to the user, like a loading spinner. How do you handle that here? |
Conceptually, just think of the component being able to flush/pipe partial updates to the DOM early, rather than having to do it all at once at the end using the export default async (node, data) => {
const o = once(node)
, { pull } = ripple
o.classed('is-loading', true)
const posts = await pull('posts')
o.classed('is-loading', false)
o('h1', 1)
.text('HN')
o('li', posts)
.text(d => d.title)
} The component is still declarative and the contract is still a function of data. It just doesn't have to be instantaneous (although it can be too). I should add: the original reason I didn't like using What's even more awesome, is that I just realised using Resources are cached offline, so in subsequent refreshes, or on the server where it's always a local cache lookup, you don't see the loading state and the ticker never ticks once. |
So data dependencies would no longer be passed through data argument of component put declared within using pull/subscribe? Subscribe would use generators/yield to cause redraw.
… On 4 Dec 2016, at 16:12, Pedram Emrouznejad ***@***.***> wrote:
Conceptually, just think of the component being able to flush/pipe partial updates to the DOM early, rather than having to do it all at once at the end using the return keyword. Simple example:
export default async (node, data) => {
const o = once(node)
, { pull } = ripple
o.classed('is-loading', true)
const posts = await pull('posts')
o.classed('is-loading', false)
o('h1', 1)
.text('HN')
o('li', posts)
.text(d => d.title)
}
The component is still declarative and the contract is still a function of data. It just doesn't have to be instantaneous (although it can be too).
I should add: the original reason I didn't like using return was that it necessitates the existence of some reconciler, so you can't use the component standalone. In this case, you can simply require any component, invoke it on any node with some data.
What's even more awesome, is that I just realised using await is a very natural way to pause/resume a component à la Fiber 😱 I added an arbitrary 2 second delay on serving the posts, and another fast ticking counter parallel to the component. The other ticker ticks whilst the main component is paused on loading!
Resources are cached offline, so in subsequent refreshes, or on the server where it's always a local cache lookup, you don't see the loading state and the ticker never ticks once.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
I think we'd keep the data argument, as the parent may pass down data via that. But I think subscribed dependencies should also still be available there so it's the one place the component can get everything it needs. This also means you can skip
I'm thinking to use the existing mechanism actually: just tag the node with the dependency. Then whenever there is an update to the dependency, it redraws the node. This way, it's just one render function and the component is like the sink of the stream, rather than trying to manage the lifecycle of the stream in the component. |
Fixed in 0.7.0. /cc @domenic if he has any thoughts/advice on how imports should work in a universal context, i.e: what would happen if a component that is rendered on both server and client uses import?
|
I'm not sure what the question is exactly. For the foreseeable future, only absolute URLs and specifiers starting with /, ./. and ../ will work on the client (and will be interpreted as relative URLs). My understanding is that in Node it is still up in the air how specifiers will be interpreted; environments like Babel have picked one interpretation that will probably diverge from whatever is eventually implemented in Node core. It sounds like this might a transpiler repo, though, in which case the usual course I've seen is for people to just make up semantics for specifiers (like Babel does) instead of using the native ones that are implemented in the browser/will be implemented in Node. |
Automatic lazy loading of resources during the rendering pipeline works pretty well using the backpressure module. The declarative usage uses the imperative form
ripple.pull()
under the hood. This is very similar to the dynamic import proposalimport()
which looks pretty neat, and I think it would be better to align the API with that. In addition, I think this means we should be able to keep everything in one function rather than define the component's dependencies in theneeds
header (akagetInitialProps
). Proposal:import
would just load from the core cache, or fetch and load.subscribe
would do the same, but also redraw that component when there are updates to the resource.The spec only mentions how to resolve module specifiers that start with
/
,./
or../
and leaves resolving "bare" import specifiers for later. However, I'm not sure how these paths can ever be interpreted in a universal context (i.e. as files in Node, but URLs in browser?). I think starting with bare specifiers would be a small change, more useful and make the most sense (e.g.import("moment")
).The core is also the equivalent of what the standard calls module map. The placeholder object whilst a fetch is in-flight just needs to be changed to a Promise however.
/cc @rauchg @developit @jordwalke for thoughts following on from this twitter discussion.. do you think this would work?
The text was updated successfully, but these errors were encountered: