Sunday, 18 June 2017

Data Persistence in Browser with JavaScript Part-1



IndexedDB:

Unlike SQL databases that use columns to represent different attributes of schema IndexedDB uses JavaScript objects to represent data. Also indexedDB is very fast due to the indexing feature. The indexing feature allows developers to do high performance searches where the objects are indexed with a key. More over it has asynchronous APIs and is able to store much larger data compared to 'Web Storage'. The storage limit is calculated at 50% of the available memory on the hard drive. So in the case if the available memory on the hard drive is 100 GB then the limit for indexedDB would be 50 GB.

Opening an IndexedDB database:

var request = window.indexedDB.open("test-database", 1);Arial

The 'window.indexedDB.open("test-database", 1)' function call opens a database with its name set to 'test-database' and version number to '1'. This means that the schema structure will be specific to the version number and if the schema structure needs to be updated then version number will also be updated.

The code below shows sample usage for indexedDB:

let indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;

var dbOpen = indexedDB.open("SampleDataBase", 1);

dbOpen.onupgradeneeded = function() {
    var db = dbOpen.result;
    var store = db.createObjectStore("SampleObjectStore", {keyPath: "id"});
    var index = store.createIndex("NameIndex", ["name.last", "name.first"]);
};

dbOpen.onsuccess = function() {

    var db = dbOpen.result;
    var transaction = db.transaction("SampleObjectStore", "readwrite");
    var store = transaction.objectStore("SampleObjectStore");
    var index = store.index("NameIndex");

    // add data
    store.put({id: 1000, name: {first: "Edward", last: "Jones"}});
    store.put({id: 1, name: {first: "John", last: "Hancock"}});
    
    // query
    var getUser1 = store.get(1000);
    var getUser2 = index.get(["Hancock", "John"]);

    getUser1.onsuccess = function() {
        console.log(getUser1.result.name.last);  // Jones
    };

    getUser2.onsuccess = function() {
        console.log(getUser2.result.name.last);   // Hancock
    };

    // close db when transaction is done
    transaction.oncomplete = function() {
        db.close();
    };
}

Saturday, 10 June 2017

Generics in TypeScript


The ability to build reusable components in a programming language enables developers to be DRY while coding. This also helps reduce the software complexity and is much easier to maintain. Each reusable component can also be tested for edge cases which makes the code robust.


Generic Functions:

In TypeScript generic functions can be useful for implementing factories. The following example shows how generic functions can be implemented:
function getType<T>(input: T): string{
   return typeof input;
}


getType("hello"); //string
getType(100); //number
getType({'city': 'Sanfrancisco', 'id': 1}); //object


In this example the function 'getType' can take any type as an argument. So the argument "hello" will return a 'string' type. Similarly the arguments 100 and {'city': 'Sanfrancisco', 'id': 1} will return 'number' and 'object' types respectively. 

Generic Classes:

Using generic classes developers can constrain the type used by a class. Also it enables developers to use a single class for various purposes by changing the type and method definition.


class BasicCalculator<T>{
    add: (value1:T, value2:T) => T;
    multiply: (value1:T, value2:T) => T;
    subtract: (value1:T, value2:T) => T;
    divide: (value1:T, value2:T) => T;
}



///Using number type.

let calc = new BasicCalculator<number>();

calc.add = function(a, b){ return a+b;}
calc.multiply = function(a, b){ return a*b;}
calc.subtract = function(a, b){ return Math.abs(a-b);}
calc.divide = function(a, b){ if(a==0){ return 0; } if(b!==0){ return a/b; } return -1;}

console.log(calc.add(1, 3)); //4
console.log(calc.multiply(1, 3)); //3
console.log(calc.subtract(1, 3)); //2
console.log(calc.divide(1, 3)); //0.33333...


///Using string type.

let calcString = new BasicCalculator<string>();

calcString.add = function(a, b){ return a.length+b.length+"";}
calcString.multiply = function(a, b){ return a.length*b.length+"";}
calcString.subtract = function(a, b){ return Math.abs(a.length-b.length)+"";}
calcString.divide = function(a, b){ if(a.length==0){ return 0+""; } if(b.length!==0){ return (a.length/b.length)+""; } return -1+"";}

console.log(calcString.add("Apple", "Banana")); //11
console.log(calcString.multiply("Apple", "Banana")); //30
console.log(calcString.subtract("Apple", "Banana")); //1
console.log(calcString.divide("Apple", "Banana")); //0.833333...

The examples shows how 'BasicCalculator' can be instantiated with multiple types and when instantiated with a particular type it is constrained only that one. 

