const fs = require('fs');
const path = require('path');
const esprima = require('esprima');
const Rx = require('rxjs');

let globalTree = {};
const deps = new Rx.Subject();

const files = deps
    .map(dep => path.resolve('./examples/fn/01/', dep) + '.js');

files.subscribe(file => { 
    console.log('working on', file);
    abc(file);
}, error => { 
    console.error(error);
}, () => { 
    console.log(123);
}); 

function abc(filename) { 
    let analysis = {
        imports: [],
        declaredFn: [],
        invokedFn: [],
        exportedFn: []
    };

    globalTree[filename] = analysis;

    const nodes = Rx.Observable
        .from([filename])
        .flatMap(file => Rx.Observable.bindNodeCallback(fs.readFile)(file, 'utf8'))
        .flatMap(code => Rx.Observable.fromEventPattern(handler => esprima.parse(code, { sourceType: 'module' }, handler)))
        .share();

    const imports = nodes
        .filter(node => node.type === 'ImportDeclaration')
        .map(node => node.source.value);

    const invokedFn = nodes
        .filter(node => node.type === 'CallExpression' && node.callee.type === 'Identifier')
        .map(node => node.callee.name);

    const declaredFn = nodes
        .filter(node => node.type === 'FunctionDeclaration')
        .map(node => node.id.name);

    const exportedFn = nodes
        .filter(node => node.type === 'ExportNamedDeclaration')
        .map(node => node.declaration.id.name);
    
    imports.subscribe(value => { 
        globalTree[filename].imports.push(value);
        deps.next(value);
    });

    declaredFn.subscribe(value => { 
        globalTree[filename].declaredFn.push(value);
    });

    invokedFn.subscribe(value => { 
        globalTree[filename].invokedFn.push(value);
    });

    exportedFn.subscribe(value => { 
        globalTree[filename].exportedFn.push(value);
    });
}

deps.next('index');

setTimeout(function () {
    console.log(globalTree);
}, 1000);

@@ -476,18 +476,18 @@
 mports: 
-%5B%5D
+%7B%7D
 ,%0A      
@@ -496,26 +496,26 @@
 declaredFn: 
-%5B%5D
+%7B%7D
 ,%0A        in
@@ -523,18 +523,18 @@
 okedFn: 
-%5B%5D
+%7B%7D
 ,%0A      
@@ -551,10 +551,10 @@
 Fn: 
-%5B%5D
+%7B%7D
 %0A   
@@ -1451,46 +1451,88 @@
     
-imports.subscribe(value =%3E %7B %0A
+function count(type, key) %7B%0A        globalTree%5Bfilename%5D%5Btype%5D%5Bkey%5D =%0A  
         
 glob
@@ -1519,32 +1519,36 @@
 ey%5D =%0A          
+  !!
 globalTree%5Bfilen
@@ -1555,22 +1555,133 @@
 ame%5D
-.imports.push(
+%5Btype%5D%5Bkey%5D ? globalTree%5Bfilename%5D%5Btype%5D%5Bkey%5D + 1 : 1;%0A    %7D%0A    %0A    imports.subscribe(value =%3E %7B %0A        count('imports', 
 valu
@@ -1764,37 +1764,23 @@
         
-globalTree%5Bfilename%5D.
+count('
 declared
@@ -1777,30 +1777,27 @@
 ('declaredFn
-.push(
+', 
 value);%0A    
@@ -1845,37 +1845,23 @@
         
-globalTree%5Bfilename%5D.
+count('
 invokedF
@@ -1857,30 +1857,27 @@
 t('invokedFn
-.push(
+', 
 value);%0A    
@@ -1930,29 +1930,15 @@
     
-globalTree%5Bfilename%5D.
+count('
 expo
@@ -1947,14 +1947,11 @@
 edFn
-.push(
+', 
 valu

add counter