Sunday, September 11, 2016

Reporting Value Runs in Sequential Data

Summary

liniarGroup accepts an array, and a mapping function. It will output an array of objects describing the index ranges of contiguous sequences, based on the mapping function.

Usage

A Simple Example

window.BN.liniarGroup([0, 0, 1, 2, 2], (v) => v);

results in:

0 - 1,  0
2, 1
3,  2

mapped value: 0, range: "0 - 1", 
mapped value: 1, range: "2"
mapped value: 2, range: "3 - 4"

note: console.table() is useful for displaying this data

A More Complex Example

------------------------

window.BN.liniarGroup(phonebook.entries, (v) => { 
 if (!v.getName()) return "undefined";
 return v.getName()["Last Name"]; 
});

results in:

range: "0 - 50",  mapped value: "Anderson"
range: "51-55", mapped value: "Appleton"
range: "56-57", mapped value: "Avery"
range: "60", mapped value: "Axelrod"

Code

window.BN = window.BN || {};
window.BN.liniarGroup = (arraryIn, fnMap) => {
    let results = [];
    let prevIdx = 0;
    let prevVal = fnMap(arraryIn[0]);
    let lastFoundIndex = undefined;
    for(var i=1; i<arraryIn.length; i++) {
        let iter = arraryIn[i];
        let mappedVal = fnMap(iter);
        if (mappedVal === prevVal) {
            
        }
        else {
            let range = prevIdx === (i-1) ? prevIdx.toString() : prevIdx + " - " + (i-1);
            results.push({"range" : range, "mapped value": prevVal});
            prevVal = mappedVal;
            prevIdx = i;
        }
    }
    let range = prevIdx === (i-1) ? prevIdx.toString() : prevIdx + " - " + (i-1);
    results.push({"range" : range, "mapped value": prevVal});
    return results;
}


Friday, September 2, 2016

Inner Classes in TypesScript

Example of Inner Classes in Typescript

(available since 1.6)

The implementation method is actually "class expressions".

We use them to create a private "inner class" (e.g. myClassExpresion) which is instantiated with the parent class's this and assigned to a public property of the parent class (e.g. innerClassInstance).

Unfortunately, the "inner class" does not have access to private or protected members of the parent.

class Greeter {
    constructor(message: string) {
        this.greeting = message;
    }

    //inner class definition
    private myClassExpresion = class {
        constructor(private parent: Greeter){}
        public say(x: number) {
            return this.parent.greet() + " " + x;
        }
    }

    public greet() {
        return "Hello, " + this.greeting;
    }

    // inner class instance
    public innerClassInstance = new this.myClassExpresion(this);

    private greeting: string;
}

// USAGE
let greeter = new Greeter("I am number");
alert(greeter.innerClassInstance.say(9));

note: the inner class must be defined within the parent class before it is instantiated.

Monday, August 29, 2016

A safer JSON.stringify + Save to file


Safe Stringify


This code follows links once and only once, so, there should be no circular references.

Note that large objects should NOT be output to the console, as this will be super slow.

Assign the safeStringify to a variable and save it to a file using console.save below.

See the sample usage at the end of this article.

var safeStringify = function(obj, replacer, indent) {
    var printedObjects = [];
    var printedObjectKeys = [];
    function is_scalar(obj){return (/string|number|boolean/).test(typeof obj);}
    function printOnceReplacer(key, value) {
        if (value === null || value === undefined || is_scalar(value))
            return value;
        if (printedObjects.length > 10000) {
            return 'object too long';
        }
        // try to find the current object in "printedObjects"
        var printedObjIndex = false;
        printedObjects.forEach(function(obj, index) {
            if (obj === value) {
                printedObjIndex = index;
            }
        });

        // handle root case
        if (key == '') {
            //root element
            printedObjects.push(obj);
            printedObjectKeys.push("root");
            return value;
        } 
        // hadle case previously found reference case
        else if (printedObjIndex + "" != "false" && typeof (value) == "object") {
            if (printedObjectKeys[printedObjIndex] == "root") {
                return "(pointer to root)";
            } else {
                return "(see " + ((!!value && !!value.constructor) ? value.constructor.name.toLowerCase() : typeof (value)) + " with key " + printedObjectKeys[printedObjIndex] + ")";
            }
        } 
        // hanle newly found reference case, and calling the replacer
        else {
            var qualifiedKey = key || "(empty key)";
            printedObjects.push(value);
            printedObjectKeys.push(qualifiedKey);
            if (replacer) {
                return replacer(key, value);
            } else {
                return value;
            }
        }
    }
    return JSON.stringify(obj, printOnceReplacer, indent);
};