Generic Interfaces:

Similar to generic classes the generic interfaces can be used to implement methods that process object of only a certain type. Generic interfaces can more concise than generic classes by being able to provide a general signature for several implementations. 
interface identityInterface<T> {
    (arg: T): T;
}

function customIdentityFunction<T>(arg: T): T {
    return arg;
}

let newIdentityNum: identityInterface<number> = customIdentityFunction;

console.log(newIdentityNum(45));//45

let newIdentityObj: identityInterface<object> = customIdentityFunction;

console.log(newIdentityObj({'name': 'Phil', 'id': 76}));//{'name': 'Phil', 'id': 76}

let newIdentityStr: identityInterface<string> = customIdentityFunction;

console.log(newIdentityStr("test"));//"test"


The 'identityInterface' provides a general signature for multiple implementations. For instance setting type to 'number' will constraint 'customIdentityFunction' to only return a number.Similarly the types object and string will constraint the function to the respective type.

Thursday, 1 June 2017

Currency parser with Web Components

Web Components is a set of features being added to the HTML DOM to allow the development of custom components. This also allows developers to have encapsulation in their code which prevents undesired conflicts.

Fig 1.0 Web Components Spec

Custom Elements:

Allows developers to define new types of elements in html.

<currency-parser value="1000.456" decimal="2digit" addSymbol="true" symbol="$"></currency-parser>

Shadow DOM:

Shadow DOM helps to tackle the DOM tree encapsulation issue. The shadow DOM hides JavaScript, HTML and CSS from parent document to prevent collisions from other modules.

HTML Templates:

Templates are markups that can be instantiated during runtime for use in the application. 

<template>
    <div>
        ...
    </div>
</tempalte>

HTML Imports:

This provides way to include HTML documents in other HTML documents. The imported document can contain its own <style> and <script>. 


<link rel="import" href="/path-to-folder/currency-parser.html"></link>


Demo
In this demo I have built a currency parser that can transform any given value to the right currency. This is a very simple program which shows the different aspects of web components.

index.html:
<!DOCTYPE html>
<html>
    <head>
        <title>Currency Parser</title>
        <link rel="import" href="./currency-parser.html">
    </head>
    <body>
        <h1>Currency Parser</h1>
        <currency-parser value="1000.456" decimal="1-digit" addSymbol="true" symbol="$">
        </currency-parser>
    </body>
</html>

In the 'index.html' file the 'currency-parser.html' file is imported using HTML Imports and using custom element tag 'currency-parser' the new web component can be instantiated.

currency-parser.html:
<template>
<style>
</style>
<div>
    <span id="currency-value"></span>
</div>
</template>
<script>
(function(){
    let thisDoc = document.currentScript.ownerDocument;
    let thatDoc  = document;
    let tmpl = thisDoc.querySelector('template');
    let Element = Object.create(HTMLElement.prototype);
    let shaDowRoot;
    Element.createdCallback = function(){
        shadowRoot = this.createShadowRoot();
        let clone = thatDoc.importNode(tmpl.content, true);
        shadowRoot.appendChild(clone);
        
        //Web Component Logic
        let decimal= Number(this.getAttribute('decimal').split("-")[0]);
        let finalValue = Number(this.getAttribute('value')).toFixed(decimal);
        let field = shadowRoot.querySelector('#currency-value');
        if(JSON.parse(this.getAttribute('addSymbol'))===true){
            field.innerHTML = this.getAttribute('symbol')+""+finalValue;
        }else{
            field.innerHTML = finalValue;
        }
    }
    thatDoc.registerElement('currency-parser', {prototype:Element});
})()
</script>

The 'currency-parser.html' file contains template(layout) for the 'currency-parser' web component. Also it contains JS logic for attaching this component to the Shadow DOM and the internal logic for parsing the currency.

Output in Chrome:







Saturday, 20 May 2017

Generators and Iterators in ECMAScript 6

This blog post is intended to ease the understanding of iterators and generators in ES6. 


In ES6 the for..of operator allows developers to directly iterate over values unlike the for..in operator in vanilla JavaScript which iterates over index. Some object types in ES6 have built-in iterators by default like the StringArrayTypedArrayMap and Set. But the Object literal ({"key":"value"}) cannot be iterated by the for..of operator because it does not implement the @@iterator method.



Fig 1.0 ES6 Iterable Objects

These objects can be better understood by investigating the Iterable Protocol and the Iterator Protocol.

Iterable Protocol:


The iterable protocol allows ES6 objects to implement their own iteration functionality. In order to have iteration functionality ES6 objects need to implement the @@iterator method.
The @@iterator is actually the key to the actual function. This key should be present on the prototype chain of the object that requires iteration functionality.


