These are chat archives for ractivejs/ractive

24th
Jul 2018
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 08:59 UTC
here is the first async component/dependency loading attempt in production with browserify
you can play with the live demo and take a look at the source code
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 10:03 UTC
is there any way to tell Ractive something like "Component Foo is available from now on, you should refresh all instances"?
like we do the following manually:
Ractive.components.Foo = Ractive.extend(...)
{{#if @shared.availableDeps.foo}}
  <Foo> hello there </Foo>
{{/if}}
{{#if @shared.availableDeps.foo}}
  <Foo>other instance</Foo>
{{/if}}
and then set @shared.availableDeps.foo manually
(wait, isn't this a solid solution already? o_O)
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 11:19 UTC
async-graph-load.gif
Giannis Koutsaftakis
@kouts
Jul 24 2018 11:23 UTC
Nice!
Joseph
@fskreuz
Jul 24 2018 12:02 UTC
iirc, async components are just promises that resolve a constructor. you can probably just chain a "pass-through" .then()
.then(component => {
  console.log('do stuff')
  return component
})
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 12:16 UTC
that's correct but this case is a little bit different
(I've moved the example here, btw)
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 12:53 UTC
I'm using an async component to be able to use a regular component as if it is designed for async usage, like this
so my question comes to this point: how can I combine the async component's behaviour with a regular component? in other words, how can I delay Ractive til a specific time when Ractive wants to render a component?
Joseph
@fskreuz
Jul 24 2018 13:12 UTC
So in short, render all the things only when both regular and async components are ready? Hmm...
Anchors come into mind.
Although you'd have to do the instantiation and wiring yourself.
Arnaud Dagnelies
@dagnelies
Jul 24 2018 15:37 UTC
sometimes it's easier to load everything at the start and display a loading icon / progress bar :p
Are you also sure you need a "component"?
I also have an app which needs to display several custom forms which are built server side. In order to do that, I simply fetch them async and "insert" them using resetPartial() . Works perfectly.
Arnaud Dagnelies
@dagnelies
Jul 24 2018 15:43 UTC
I've wrapped it in a simple tag "<remote url='{{remoteContentUrl}}' />" and voilà. I don't think it would work with components, but with partials, it works out of the box.
Btw, I don't know what you're loading but 2.8 MB is so heavy that it's already a reason not to use it for most people
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 15:54 UTC

sometimes it's easier to load everything at the start and display a loading icon / progress bar :p

from the point of view of the developer, I think it's "always" :D

I didn't aware of resetPartial() method. that might be useful in some cases
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 16:03 UTC
2.8 MB is nearly nothing for my target applications. Think that we'll build a 100MB webapp that loads in 3 seconds and progressively installs the required components (both the Ractive components and other libraries) and saves/caches the "installed" parts locally. When an update is needed, only diffs will be sent over the wire, patch will be applied on the client side
for example, I want to build a pcb drawing software with Ractive, like that: https://github.com/ceremcem/aecad
also, I would love to implement an onshape.com like 3D CAD application
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 16:24 UTC
think that we are handing the scripts over to the user for downloading (by a simple download script). this way users can share the application (or even components) offline
Chris Reeves
@evs-chris
Jul 24 2018 16:24 UTC
that's a big webapp 😅
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 16:24 UTC
huuuuuuuuuuuuuuuuuuuuuuge :)
Chris Reeves
@evs-chris
Jul 24 2018 16:26 UTC
for async components, any reason not to just use the placeholder partial while they load and let everything else go?
or do you have intercomponent dependencies?
my approach right now is to have everything being the core app load async, throw up aspinner while loading, and await all the deps as async views are opened
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 16:57 UTC
you mean "a component depends on one or more async component" by "intercomponent dependencies", right? if so, yes, I have such components, like CouchDB Design Document Editor that depends on ACE editor, here
problem with the placeholder is that I think we should be able to change a component into an async component at any time. so, every component should be async, I think
sorry, it isn't an exact answer. let me try again
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 17:03 UTC
unable... I'm not sure if I can explain anything wrong with placeholder approach. I think I didn't get it well
Chris Reeves
@evs-chris
Jul 24 2018 17:22 UTC
by intercomponent dependencies, I mean that componentA needs a reference to its sibling componentB in order to interact with it
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 17:22 UTC
we can mount any component to any anchor at any time. but this is not the case. we already know and declare what component should be mounted where at the time of coding. problem is that: think we used component Foo 100 times in the application and we forgot the anchor names already. When component Foo is fetched, how do we know which anchors to mount it?
Chris Reeves
@evs-chris
Jul 24 2018 17:23 UTC
as long as it's just parent-child, you can usually reasonably block until all deps are loaded or throw up a placeholder that indicates a loading state
you can have multiple anchors named foo
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 17:23 UTC
for intercomponent deps: I always define components globally, so any component may or may not depend to any other
Chris Reeves
@evs-chris
Jul 24 2018 17:24 UTC
just need to throw instances in until they all fill, but it's probably not that simple in a real app
ah, that makes things a little more difficult
I have a few common components that are global and assumed to be in place, but I import deps explicitly for everything else, mostly for this reason
makes it a lot easier to keep up with what's ready and when
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 17:43 UTC
think that we could pass the events to child components with {{extra-attributes}}. we could easily define "synchronizer components" like this
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 17:48 UTC
this works, but we have to proxy every event within the synchronizer component, which would force us keep event declarations even in both components (source of possible bugs)
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 17:58 UTC
it's a very long name, but what I mean is Synchronizers concept , like Components or Partials. Think that we defined a sync component Foo. this component got very very big in time, so we decided to load it asynchronously. We'll define another file that contains a synchronization definition, something like this:
Ractive.synchronizers.Foo = Ractive.extend({
  template: `
    {{#if @shared.deps.Foo === true}}
      {{doTheMagic}}
    {{else}}
      <p>Fetching Foo in progress...</p>
    {{/if}}
  `,
    onrender: function(){
      // we now know that user needed the Foo component, we should start fetching 
    }
})
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 18:04 UTC
then we require this file synchronously. When <Foo /> component is about to render, Ractive will look if there is a component already defined with the name Foo. if not, it will look if there is a synchronizer defined. If a synchronizer is found, it will be used as if it is the Foo component. when a synchronizer needs to {{doTheMagic}} (user will set @shared.deps.Foo or whatever variable he chooses on his own), the Foo synchronizer will know that it should use Ractive.components.Foo for the magic, under the hood.
Chris Reeves
@evs-chris
Jul 24 2018 18:09 UTC
I got partway through adding events to attributes and extra-attributes, but then I got to builtin component events and it got a little weird
I suppose builtins should be implicitly included in attributes: { events: [] }
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 18:15 UTC
does this mean this (line 14) should (eventually) work?
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 18:21 UTC
think that we have an excel component. this might be a huge component and it might take quite some time with slow networks. So we might design our synchronizer component in a way where it is able to display simple contents in a table during actual component fetch
like we can provide a <textarea> while <ace-editor > is being fetched
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 18:53 UTC
like this:
Chris Reeves
@evs-chris
Jul 24 2018 18:54 UTC
theoretically, that would work
I haven't tried it in practice yet
with that, it would pass through anything not a builtin (render, init, etc)
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 18:54 UTC
async-fallback.gif
Chris Reeves
@evs-chris
Jul 24 2018 18:58 UTC
you could also build your synchronizer with a macro parial, which is what async components use under the hood
they make controlled rendering a lot easier
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 19:00 UTC
that's great news!
Chris Reeves
@evs-chris
Jul 24 2018 19:00 UTC
<synchronizer component="ace-thingy" other args="here"><textarea>tmp for loading...</textarea></synchronizer>
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 19:00 UTC
a-ha! macro is already documented!
hmm. can not I {{doTheMagic}} with macro?
Chris Reeves
@evs-chris
Jul 24 2018 19:02 UTC
you should be able to
you can render any template in there at any time
using handle.setTemplate
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 19:22 UTC
do we have any example for the macro usage?
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 19:32 UTC
...I think I can find something useful in https://github.com/evs-chris/raui
Giannis Koutsaftakis
@kouts
Jul 24 2018 19:47 UTC
@ceremcem how do you structure your modules loading? I'm in the process exploring options for async loading of components that comprise "views" files
Does browserify help with that?
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 19:49 UTC
I setup the browserifying process for building certain bundles from certain entry points (files)
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 19:57 UTC
for example, that browserifying flow builds output/js/app.js from app.ls and output/js/dep.js from dep.ls. I'm simply loading app.js with html document's script tag and requesting the dep.js in Ractive.complete with getScriptCached
Chris Reeves
@evs-chris
Jul 24 2018 20:27 UTC
yeah, I need to make a macro tutorial
on my roundtoit list
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 20:44 UTC
if I could create the component with events, we are all set to go!
Chris Reeves
@evs-chris
Jul 24 2018 20:46 UTC
that was the goal anyways 😀
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 21:15 UTC
that was a piece of cake!
(hold on)
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 21:46 UTC
This is the HOWTO to convert sync components into async components.
Cerem Cem ASLAN
@ceremcem
Jul 24 2018 23:02 UTC
@evs-chris How can I make the code updated when something is written into the textarea? Playground