ref: modified from http://stackoverflow.com/a/17773553/279393

console.save


(function(console){

    console.save = function(data, filename){

        if(!data) {
            console.error('Console.save: No data')
            return;
        }

        if(!filename) filename = 'console.json'

        if(typeof data === "object"){
            data = JSON.stringify(data, undefined, 4)
        }

        var blob = new Blob([data], {type: 'text/json'}),
            e    = document.createEvent('MouseEvents'),
            a    = document.createElement('a')

        a.download = filename
        a.href = window.URL.createObjectURL(blob)
        a.dataset.downloadurl =  ['text/json', a.download, a.href].join(':')
        e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        a.dispatchEvent(e)
    }
})(console)


ref: http://bgrins.github.io/devtools-snippets/#console-save


Simple Usage

var BNes = safeStringify(myVariableToStringify, undefined, 4);

console.save(BNes);

More Complex Usage

var BNes = safeStringify(myVariableToStringify, (k, v) => {
    let replacements = {"_parent": "[CIRCULAR]", "domElem": "[DOM ELEMENT]"};
    // Replace references to HTML elements with a string
    if (v && v.constructor) {
        let cn = v.constructor.name.toLowerCase();
        if (cn.indexOf("element") === cn.length - 7 && cn.indexOf("html") !== -1)
        return "HTML ELEMENT";
    }
    if (replacements[k] !== undefined)
        return replacements[k];
    else
        return v;
}, 4);

console.save(BNes);

Tuesday, July 26, 2016

Running VSCode with a Local TypeScript Install

Install TypeScript


First, install TypeScript via

npm install -g typescript
or even

npm install -g typescript@beta
from the root of your app (where your tsconfig is located).

Test your install with...

node ./node_modules/typescript/bin/tsc -p ./
and
node ./node_modules/typescript/bin/tsc -v

Configure VSCode

settings

Under file>>preferences>>settings, select user

This will open settings.json.  Add the following entry:

{
    // Specifies the folder path containing the tsserver and lib*.d.ts files to use.
    "typescript.tsdk":"node_modules/typescript/lib"
}

tasks.json

change

"command": "tsc"
to

"command": ".\\node_modules\\.bin\\tsc.cmd"





Sunday, February 21, 2016

Reducing Complexity in Large JavaScript to TypeScript Conversions

One of the primary design goals of TypeScript was to bring some much needed structure to large and unwieldy JavaScript projects.

In aid of this goal, TypeScript provides modules of various flavors, namespaces, classes and enums.

Use of these structures is usually the second step (after resolving type issues by liberal application of the "any" type) in the conversion of a large JavaScript code base into TypeScript.  After which, developers can now start applying their newly minted class types, modules and namespaces to existing code.

Often though, due to the somewhat mechanical nature of the conversion of raw JavaScript functions into classes and modules/namespaces, only the structural aspects of  encapsulation are attended to. The "data hiding" aspect of encapsulation takes some more thought, but is potentially more valuable.

In this post, I will lay out a few steps that can be taken to increase encapsulation in your project and begin to decouple its logic from its state.

Many of these steps will be familiar to you, as they are not TypeScript specific.  Also, you may think that your code just needs to be refactored as a whole, and these steps are piecemeal refactoring at best.  This well may be, but the great advantage of these techniques is that they are concrete, straight forward steps that will decouple much of your code from state and prepare it for further refactoring, if necessary.

