// Console devtools for choo v8, carrying forward the essentials of // choo-devtools 3.x (MIT): a window.choo handle with the live state, an // event log, emit-from-the-console, and render timings via the // PerformanceObserver watching nanotiming's measures. Usage: // // import devtools from '@uhhm/buuh-devtools' // app.use(devtools()) // // The store is a no-op on the server and (by default) stays quiet in the // console; set localStorage.CHOO_DEVTOOLS_VERBOSE = 'true' to log every // event as it happens. const MAX_LOG = 1000 export default function devtools (opts) { opts = opts || {} const max = opts.max || MAX_LOG return function devtoolsStore (state, emitter, app) { if (typeof window === 'undefined') return const log = [] let verbose = false try { verbose = window.localStorage.CHOO_DEVTOOLS_VERBOSE === 'true' } catch (e) {} emitter.on('*', function (name, ...data) { const entry = { name: String(name), data, at: Date.now() } log.push(entry) if (log.length > max) log.shift() if (verbose && name !== state.events.RENDER) { console.debug('choo: %s', entry.name, ...data) } }) const timings = [] if (typeof PerformanceObserver === 'function') { try { const observer = new PerformanceObserver(function (list) { for (const entry of list.getEntries()) { if (!/\[\d+\]$/.test(entry.name)) continue // nanotiming measures only timings.push({ name: entry.name.replace(/ \[\d+\]$/, ''), duration: entry.duration }) if (timings.length > max) timings.shift() } }) observer.observe({ entryTypes: ['measure'] }) } catch (e) {} } window.choo = { state, emit: emitter.emit.bind(emitter), emitter, app, log, timings, // JSON snapshot of state (cache/functions excluded via toJSON) copy () { const json = JSON.stringify(state, null, 2) if (navigator.clipboard) navigator.clipboard.writeText(json) return json }, help () { console.log([ 'window.choo — choo devtools', ' choo.state live app state', ' choo.emit(name, …data) fire an event', ' choo.log last ' + max + ' events', ' choo.timings nanotiming render measures', ' choo.copy() state as JSON (and to clipboard)', " localStorage.CHOO_DEVTOOLS_VERBOSE = 'true' log every event" ].join('\n')) return '☰' } } } }