Skip to content

Instantly share code, notes, and snippets.

@axefrog
Last active May 6, 2016 04:49
Show Gist options
  • Save axefrog/2965fbec270991203029ca56ad97ab84 to your computer and use it in GitHub Desktop.
Save axefrog/2965fbec270991203029ca56ad97ab84 to your computer and use it in GitHub Desktop.
A very quick-and-dirty proxy interceptor for introspection of an object's behaviour. Assumes chalk is installed.
import chalk from 'chalk';
function str(val) {
return val ? val.toString().replace(/\s+/g, ' ') : val;
}
let i = 0;
export function intercept(obj, title) {
return new Proxy(obj, {
get(target, name) {
const value = target[name];
if(name === 'toString') return value;
if(typeof value !== 'function') return value;
return new Proxy(value, {
get(target, name1) {
if(name1 === 'toString') {
return () => str(target);
}
return target[name1];
},
apply(target, thisArg, args) {
const k = ++i;
console.log(chalk.blue(`EXEC [${k}] => ${title}.${name}(${args.map(str).join(', ')})`));
const value = target.apply(thisArg, args);
console.log(chalk.gray(`EXEC [${k}] <= ${chalk.green(str(value))}`));
return value;
}
});
},
set(target, name, value) {
console.log(chalk.magenta(`SET ${title}.${name} = ${str(value)}`));
target[name] = value;
return true;
}
});
}
import {intercept} from './intercept';
const timer = intercept(new VirtualTimer(), 'timer');
const sink = new Sink();
const testEnv = new TestEnv(timer, sink);
const disposable = new SettableDisposable();
const observer = new Observer(sink.event.bind(sink), sink.end.bind(sink), sink.error.bind(sink), disposable);
const scheduler = intercept(new Scheduler(timer), 'scheduler');
disposable.setDisposable(source.run(observer, scheduler));
// We've intercepted scheduler and timer above. The output below will display everything they do.
## Note that the following will be colored, thanks to chalk, making it easier to scan through.
EXEC [1] => scheduler.asap([object Object])
EXEC [2] => scheduler.schedule(0, -1, [object Object])
EXEC [3] => scheduler.now()
EXEC [4] => timer.now()
EXEC [4] <= 0
EXEC [3] <= 0
EXEC [5] => scheduler._scheduleNextRun(0)
EXEC [6] => scheduler._scheduleNextArrival(0, 0)
SET scheduler._nextArrival = 0
EXEC [7] => timer.setTimer(function () { self._runReadyTasks(self.now()); }, 0)
SET timer._task = function () { self._runReadyTasks(self.now()); }
SET timer._time = 0
EXEC [7] <= [object Object]
SET scheduler._timer = [object Object]
EXEC [6] <= undefined
EXEC [5] <= undefined
EXEC [2] <= [object Object]
EXEC [1] <= [object Object]
NEXT
EXEC [8] => timer.tick(10)
SET timer._targetNow = 10
EXEC [9] => timer._run()
SET timer._active = true
EXEC [10] => timer._step()
SET timer._timer = [object Object]
SET timer._promise = [object Promise]
EXEC [10] <= [object Promise]
SET timer._promise = [object Promise]
EXEC [9] <= [object Promise]
EXEC [8] <= [object Promise]
SET timer._task = undefined
SET timer._now = 0
SET timer._time = Infinity
EXEC [11] => timer._task()
EXEC [12] => scheduler._runReadyTasksBound()
EXEC [13] => timer.now()
EXEC [13] <= 0
EXEC [14] => scheduler.asap([object Object])
EXEC [15] => scheduler.schedule(0, -1, [object Object])
EXEC [16] => scheduler.now()
EXEC [17] => timer.now()
EXEC [17] <= 0
EXEC [16] <= 0
EXEC [18] => scheduler._scheduleNextRun(0)
EXEC [19] => scheduler._scheduleNextArrival(0, 0)
SET scheduler._nextArrival = 0
EXEC [20] => timer.setTimer(function () { self._runReadyTasks(self.now()); }, 0)
SET timer._task = function () { self._runReadyTasks(self.now()); }
SET timer._time = 0
EXEC [21] => timer._run(function () { self._runReadyTasks(self.now()); })
EXEC [21] <= [object Promise]
EXEC [20] <= [object Object]
SET scheduler._timer = [object Object]
EXEC [19] <= undefined
EXEC [18] <= undefined
EXEC [15] <= [object Object]
EXEC [14] <= [object Object]
EXEC [22] => scheduler.asap([object Object])
EXEC [23] => scheduler.schedule(0, -1, [object Object])
EXEC [24] => scheduler.now()
EXEC [25] => timer.now()
EXEC [25] <= 0
EXEC [24] <= 0
EXEC [26] => scheduler._scheduleNextRun(0)
EXEC [26] <= undefined
EXEC [23] <= [object Object]
EXEC [22] <= [object Object]
EXEC [27] => timer.now()
EXEC [27] <= 0
EXEC [12] <= undefined
EXEC [11] <= undefined
EXEC [28] => timer._step()
SET timer._timer = [object Object]
SET timer._promise = [object Promise]
EXEC [28] <= [object Promise]
SET timer._task = undefined
SET timer._now = 0
SET timer._time = Infinity
EXEC [29] => timer._task()
EXEC [30] => scheduler._runReadyTasksBound()
EXEC [31] => timer.now()
EXEC [31] <= 0
EXEC [32] => scheduler.delay(10, [object Object])
EXEC [33] => scheduler.schedule(10, -1, [object Object])
EXEC [34] => scheduler.now()
EXEC [35] => timer.now()
EXEC [35] <= 0
EXEC [34] <= 0
EXEC [36] => scheduler._scheduleNextRun(0)
EXEC [37] => scheduler._scheduleNextArrival(10, 0)
SET scheduler._nextArrival = 10
EXEC [38] => timer.setTimer(function () { self._runReadyTasks(self.now()); }, 10)
SET timer._task = function () { self._runReadyTasks(self.now()); }
SET timer._time = 10
EXEC [39] => timer._run(function () { self._runReadyTasks(self.now()); })
EXEC [39] <= [object Promise]
EXEC [38] <= [object Object]
SET scheduler._timer = [object Object]
EXEC [37] <= undefined
EXEC [36] <= undefined
EXEC [33] <= [object Object]
EXEC [32] <= [object Object]
EXEC [40] => scheduler.delay(10, [object Object])
EXEC [41] => scheduler.schedule(10, -1, [object Object])
EXEC [42] => scheduler.now()
EXEC [43] => timer.now()
EXEC [43] <= 0
EXEC [42] <= 0
EXEC [44] => scheduler._scheduleNextRun(0)
EXEC [44] <= undefined
EXEC [41] <= [object Object]
EXEC [40] <= [object Object]
EXEC [45] => scheduler.delay(5, [object Object])
EXEC [46] => scheduler.schedule(5, -1, [object Object])
EXEC [47] => scheduler.now()
EXEC [48] => timer.now()
EXEC [48] <= 0
EXEC [47] <= 0
EXEC [49] => scheduler._scheduleNextRun(0)
EXEC [50] => scheduler._unschedule()
EXEC [51] => timer.clearTimer([object Object])
EXEC [52] => timer._cancel()
SET timer._timer = null
EXEC [52] <= undefined
SET timer._time = Infinity
SET timer._task = undefined
EXEC [51] <= undefined
SET scheduler._timer = null
EXEC [50] <= undefined
EXEC [53] => scheduler._scheduleNextArrival(5, 0)
SET scheduler._nextArrival = 5
EXEC [54] => timer.setTimer(function () { self._runReadyTasks(self.now()); }, 5)
SET timer._task = function () { self._runReadyTasks(self.now()); }
SET timer._time = 5
EXEC [55] => timer._run(function () { self._runReadyTasks(self.now()); })
EXEC [55] <= [object Promise]
EXEC [54] <= [object Object]
SET scheduler._timer = [object Object]
EXEC [53] <= undefined
EXEC [49] <= undefined
EXEC [46] <= [object Object]
EXEC [45] <= [object Object]
EXEC [56] => scheduler.delay(5, [object Object])
EXEC [57] => scheduler.schedule(5, -1, [object Object])
EXEC [58] => scheduler.now()
EXEC [59] => timer.now()
EXEC [59] <= 0
EXEC [58] <= 0
EXEC [60] => scheduler._scheduleNextRun(0)
EXEC [60] <= undefined
EXEC [57] <= [object Object]
EXEC [56] <= [object Object]
EXEC [61] => timer.now()
EXEC [61] <= 0
EXEC [30] <= undefined
EXEC [29] <= undefined
EXEC [62] => timer._step()
SET timer._timer = [object Object]
SET timer._promise = [object Promise]
EXEC [62] <= [object Promise]
SET timer._task = undefined
SET timer._now = 5
SET timer._time = Infinity
EXEC [63] => timer._task()
EXEC [64] => scheduler._runReadyTasksBound()
EXEC [65] => timer.now()
EXEC [65] <= 5
EVENT! 50
EXEC [66] => scheduler.cancelAll(function (task) { return task.sink === self.sink; })
EXEC [67] => scheduler._reschedule()
EXEC [68] => scheduler.now()
EXEC [69] => timer.now()
EXEC [69] <= 5
EXEC [68] <= 5
EXEC [70] => scheduler._scheduleNextRun(5)
EXEC [71] => scheduler._scheduleNextArrival(10, 5)
SET scheduler._nextArrival = 10
EXEC [72] => timer.setTimer(function () { self._runReadyTasks(self.now()); }, 5)
SET timer._task = function () { self._runReadyTasks(self.now()); }
SET timer._time = 10
EXEC [73] => timer._run(function () { self._runReadyTasks(self.now()); })
EXEC [73] <= [object Promise]
EXEC [72] <= [object Object]
SET scheduler._timer = [object Object]
EXEC [71] <= undefined
EXEC [70] <= undefined
EXEC [67] <= undefined
EXEC [66] <= undefined
EXEC [74] => scheduler.cancel([object Object])
EXEC [74] <= undefined
EXEC [75] => timer.now()
EXEC [75] <= 5
EXEC [64] <= undefined
EXEC [63] <= undefined
EXEC [76] => timer._step()
SET timer._timer = [object Object]
SET timer._promise = [object Promise]
EXEC [76] <= [object Promise]
SET timer._task = undefined
SET timer._now = 10
SET timer._time = Infinity
EXEC [77] => timer._task()
EXEC [78] => scheduler._runReadyTasksBound()
EXEC [79] => timer.now()
EXEC [79] <= 10
EVENT! 100
EXEC [80] => scheduler.cancelAll(function (task) { return task.sink === self.sink; })
EXEC [81] => scheduler._reschedule()
EXEC [82] => scheduler._unschedule()
EXEC [83] => timer.clearTimer()
EXEC [83] <= undefined
SET scheduler._timer = null
EXEC [82] <= undefined
EXEC [81] <= undefined
EXEC [80] <= undefined
EXEC [84] => scheduler.cancel([object Object])
EXEC [84] <= undefined
EXEC [85] => timer.now()
EXEC [85] <= 10
EXEC [78] <= undefined
EXEC [77] <= undefined
EXEC [86] => timer._step()
SET timer._timer = [object Object]
SET timer._promise = [object Promise]
EXEC [86] <= [object Promise]
END!
SET timer._now = 10
SET timer._time = Infinity
SET timer._promise = null
SET timer._promise = null
SET timer._promise = null
SET timer._promise = null
SET timer._promise = null
NEXT
Bucket { t: 10, events: [ 50, 100 ], error: null, end: { x: undefined } }
NEXT
EXEC [87] => timer.tick(1)
SET timer._targetNow = 11
EXEC [88] => timer._run()
SET timer._active = true
EXEC [89] => timer._step()
SET timer._timer = [object Object]
SET timer._promise = [object Promise]
EXEC [89] <= [object Promise]
SET timer._promise = [object Promise]
EXEC [88] <= [object Promise]
EXEC [87] <= [object Promise]
SET timer._task = undefined
SET timer._now = Infinity
SET timer._time = Infinity
EXEC [90] => timer._step()
SET timer._timer = [object Object]
SET timer._promise = [object Promise]
EXEC [90] <= [object Promise]
SET timer._now = 11
SET timer._time = Infinity
SET timer._promise = null
SET timer._promise = null
NEXT
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment