UNPKG

armo-breadboard

Version:

Edit a live React component's source in real time.

115 lines (95 loc) 2.36 kB
import { FakeHistory } from 'fake-history' export function create() { // TODO: should be paused by default return new WindowWrapper() } export default class WindowWrapper { constructor(console) { this.seq = 1 this.timeouts = [] this.intervals = [] this.frames = [] this.window = { console: console, alert: window.alert, prompt: window.prompt, confirm: window.confirm, setTimeout: (cb, ms) => { const id = window.setTimeout(cb, ms) this.timeouts.push(id) return id }, setInterval: (cb, ms) => { const id = window.setInterval(cb, ms) this.intervals.push(id) return id }, requestAnimationFrame: (cb) => { const id = window.requestAnimationFrame(cb) this.frames.push(id) return id }, fetch: (...args) => { const seq = this.seq return new Promise((resolve, reject) => window.fetch(...args).then( (...success) => { if (seq === this.seq) { resolve(...success) } }, (...failure) => { if (seq === this.seq) { reject(...failure) } } ) ) }, History: new FakeHistory(), } } eval(source, globals={}) { const exports = {} const module = { exports: exports } const windowKeys = Object.keys(window) const globalKeys = Object.keys(globals) const execute = new Function( 'window', 'module', 'exports', ...globalKeys, ...windowKeys, source ) execute( window, module, exports, ...globalKeys.map(key => globals[key]), ...windowKeys.map(key => this.window[key]) ) const component = exports.default return exports.default } reset() { for (let timeout of this.timeouts) { window.clearTimeout(timeout) } for (let interval of this.intervals) { window.clearInterval(interval) } for (let frame of this.frames) { window.cancelAnimationFrame(frame) } this.timeouts.length = 0 this.intervals.length = 0 this.frames.length = 0 this.window.console.clear() this.seq++ } destroy() { this.reset() this.window.console = null } }