I will include some examples in this post, but with some reservations.  By its nature, it is difficult to show how a large and complex application can be simplified using short samples.

Nevertheless, here is an example of how an app might look at the beginning of the process I will describe:


class Person {
    name: string;
    vacationDays: number;
    
    logFriendlyMessage(message: string) {
        this.appendToMessages(this.name + ", " + message);
    }
    logVacationDays() { 
        this.appendToMessages("You have " + this.vacationDays + " days of vacation left");
    };
    appendToMessages(message: string) {
        let newElement = document.createElement("div");
        newElement.innerHTML = message;
        document.getElementById("divMessages").appendChild(newElement);
    }
    
}

document.addEventListener("DOMContentLoaded", (_) => {
    let person:Person = new Person();
    person.name = "Tom";
    person.vacationDays = 10;

    person.logFriendlyMessage("you're a clever programmer");
    person.logVacationDays();
});

In the beginning our class exposes 3 methods, 2 data members and an implicit constructor.

Step 1: make it private if you can; export it only if you must

Walk through all your classes, and use TypeScript's access modifiers (private, protected and public) to hide as much of your classes inner workings from the outside world.  If you must expose a data member, consider doing so via getter and setter functions and exposing only what you must.


class Person {
    constructor(private name: string, private vacationDays: number) {
    }
    
    logFriendlyMessage(message: string) {
        this.appendToMessages(this.name + ", " + message);
    }
    logVacationDays() { 
        this.appendToMessages("You have " + this.vacationDays + " days of vacation left");
    };
    private appendToMessages(message: string) {
        let newElement = document.createElement("div");
        newElement.innerHTML = message;
        document.getElementById("divMessages").appendChild(newElement);
    }   
}

document.addEventListener("DOMContentLoaded", (_) => {
    let person:Person = new Person("Tom", 10);

    person.logFriendlyMessage("you're a clever programmer");
    person.logVacationDays();
});

After this step, our class  exposes only 2 methods and a constructor.

Step 2: make functions static if you can, even at a cost

One of the reasons we prefer encapsulation over a sea of globals, is that when maintaining code, we have some idea of the scope of possible side effects of a function just by seeing in which class or module it resides.

When we change class instance methods into static methods, we further reduce this scope, making it easier to reason about our code.

This is often worth the price of adding another layer of indirection:


class Person {
    constructor(private name: string, private vacationDays: number) {
    }
    
    logFriendlyMessage(message: string) {
        Person.logFriendlyMessage(this.name, message);
    }
    private static logFriendlyMessage(name: string, message: string) {
        Person.appendToMessages(name + ", " + message);
    }
    logVacationDays() { 
        Person.logVacationDays(this.vacationDays);
    };
    private static logVacationDays(vacationDays: number) { 
        Person.appendToMessages("You have " + vacationDays + " days of vacation left");
    };
    private static appendToMessages(message: string) {
        let newElement = document.createElement("div");
        newElement.innerHTML = message;
        document.getElementById("divMessages").appendChild(newElement);
    }
    
}

document.addEventListener("DOMContentLoaded", (_) => {
    let person:Person = new Person("Susan", 42);

    person.logFriendlyMessage("you're a clever programmer");
    person.logVacationDays();
});

After this step, our external exposure is the same, but our methods that do the work are easier to reason about because their parameters are explicit; there are becoming more pure.

Again, since the example is necessarily short, the benefits are not as obvious as I would like.  If you imagine these static methods were each 40 lines long, containing many conditionals and assignments, you can start to see the value.

But, regardless, Person looks more complex, so...

Step 3: move static functions into "library" modules/namespaces

One of the side benefits of decoupling these methods from the object state is that, as our class gets larger, we can simply move them into a new module/namespace.

One note: often it is hard for me to come up with a good name for these libraries, and I feel I shouldn't break out functions into another object unless they have some cohesive theme.  My advice is just go ahead split out your statics and name it something like "MyClassLib".  Later, some natural groupings will emerge and you can reorganize and rename your libraries.


class Person {
    
    constructor(private name: string, private vacationDays: number) {
    }
    
