glimmerjs / glimmer.js

Central repository for the Glimmer.js project
https://glimmerjs.com
MIT License
746 stars 75 forks source link

support async logic inside ssr renderer #367

Open lifeart opened 2 years ago

lifeart commented 2 years ago

it will be great to have possibility to provide kinda "waiters" to ssr render functions, to allow render some lazy-loaded components or components with async data.

awaiters could be registered on the fly, during initial rendering

renderToString(App, { awaiter } );
class App extends Component {
   constructor(owner, args) {
      super(owner, args);
      // sync awaiter registration;
      this.onComponentLoaded = this.args.awaiter.register("componentLoaded");
      import('components/my-component').then((result) => {
         this.componentToRender = result.default;
         setTimeout(() => {
              // async awaiter  resolution
              this.onComponentLoaded.resolve();
          });
      })
   }
}
class App extends Component {
   @tracked data;
   constructor(owner, args) {
      super(owner, args);
      // sync awaiter registration;
      this.onDataLoaded = this.args.awaiter.register("dataLoaded");
      fetch('api/users').then(result => result.toJSON()).then((data) => {
                  this.data = data;
                  setTimeout(() => {
                        this.onDataLoaded.resolve();
                   });
       });
   }
}

renderToString function should wait for all awaiters to be resolved before returning output

// awaiter may be an global hook, to simplify it's usage inside components

lifeart commented 2 years ago

looks like best way to do it, is use "Vue" way, having independent router instance, and resolve all nessesary deps before rendering.

see "addResolver" section https://github.com/josemarluedke/glimmer-apollo/issues/48#issue-1029901494