Progressive rendering with Catberry.js

Progressive rendering with Catberry.js

Denis Rechkunov
SDE at

Framework Overview

Flux Stores

Flux Stores in Catberry.js

Directory "catberry_stores" with .js-files

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
			 // and notify about changes
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
			// go to this link
			// then Store1 and Store2 will have 
			this.$ === '123'
			// and only Store1 will have 
			this.$context.state.query === 'find-a-cat'


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


  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">

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



TTFB Using Progressive Rendering


Quick Start

			$ npm -g install catberry-cli
			$ catberry init example

Keep in touch

Thank you!