    logFriendlyMessage(message: string) {
        PersonLib.logFriendlyMessage(this.name, message);
    }
    logVacationDays() { 
        PersonLib.logVacationDays(this.vacationDays);
    };
    
}

namespace PersonLib {
    export function logFriendlyMessage(name: string, message: string) {
        UILib.appendToMessages(name + ", " + message);
    }
    export function logVacationDays(vacationDays: number) { 
        UILib.appendToMessages("You have " + vacationDays + " days of vacation left");
    };
}

namespace UILib {
    export function appendToMessages(message: string) {
        let newElement = document.createElement("div");
        newElement.innerHTML = message;
        document.getElementById("divMessages").appendChild(newElement);
    }
}

document.addEventListener("DOMContentLoaded", (_) => {
    let person:Person = new Person("Susan", 42);

    person.logFriendlyMessage("you're a clever programmer");
    person.logVacationDays();
});

After this step, Person is less complex, and is more maintainable.  Person is maintaining state, and PersonLib is handling the logic.  We are starting to see some separation of concerns.

When a library function is called, the developer can tell 2 things at a glance:

1) The inputs are the function parameters, and nothing else.
2) The outputs/side effects are limited to those parameters that are passed by reference and the return value.

Or the developers could make these assumptions, if it was't for globals.  Globals are still wide open.

Decoupling library code from globals will be the subject of my next post.

Ref:

Refactoring Into Pure Functions




Monday, February 15, 2016

Using TypeScript Decorators to Assert State

The Project

My project is an event driven and ajax heavy HTML5 Canvas based web app written in TypeScript.

The Problem

Recently, I started encountering some bugs caused by incorrect execution order.

For example, my app was trying to render to the canvas from "view A" after "view B" was shown.

Due to the heavily async nature of the app, it was not at all obvious why the code was being called in an unexpected order.

Solution Attempt 1: inline state assertions

My initial step was to add state to my primary view.


enum EUIState {
    UNDEFINED = 0,
    CONSTRUCTED = 1,
    INITIALIZED = 2,
    STARTED = 4,
    MOVING_BACK_IN_TIME = 8,
    MOVING_FORWARD_IN_TIME = 16,
    STOPPED = 32
}

class PrimaryView {
    private state: EUIState = EUIState.UNDEFINED;
}  


Then I set state transitions in my code...

e.g.


class PrimaryView {
    private state: EUIState = EUIState.UNDEFINED;
    private animationFrameHandle: number = null;
    constructor() {
        this.state = EUIState.CONSTRUCTED;
    }
    public start(): void {
        this.state = EUIState.STARTED;
        this.animationFrameHandle = window.requestAnimationFrame(() => this.onRender());
    }
    private onRender() {
        //render canvas here
    }
}  



Then, in a few of my methods, I added some assertions...

e.g.


    private onRender() {
        if (this.state !== EUIState.STARTED && this.state !== EUIState.MOVING_BACK_IN_TIME && this.state !== EUIState.MOVING_FORWARD_IN_TIME)
            throw new Error("Invalid stare transition");
        //render canvas here
    }


Ugly.

This was ugly ugly code that would be sprinkled throughout my app, and that I would have to pull out later by hand.

It was time to whip out the TypeScript decorators.

Solution Attempt 2: TypeScript decorators

I had written C# Attributes and used Java Annotations in the past, so I was keen on seeing what I could do with TypeScript.

I found valuable info here, in depth info here and a bare bones spec here.

I won't rehash the contents of those pages in this post, but let my inline comments tell the story.