Fig 2.0 Overview of for..of with iterable objects


The @@iterator method is accessible via Symbol.iterator key. When an Object is iterated using for..of operator its @@iterator method from the prototype chain returns a function that provides the iterator to access Object's values.

The code below shows an example of built-in iterable which is  the String object.


var someString = 'Hello World';
console.log(typeof someString[Symbol.iterator]); // "function"

for(let val of someString){
  console.log(val);
}

//"H"
//"e"
//"l"
//"l"
//"o" //" " //"W" //"o" //"r" //"l" //"d"

Iterator Protocol:

Using the iterator protocol developers can define a specific way to produce values for any object. It can be done by implementing next() method. This next() method should return an object literal containing 'done' and 'value' properties.

In the code below a custom array iterator is implemented using the next() method. When the fruits array is passed the values can be obtained by calling next().value and when the iteration is done it returns next().done as true.


function fruitsIterator(array) {
    var nextIndex = 0;
    
    return {
       next: function() {
           return nextIndex < array.length ?
               {value: 'Fruit: '+array[nextIndex++], done: false} :
               {done: true};
       }
    };
}

var frIt = fruitsIterator(['Apple', 'Orange', 'Kiwi']);

console.log(frIt.next().value); // 'Fruit: Apple'
console.log(frIt.next().value); // 'Fruit: Orange'
console.log(frIt.next().value); // 'Fruit: Kiwi'
console.log(frIt.next().done);  // true

Generator:

In simple terms the generator object can behave like an iterable and an iterator. It is also able to maintain state of its own. The function* deceleration returns a generator object.




Fig 3.0 Overview of generator

The code below shows different use cases of generators. Notice that 'console.log(range(0, 10, 2));' actually returns the generator object which can be used to access iterable or iteration behavior.


//Use as object
let fibonacci = {
    *[Symbol.iterator]() {
        let pre = 0, cur = 1
        for (;;) {
            [ pre, cur ] = [ cur, pre + cur ]
            yield cur
        }
    }
}

for (let n of fibonacci) {
    if (n > 1000)
        break;
    console.log(n);//1, 2, 3, 5
}

//Use as function
function* range (start, end, step) {
    while (start < end) {
        yield start
        start += step
    }
}

console.log(range(0, 10, 2));
//GeneratorFunctionPrototype {
//  "_invoke": [Function invoke]
//}

console.log(range(0, 10, 2).next());
//Object {
//  "done": false,
//  "value": 0
//}

for (let i of range(0, 10, 2)) {
    console.log(i) // 0, 2, 4, 6, 8
}






Wednesday, 10 May 2017

Memory Management in JavaScript Part-3


Task Scheduler in Blink Rendering Engine:

To ensure responsiveness Chrome is shipped with a task scheduler that enables prioritization of latency sensitive tasks, it tracks if the system is busy and it also has information on other tasks that are to be performed according to their urgency.

Since Chrome manages to sustain 60 FPS for most use cases therefore it has time period of 16.6 ms. Chrome uses this time period to complete frame rendering and input tasks. If Chrome completes the frame rendering and input tasks before 16.6 ms time then it will stay idle until the start of next period. This idle time is the key when learning about 'generational garbage collector' in Chrome. The task scheduler can estimate when there will be idle time in the system which helps V8 engine perform garbage collection. The idle task will have a deadline set by the task scheduler. This deadline is the time scheduler expects system to be idle. 


Fig 1.0 Task Scheduler Timing Diagram

Generational Garbage Collector:




Fig 2.0 Heap Overview

The 'generational garbage collector' in V8 has the JavaScript heap split into 'Young Generation' and 'Old Generation'.

Young Generation:

The young generation has newly allocated objects. Since the objects in young generation are mostly short lived so the garbage collector performs smaller garbage collection tasks in this generation. These smaller garbage collection tasks are called 'scavenges'. The younger generation is additionally split into two semi-spaces. The newer objects are allocated to the 'active semi-space' and when it becomes full the 'scavenge' operation moves the objects to the other semi-space. Fig 3.0 show the young generation split into two semi spaces. Objects that were initially moved from from semi-space 1('active semi-space') to semi-space 2 will be promoted to old generation in the next 'scavenge' operation. 


Fig 3.0 Young Generation Semi-spaces

Old Generation:

When the old generation grows beyond a derived limit the garbage collector performs major garbage collection operation on the old generation while utilizing an optimized 'Mark and Sweep' algorithm. Because marking the heap in old generation can be time consuming the V8 engine can incrementally mark objects in under 5 ms time. Finally using dedicated sweeper threads memory is freed which was initially allocated to objects in the old generation.



