Progressive rendering with Catberry.js

Progressive rendering with Catberry.js

rdner
Denis Rechkunov
SDE at

Framework Overview

Flux Stores

Flux Stores in Catberry.js

Directory "catberry_stores" with .js-files
			./catberry_stores/
  doge/
    Wow.js
    Such.js
    Store.js
  grumpy-cat/
    No.js

How to Implement a Store

			class MyStore {
			 constructor(locator) {
			  this.$lifetime = 60000; // how long to cache the data (ms)
			 }
			 load() { /* returns data (or promise) for components */ }
			 handleAddItem(args) { /* handles "add-item" */ }
			}
			module.exports = MyStore;
		

Notify that Store's Data is Changed

			handleAddItem(args) {
			 // you can get routed parameters from URI
			 this.$context.state.newsCategory;
			 // and notify about changes
			 this.$context.changed();
			}
		
The $context is a public interface of the framework.
Every store and component instance has this property.

Extracting Parameters from URL

			// you define a route
			'/some/:id[Store1,Store2]/actions?q=:query[Store1]'
			// go to this link
			'/some/123/actions?q=find-a-cat'
			// then Store1 and Store2 will have 
			this.$context.state.id === '123'
			// and only Store1 will have 
			this.$context.state.query === 'find-a-cat'
		

Components

Cat-components vs Web-components

Feature Cat Web
Define custom elements Yes Yes
Have server-side rendering Yes No
Support several template engines Yes No
Organized like directories in a project Yes No
Can be installed/published using NPM Yes No
Can be auto-discovered in a project Yes No
Shadow DOM (styles isolation) No Yes

Cat-component

			hello-world/
  index.js # exports a class
  template.hbs # is rendered inside the component's tag
  error.hbs # is rendered instead if error occurs
  cat-component.json # defines the component

Using Components as Custom Tags

			<cat-hello-world id="uniq-id" cat-store="some/Store">
			</cat-hello-world>
		

The template will be rendered inside the tag and if it contains other components' tags the process repeats recursively.

All tag attributes are accessible via this.$context.attributes

How to Implement a Cat-Component

			class MyComponent {
			 constructor(locator) { /* resolve smth from the locator */ }
			 render() { /* gets data (or promise) for the template */ }
			 bind() { /* component appears in DOM */ }
			 unbind() { /* component is removed from DOM */ }
			}
			module.exports = MyComponent;
		

Receiving Data from a Store

			render() {
			 return this.$context.getStoreData()
			  .then(data => /* success, the Store returned data */ )
			  .catch(error => /* no luck :( */ );
			}
		

Sending Action to a Store

			this.$context.sendAction('add-item', item)
			 .then(result => /* success, we have a result */ )
			 .catch(error => /* no luck :( */ );
	

Service Locator

Service Locator

			// service name, class, isSingleton
			app.locator.register('uhr', UHR, true);
			// resolve it in a constructor
			class MyComponent {
			 constructor(locator) {
			  this._uhr = locator.resolve('uhr');
			 }
			}
		

Progressive Rendering

Long Story Short

developers.google.com

Server-side

Browser-side

TTFB Using Progressive Rendering

DEMO

Quick Start

			$ npm -g install catberry-cli
			$ catberry init example
		
catberry-example
catberry-todomvc
catberry-homepage
catberry-debugger

Keep in touch

catberry.github.io
github.com/catberry/catberry

Thank you!
Questions?