// This is a decorator: a plain old JavaScript function, taking an arbitrary number of arguments.  
// note: It could take a fixed number of args, even 0 args.  The use of Rest Parameter (...states) here is case specific.
function state(...states: EUIState[]) {

    // This is the pattern you use with method decorators.  In this pattern you return a function that takes
    // some parameters describing the function call instance and returns a TypedPropertyDescriptor
    return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
        // Here we save a reference to the original method that was decorated by @state
        var originalMethod = descriptor.value; 

        // NOTE: Do not use arrow syntax here. Use a function expression in 
        // order to use the correct value of `this` in this method.
        // 
        // We are overriding the original Method to inject our own code and then call the original Method.
        descriptor.value = function (...args: any[]) {
            // This is the bit of code I wanted to inject before the call to the original Method.
            // It checks to make sure the state of the class is one of the valid states for the method.
            if (states.indexOf(this.UIState) === -1) {
                console.error("Unexpected state (" + EUIState[this.UIState] + ") in " + propertyKey);
            }
            //Call the original Method
            var result = originalMethod.apply(this, args);
            return result; // return the result of the original method
        };

        return descriptor;
    };
}



At this point, I added @state decorators to all my methods.

e.g.


    @state(EUIState.STARTED, EUIState.MOVING_BACK_IN_TIME, EUIState.MOVING_FORWARD_IN_TIME)
    private onRender() {
        //render canvas here
    }


As you can see, the syntax in much much cleaner, and I can remove the @state assertion easily either
by a mass search and replace or by the addition of a simple build step.

The Result

These @state annotations allowed me to quickly find where I had made logic errors resulting in execution order bugs.

Lessons learned

Just because I did't have a bunch of explicit state variables hanging around didn't mean my app wasn't stateful (Remember, I added the EUIState enum after the app was already failing, and I never read the PrimaryView.state variable outside of the decorators).

I had written a code base that was implicitly stateful.

So, ask yourself, "Is my code implicitly stateful?". If the answer is yes, then, just as with unit tests, you can gain some peace of mind (and thus fear change less) if you make those state transitions explicit and add debug time assertions to your code via TypeScript decorators.

Afterthoughts

def: assertion decorator
An assertion decorator is a decorator that is used to make run-time assertions and may be removed and have no effect on application execution.

Setting state

Avoid setting state inside your assertion decorators. If possible, they should effectively be pure functions. You may want to remove them at some point in the future, so you want them to have zero effect of your application logic.

If you must set state in a assertion decorator, isolate it from the rest of the application.

e.g. Create a window.decoratorState object where you can store any info you need to persist between calls to you assertion decorator, and do not access this object in your production code.

Automated Cleanup

If you want to remove your assertion decorators for performance reasons, you will want to...
  • Add a "remove assertion decorators" step to you production build process.
  • Implement your assertion decorators in a separate .ts file.
    • Remove this file from your production build
    • In this way, when you compile to production, the assertion decorators just won't be there, and you can be sure that your "remove assertion decorators" step did not miss anything.

Types of Assertions

  • app state
  • method arguments
    • e.g. testing string with a RegEx
  • context
    • e.g. the type of the this object
  • Function.caller (example)
    • Enforcing that a class A methods are only called from methods X or Y



Monday, February 8, 2016

Tracing data member assignments with TypeScript


From time tot time, especially in a large codebase with lots of async operations, I have found myself wishing I could trace every assignment for a variable.

With TypeScript properties (Accessors), it is trivial to do just that.

Imagine that you want to trace "the "data" member:

class MyClass {
    public data: Number;
}


Simply comment out the existing member and replace it with a TypeScript property of the same name and type, and insert your trace code:

class MyClass {
    //public data: Number;
 
    public set data(value: Number) {
        console.log("MyClass::data - " + this._data + " -> " + value);
        console.trace();
        this._data = value;
    }
    public get data(): Number{
        return this._data;
    }
    private _data: Number;
}


This will resolve into some pretty innocuous JavaScript:

var MyClass = (function () {
    function MyClass() {
    }
    Object.defineProperty(MyClass.prototype, "data", {
        get: function () {
            return this._data;
        },
        //public data: Number;
        set: function (value) {
            console.log("MyClass::data - " + this._data + " -> " + value);
            console.trace();
            this._data = value;
        },
        enumerable: true,
        configurable: true
    });
    return MyClass;
})();

And now you will get a nice stack trace as well as from/to values for all your assignments.


browser compatibility notes: 
Object.defineProperty and console.trace are not available in older browsers.  Check the links for compatibility.