Fig 4.0 Overview of Garbage Collection

Saturday, 29 April 2017

Memory Management in JavaScript Part-2

The modern web browsers are shipping with a 'Mark and Sweep' based garbage collector. Although there have been improvements to the 'Mark and Sweep' algorithm like 'generational memory management' for the V8 engine in Chrome but I have only discussed the base algorithm in this post.


The Mark and Sweep Algorithm:


Fig 1.0 Visualizing Mark and Sweep Algorithm 

The 'Mark and Sweep' algorithm consists of two phases. The first phase is responsible for collecting information on 'reachable' objects, this phase is called 'mark' phase. The second phase is responsible for freeing up space for 'un-reachable' objects, this phase is called 'sweep' phase.

Mark Phase:

The 'Mark and Sweep' algorithm periodically traverses through the list of variables in the target JavaScript environment. While traversing it marks values that are referred to by the variables its traversing. If the referenced values are objects themselves(Arrays or Object literals) the algorithm recursively marks  each of the contained values in them as 'reachable'. At the same time it collects all the values that have not been referenced by any other variable. In Fig 1.0 I have visualized a high level overview of the 'mark' phase of the algorithm. For the case when the algorithm traverses through 'object 1' it then recursively traverses through other objects in the list and marks them. This is because the other objects in the list were referred to by 'object 1'.

Sweep Phase:

After the algorithm has completed the 'mark' phase it then starts the 'sweep' phase. It starts by traversing through all variables in target environment again. But now if any value is not marked it de-allocates memory for that value. 

In the base algorithm the 'sweep' phase will occur right after the 'mark' phase. This might affect the speed of the application and can slow it down. But recent improvements like 'generational memory management' to the base algorithm promises to remove this overhead.




Sunday, 16 April 2017

Memory Management in JavaScript Part-1



Fig 1.0 Overview of Memory Life Cycle

Like most languages JavaScript follows a three state memory life cycle which consists of memory allocation, memory usage and releasing allocated memory. But the monitoring and release of allocated memory varies by browser.

Allocation:

The allocation of memory in JavaScript is much more simpler compared to C. JavaScript does not require explicit allocation of memory. The memory is allocated during declaration of variables.

Variables:

let num1 = 5;
let num2 = 7;
let sum = num1 + num3; 

let name = 'John'

Setting the variables 'num1' and  'num2' allocates memory for number type. The 'sum' variable is set to the mathematical sum of two numbers 'num1' and 'num2' which also allocates memory for a number. For the 'name' variable JavaScript allocates memory for a string. 

Arrays:


let number_Arry = [1,434,23,2,234234,343,233,27,45632];

let string_Arry = ['orange', 'banana', 'apple', 'strawberry'];

let combined_Arry = number_Arry.concat(string_Arry);

//combined_Arry : [1,434,23,2,234234,343,233,27,45632,"orange","banana","apple","strawberry"] 

In the case of arrays JavaScript allocates memory for the array itself and for each of its items. For instance JavaScript will allocate memory for the array 'number_Arry' and also allocate memory for each of its items. Same goes with 'combined_Arry', JavaScript will allocate memory for the array and all the items resulting from the concatenation of two arrays. 

Functions:

let randomNumber = function(low, high){
  return Math.floor(Math.random()*high+low);
}

For a function variable JavaScript will allocate memory for a function(callable object) and for each of its arguments. The function in this case is a random number generator which takes in two parameters for low and high range.
 
Object Literals:


let user = {
'firstName': 'John',
'lastName': 'Doe',
'score': 100,
'likes': 50,
'favourite_places': ['San Francisco', 'New York', 'Los Angeles', 'Montreal'],
'getLikes': function(){  return this.likes;}
}

Here the memory is allocated for an object literal and for its properties. So JavaScript allocates memory for two strings 'firstName' and 'lastName'. It also allocates memory for two numbers 'score' and 'likes'. For the 'getLikes' property JavaScript allocates memory for a function. Lastly it allocates memory for an array 'favourite_places' and also for each of its items.

Read/Write:

The read and write part of the process may involve accessing data or updating values. This is where the application logic utilizes the information stored in memory.

Releasing Memory:

Compared to C programming language JavaScript does not require developers to explicitly release memory. This is done automatically by the garbage collector which keeps track of memory allocation and the part of allocated memory that is not in use by the application. 

Current web browsers use Mark and Sweep algorithm for garbage collection. I have discussed these garbage collectors in detail in Part 2 of this post.