1.3.3 • Published 7 years ago

taco-bell v1.3.3

Weekly downloads
2
License
MIT
Repository
github
Last release
7 years ago

taco-bell

Taco bell reactive js framework with a single model source of truth. Simple as rice and beans.

building

Prerequisite: npm/node

  • ./install to install dependencies
  • tsc to build

Examples

Starter Template

Tetris

Preview

Todo mvc

Preview

Optimizations

Taco bell completely avoids use of HTML and instead operates on DOM elements themselves. There are two optimizations to bear in mind here:

  1. Browser repaints: The browser will only repaint once per javascript execution. So if an event is called, repaint is blocked regardless of how many dom nodes we manipulate.

  2. Browser reflow: Modifying a DOM node property that is a factor to the DOM's rendering will trigger a recalculation of the node and related node's appearance, e.g. their size, position, etc. Reflows may take place multiple times during javascript execution provided the node being modified is currently in the DOM. Taco Bell takes the approach to carefully remove nodes from the DOM, perform updates, and at the end of a cycle replace the nodes into the DOM so that only a single reflow is calculated.

 ...
 model.children = new ModelArray<string>();
 model.children.add('Bob');
 model.children.add('Alice');

 new Component('grand-parent', document.getElementById('app'))
    .child(
        new Collection('parent')
            .children(model.children, (name, i) -> {
                return new Component('child')
                    .withAttribute('id', i)
                    .withText(name);
            })
    );
 
 // explicitly start a cycle to initiate the app
 ComponentQueue.cycle();

Yields

<div id="app">

 <grand-parent>
    <parent>
        <child id="1">Bob</child>
        <child id="2">Alice</child>
    </parent>
 </grand-parent>
 
</div> 

Within a cycle Taco Bell progressively updates a pointer to the greatest common ancestor of all dirty nodes. Before any node is updated, it is removed, and if it is an ancestor of the current ancestor, then it is made the new ancestor, while all of its children are also removed. At the end of the cycle the ancestor is replaced into the dom and all state is reapplied (e.g. event listeners). In the above example, making a change to one of the children, e.g.

model.children.get()[0].set('Eve'); 

will trigger a cycle to only remove Bob from the list and replace him with Eve.

Managing the Cycle Cycles are triggered in multiple ways

  • implicitly by user events via AbstractComponent#on(callback). When callback completes a cycle will be triggered to apply any changes recorded by executing the callback to the DOM.
  • per component via AbstractComponent#reinit will trigger a cycle for all changes recorded to the component.
  • explicitly via ComponentQueue#cycle. This can be called anytime, however you should only need to call it in two cases.
    1. In your application startup script after you have created the DOM in order to indicate the app is ready
    2. Anytime changes need to be applied programmatically, i.e. not in response to a user initiated event bound to a component with AbstractComponent#on(callback). Examples can be found here and here

1.3.3

7 years ago

1.3.2

8 years ago

1.3.1

8 years ago

1.3.0

8 years ago

1.2.15

8 years ago

1.2.14

8 years ago

1.2.13

8 years ago

1.2.12

8 years ago

1.2.11

8 years ago

1.2.10

8 years ago

1.2.9

8 years ago

1.2.8

8 years ago

1.2.6

8 years ago

1.2.5

8 years ago

1.2.4

8 years ago

1.2.3

8 years ago

1.2.2

8 years ago

1.2.1

8 years ago

1.2.0

8 years ago

1.1.12

8 years ago

1.1.11

8 years ago

1.1.10

8 years ago

1.1.9

8 years ago

1.1.8

8 years ago

1.1.7

8 years ago

1.1.6

8 years ago

1.1.5

8 years ago

1.1.4

8 years ago

1.1.3

8 years ago

1.1.2

8 years ago

1.1.1

8 years ago

1.1.0

8 years ago

1.0.0

8 years ago