diff --git a/.eslintrc b/.eslintrc
index ac62de16..60aa4172 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -43,7 +43,7 @@
"no-return-assign": 0,
"no-shadow": 0,
"no-underscore-dangle": 0,
- "no-console": [1, { "allow": [ "warn", "error" ] }],
+ "no-console": 2,
"no-unused-vars": ["error", { "argsIgnorePattern": "^_", "vars": "all", "args": "after-used", "ignoreRestSiblings": true }],
"no-use-before-define": 0,
"no-restricted-syntax": 0,
diff --git a/src/api/Ledger.js b/src/api/Ledger.js
index bbf8eaed..c68aa590 100644
--- a/src/api/Ledger.js
+++ b/src/api/Ledger.js
@@ -1,5 +1,6 @@
// @flow
import type { Currency } from '@ledgerhq/live-common/lib/types'
+import logger from 'logger'
const BASE_URL = process.env.LEDGER_REST_API_BASE || 'https://api.ledgerwallet.com/'
@@ -20,13 +21,13 @@ export const userFriendlyError = (p: Promise): Promise =>
throw new Error(message)
}
} catch (e) {
- console.log(e)
+ logger.warn("can't parse server result", e)
}
}
throw new Error(msg)
}
}
- console.log('Ledger API: HTTP status', error.response.status, 'data: ', error.response.data)
+ logger.log('Ledger API: HTTP status', error.response.status, 'data: ', error.response.data)
throw new Error('A problem occurred with Ledger Servers. Please try again later.')
} else if (error.request) {
// The request was made but no response was received
diff --git a/src/api/Ripple.js b/src/api/Ripple.js
index 8b9686fc..52a7fe2f 100644
--- a/src/api/Ripple.js
+++ b/src/api/Ripple.js
@@ -1,4 +1,5 @@
// @flow
+import logger from 'logger'
import { RippleAPI } from 'ripple-lib'
import type { CryptoCurrency } from '@ledgerhq/live-common/lib/types'
import {
@@ -18,7 +19,7 @@ export const apiForCurrency = (currency: CryptoCurrency) => {
server: apiEndpoint[currency.id],
})
api.on('error', (errorCode, errorMessage) => {
- console.warn(`Ripple API error: ${errorCode}: ${errorMessage}`)
+ logger.warn(`Ripple API error: ${errorCode}: ${errorMessage}`)
})
return api
}
@@ -33,7 +34,7 @@ export const parseAPICurrencyObject = ({
value: string,
}) => {
if (currency !== 'XRP') {
- console.warn(`RippleJS: attempt to parse unknown currency ${currency}`)
+ logger.warn(`RippleJS: attempt to parse unknown currency ${currency}`)
return 0
}
return parseAPIValue(value)
diff --git a/src/bridge/BridgeSyncContext.js b/src/bridge/BridgeSyncContext.js
index 16b21d32..8dbe2685 100644
--- a/src/bridge/BridgeSyncContext.js
+++ b/src/bridge/BridgeSyncContext.js
@@ -1,4 +1,5 @@
// @flow
+import logger from 'logger'
import React, { Component } from 'react'
import { connect } from 'react-redux'
import type { Account } from '@ledgerhq/live-common/lib/types'
@@ -150,7 +151,7 @@ class Provider extends Component {
try {
await this.api.syncAll()
} catch (e) {
- console.error('sync issues', e)
+ logger.error('sync issues', e)
}
setTimeout(syncLoop, 10 * 1000)
}
@@ -170,6 +171,9 @@ class Provider extends Component {
}
}
-export const BridgeSyncProvider = connect(mapStateToProps, actions)(Provider)
+export const BridgeSyncProvider = connect(
+ mapStateToProps,
+ actions,
+)(Provider)
export const BridgeSyncConsumer = BridgeSyncContext.Consumer
diff --git a/src/bridge/LibcoreBridge.js b/src/bridge/LibcoreBridge.js
index 960ef946..d056b640 100644
--- a/src/bridge/LibcoreBridge.js
+++ b/src/bridge/LibcoreBridge.js
@@ -1,4 +1,5 @@
// @flow
+import logger from 'logger'
import React from 'react'
import { map } from 'rxjs/operators'
import type { Account } from '@ledgerhq/live-common/lib/types'
@@ -93,7 +94,7 @@ const LibcoreBridge: WalletBridge = {
})()
return {
unsubscribe() {
- console.warn('LibcoreBridge: unsub sync not implemented')
+ logger.warn('LibcoreBridge: unsub sync not implemented')
},
}
},
diff --git a/src/bridge/makeMockBridge.js b/src/bridge/makeMockBridge.js
index eb41396d..8a30ec7a 100644
--- a/src/bridge/makeMockBridge.js
+++ b/src/bridge/makeMockBridge.js
@@ -1,4 +1,5 @@
// @flow
+import logger from 'logger'
import {
genAccount,
genAddingOperationsInAccount,
@@ -45,7 +46,7 @@ function makeMockBridge(opts?: Opts): WalletBridge<*> {
const accountId = initialAccount.id
if (syncTimeouts[accountId]) {
// this is just for tests. we'll assume impl don't need to handle race condition on this function.
- console.warn('synchronize was called multiple pending time for same accounts!!!')
+ logger.warn('synchronize was called multiple pending time for same accounts!!!')
}
syncTimeouts[accountId] = setTimeout(() => {
if (Math.random() < syncSuccessRate) {
diff --git a/src/commands/isCurrencyAppOpened.js b/src/commands/isCurrencyAppOpened.js
index baeae613..325bde88 100644
--- a/src/commands/isCurrencyAppOpened.js
+++ b/src/commands/isCurrencyAppOpened.js
@@ -43,7 +43,6 @@ const cmd: Command = createCommand(
// in case of ETH / XRP, the address derivation is enough
return true
} catch (e) {
- console.log(e)
// if anything failed, it does not pass
return false
}
diff --git a/src/commands/listenDevices.js b/src/commands/listenDevices.js
index 529250fb..afef5057 100644
--- a/src/commands/listenDevices.js
+++ b/src/commands/listenDevices.js
@@ -1,5 +1,6 @@
// @flow
+import logger from 'logger'
import { createCommand } from 'helpers/ipc'
import { Observable } from 'rxjs'
import CommNodeHid from '@ledgerhq/hw-transport-node-hid'
@@ -16,7 +17,7 @@ const cmd = createCommand('listenDevices', () =>
case 'add': {
const pendingRemove = pendingRemovePerPath[e.descriptor]
if (pendingRemove) {
- console.warn(`Skipping remove/add usb event for ${e.descriptor}`)
+ logger.warn(`Skipping remove/add usb event for ${e.descriptor}`)
// there where a recent "remove" event, we don't emit add because we didn't emit "remove" yet.
clearTimeout(pendingRemove)
delete pendingRemovePerPath[e.descriptor]
diff --git a/src/components/DashboardPage/AccountsOrder.js b/src/components/DashboardPage/AccountsOrder.js
index a3c7831a..a28f7063 100644
--- a/src/components/DashboardPage/AccountsOrder.js
+++ b/src/components/DashboardPage/AccountsOrder.js
@@ -1,5 +1,6 @@
// @flow
+import logger from 'logger'
import React, { Component } from 'react'
import styled from 'styled-components'
import { compose } from 'redux'
@@ -63,7 +64,7 @@ function sortAccounts(accounts: Account[], orderAccounts: string, props: Props)
}
return ids
}
- console.warn(`sortAccounts not implemented for ${orderAccounts}`)
+ logger.warn(`sortAccounts not implemented for ${orderAccounts}`)
return null
}
@@ -220,4 +221,10 @@ class AccountsOrder extends Component {
}
}
-export default compose(connect(mapStateToProps, mapDispatchToProps), translate())(AccountsOrder)
+export default compose(
+ connect(
+ mapStateToProps,
+ mapDispatchToProps,
+ ),
+ translate(),
+)(AccountsOrder)
diff --git a/src/components/EnsureDeviceApp/index.js b/src/components/EnsureDeviceApp/index.js
index 36faaafe..4fed6072 100644
--- a/src/components/EnsureDeviceApp/index.js
+++ b/src/components/EnsureDeviceApp/index.js
@@ -1,6 +1,7 @@
// @flow
import { PureComponent } from 'react'
import { connect } from 'react-redux'
+import logger from 'logger'
import type { Account, CryptoCurrency } from '@ledgerhq/live-common/lib/types'
import type { Device } from 'types/common'
@@ -125,7 +126,7 @@ class EnsureDeviceApp extends PureComponent {
.toPromise()
const { freshAddress } = account
if (account && freshAddress !== address) {
- console.warn({ freshAddress, address })
+ logger.warn({ freshAddress, address })
throw new Error('Account address is different than device address')
}
} else if (currency) {
diff --git a/src/components/GenuineCheckModal/index.js b/src/components/GenuineCheckModal/index.js
index b80fe0d9..8ede689b 100644
--- a/src/components/GenuineCheckModal/index.js
+++ b/src/components/GenuineCheckModal/index.js
@@ -1,5 +1,6 @@
// @flow
+import logger from 'logger'
import React, { PureComponent } from 'react'
import { compose } from 'redux'
import { connect } from 'react-redux'
@@ -42,7 +43,7 @@ class GenuineCheck extends PureComponent {
withGenuineCheck
onGenuineCheck={onGenuineCheck}
onStatusChange={status => {
- console.log(`status changed to ${status}`)
+ logger.log(`status changed to ${status}`)
}}
render={({ appStatus, genuineCheckStatus, deviceSelected, errorMessage }) => (
{
}
}
-export default compose(connect(mapStateToProps), translate())(GenuineCheck)
+export default compose(
+ connect(mapStateToProps),
+ translate(),
+)(GenuineCheck)
diff --git a/src/components/ManagerPage/FirmwareUpdate.js b/src/components/ManagerPage/FirmwareUpdate.js
index df2c619a..772dfc4c 100644
--- a/src/components/ManagerPage/FirmwareUpdate.js
+++ b/src/components/ManagerPage/FirmwareUpdate.js
@@ -1,5 +1,6 @@
// @flow
+import logger from 'logger'
import React, { PureComponent } from 'react'
import isEqual from 'lodash/isEqual'
import isEmpty from 'lodash/isEmpty'
@@ -82,7 +83,7 @@ class FirmwareUpdate extends PureComponent {
this.fetchLatestFirmware()
}
} catch (err) {
- console.log(err)
+ logger.log(err)
}
}
diff --git a/src/components/QRCodeCameraPickerCanvas.js b/src/components/QRCodeCameraPickerCanvas.js
index 13c2c27d..271f2c4e 100644
--- a/src/components/QRCodeCameraPickerCanvas.js
+++ b/src/components/QRCodeCameraPickerCanvas.js
@@ -2,6 +2,7 @@
import React, { Component } from 'react'
import QrCode from 'qrcode-reader'
+import logger from 'logger'
export default class QRCodeCameraPickerCanvas extends Component<
{
@@ -88,7 +89,7 @@ export default class QRCodeCameraPickerCanvas extends Component<
try {
video.play()
} catch (e) {
- console.error(e)
+ logger.error(e)
}
let lastCheck = 0
let raf
diff --git a/src/components/SelectExchange.js b/src/components/SelectExchange.js
index 870413ba..e8027e30 100644
--- a/src/components/SelectExchange.js
+++ b/src/components/SelectExchange.js
@@ -2,6 +2,7 @@
import React, { Component } from 'react'
import type { Currency } from '@ledgerhq/live-common/lib/types'
import type { Exchange } from '@ledgerhq/live-common/lib/countervalues/types'
+import logger from 'logger'
import Select from 'components/base/Select'
import Spinner from 'components/base/Spinner'
@@ -67,7 +68,7 @@ class ExchangeSelect extends Component<
this.setState({ exchanges })
}
} catch (error) {
- console.error(error)
+ logger.error(error)
if (!this._unmounted && this._loadId === _loadId) {
this.setState({ error })
}
diff --git a/src/components/base/SideBar/SideBarListItem.js b/src/components/base/SideBar/SideBarListItem.js
index 56d09ddf..85e6e91e 100644
--- a/src/components/base/SideBar/SideBarListItem.js
+++ b/src/components/base/SideBar/SideBarListItem.js
@@ -24,11 +24,17 @@ export type Props = {
class SideBarListItem extends PureComponent {
render() {
const {
- item: { icon: Icon, label, desc, iconActiveColor, hasNotif, onClick },
+ item: { icon: Icon, label, desc, iconActiveColor, hasNotif, onClick, value },
isActive,
} = this.props
return (
-
+
{!!Icon && }
{typeof label === 'function' ? (
diff --git a/src/helpers/countervalues.js b/src/helpers/countervalues.js
index 4859ad79..41e509a9 100644
--- a/src/helpers/countervalues.js
+++ b/src/helpers/countervalues.js
@@ -10,6 +10,7 @@ import {
currencySettingsSelector,
intermediaryCurrency,
} from 'reducers/settings'
+import logger from 'logger'
const pairsSelector = createSelector(
currenciesSelector,
@@ -49,7 +50,7 @@ const addExtraPollingHooks = (schedulePoll, cancelPoll) => {
}
const CounterValues = createCounterValues({
- log: (...args) => console.log('CounterValues:', ...args), // eslint-disable-line no-console
+ log: (...args) => logger.log('CounterValues:', ...args),
getAPIBaseURL: () => 'https://ledger-countervalue-poc.herokuapp.com',
storeSelector: state => state.countervalues,
pairsSelector,
diff --git a/src/helpers/ipc.js b/src/helpers/ipc.js
index 25053ef5..38abb40b 100644
--- a/src/helpers/ipc.js
+++ b/src/helpers/ipc.js
@@ -1,4 +1,5 @@
// @flow
+import logger from 'logger'
import { Observable } from 'rxjs'
import uuidv4 from 'uuid/v4'
@@ -48,20 +49,20 @@ function ipcRendererSendCommand(id: string, data: In): Observable {
if (requestId !== msg.requestId) return
switch (msg.type) {
case 'NEXT':
- console.log(`● CMD ${id}`, msg.data)
+ logger.log(`● CMD ${id}`, msg.data)
if (msg.data) {
o.next(msg.data)
}
break
case 'COMPLETE':
- console.log(`✔ CMD ${id} finished in ${(Date.now() - startTime).toFixed(0)}ms`)
+ logger.log(`✔ CMD ${id} finished in ${(Date.now() - startTime).toFixed(0)}ms`)
o.complete()
ipcRenderer.removeListener('command-event', handleCommandEvent)
break
case 'ERROR':
- console.warn(`✖ CMD ${id} error`, msg.data)
+ logger.warn(`✖ CMD ${id} error`, msg.data)
o.error(msg.data)
ipcRenderer.removeListener('command-event', handleCommandEvent)
break
@@ -74,7 +75,7 @@ function ipcRendererSendCommand(id: string, data: In): Observable {
ipcRenderer.send('command', { id, data, requestId })
- console.log(`CMD ${id}.send(`, data, ')')
+ logger.log(`CMD ${id}.send(`, data, ')')
return unsubscribe
})
diff --git a/src/helpers/libcore.js b/src/helpers/libcore.js
index bdb7ee91..38d3c64a 100644
--- a/src/helpers/libcore.js
+++ b/src/helpers/libcore.js
@@ -1,5 +1,6 @@
// @flow
+import logger from 'logger'
import Btc from '@ledgerhq/hw-app-btc'
import { withDevice } from 'helpers/deviceAccess'
import { getCryptoCurrencyById } from '@ledgerhq/live-common/lib/helpers/currencies'
@@ -216,12 +217,10 @@ async function buildAccountRaw({
}: {
njsAccount: NJSAccount,
isSegwit: boolean,
- // $FlowFixMe
wallet: NJSWallet,
currencyId: string,
accountIndex: number,
core: *,
- // $FlowFixMe
ops: NJSOperation[],
}): Promise {
const njsBalance = await njsAccount.getBalance()
@@ -373,7 +372,7 @@ export async function syncAccount({
syncedRawAccount.balance = njsBalance.toLong()
- console.log(`Synced account [${syncedRawAccount.name}]: ${syncedRawAccount.balance}`)
+ logger.log(`Synced account [${syncedRawAccount.name}]: ${syncedRawAccount.balance}`)
return syncedRawAccount
}
diff --git a/src/helpers/promise.js b/src/helpers/promise.js
index 6cebf415..a80ba5af 100644
--- a/src/helpers/promise.js
+++ b/src/helpers/promise.js
@@ -1,5 +1,5 @@
// @flow
-
+import logger from 'logger'
// small utilities for Promises
export const delay = (ms: number): Promise => new Promise(f => setTimeout(f, ms))
@@ -21,7 +21,7 @@ export function retry(f: () => Promise, options?: $Shape)
}
// In case of failure, wait the interval, retry the action
return result.catch(e => {
- console.warn('Promise#retry', e)
+ logger.warn('Promise#retry', e)
return delay(interval).then(() => rec(remainingTry - 1, interval * intervalMultiplicator))
})
}
diff --git a/src/helpers/withLibcore.js b/src/helpers/withLibcore.js
index babacb3e..37a9c49d 100644
--- a/src/helpers/withLibcore.js
+++ b/src/helpers/withLibcore.js
@@ -1,6 +1,7 @@
// @flow
import invariant from 'invariant'
+import logger from 'logger'
const core = require('@ledgerhq/ledger-core')
@@ -23,7 +24,7 @@ export default function withLibcore(job: Job): Promise {
const p = queue.then(() => job(core, walletPool))
queue = p.catch(e => {
- console.warn(`withLibCore: Error in job`, e)
+ logger.warn(`withLibCore: Error in job`, e)
})
return p
diff --git a/src/internals/index.js b/src/internals/index.js
index 8cfb9226..4c53b555 100644
--- a/src/internals/index.js
+++ b/src/internals/index.js
@@ -1,5 +1,6 @@
// @flow
import commands from 'commands'
+import logger from 'logger'
require('../env')
require('../init-sentry')
@@ -13,7 +14,7 @@ process.on('message', m => {
const { data, requestId, id } = m.command
const cmd = commands.find(cmd => cmd.id === id)
if (!cmd) {
- console.warn(`command ${id} not found`)
+ logger.warn(`command ${id} not found`)
return
}
subscriptions[requestId] = cmd.impl(data).subscribe({
@@ -32,7 +33,7 @@ process.on('message', m => {
})
},
error: error => {
- console.warn('Command error:', error)
+ logger.warn('Command error:', error)
delete subscriptions[requestId]
process.send({
type: 'ERROR',
@@ -55,4 +56,4 @@ process.on('message', m => {
}
})
-console.log('Internal process is up!')
+logger.log('Internal process is up!')
diff --git a/src/logger.js b/src/logger.js
new file mode 100644
index 00000000..1e68f43c
--- /dev/null
+++ b/src/logger.js
@@ -0,0 +1,45 @@
+// @flow
+/* eslint-disable no-console */
+
+/**
+ * IDEA:
+ * logger is an alternative to use for console.log that will be used for many purposes:
+ * - provide useful data for debugging during dev (idea is to have opt-in env var)
+ * - enabled in prod to provide useful data to debug when sending to Sentry
+ * - for analytics in the future
+ */
+
+export default {
+ // tracks the user interactions (click, input focus/blur, what else?)
+
+ onClickElement: (role: string, roleData: ?Object) => {
+ if (!__DEV__ || process.env.DEBUG_CLICK_ELEMENT) {
+ const label = `👆 ${role}`
+ if (roleData) {
+ console.log(label, roleData)
+ } else {
+ console.log(label)
+ }
+ }
+ },
+
+ // tracks Redux actions (NB not all actions are serializable)
+
+ onReduxAction: (action: Object) => {
+ if (!__DEV__ || process.env.DEBUG_ACTION) {
+ console.log(`⚛️ ${action.type}`, action)
+ }
+ },
+
+ // General functions in case the hooks don't apply
+
+ log: (...args: any) => {
+ console.log(...args)
+ },
+ warn: (...args: any) => {
+ console.warn(...args)
+ },
+ error: (...args: any) => {
+ console.error(...args)
+ },
+}
diff --git a/src/main/bridge.js b/src/main/bridge.js
index e74b88c5..54acd85b 100644
--- a/src/main/bridge.js
+++ b/src/main/bridge.js
@@ -6,6 +6,7 @@ import { fork } from 'child_process'
import { ipcMain, app } from 'electron'
import { ipcMainListenReceiveCommands } from 'helpers/ipc'
import path from 'path'
+import logger from 'logger'
import setupAutoUpdater, { quitAndInstall } from './autoUpdate'
@@ -16,7 +17,7 @@ let internalProcess
const killInternalProcess = () => {
if (internalProcess) {
- console.log('killing internal process...')
+ logger.log('killing internal process...')
internalProcess.kill('SIGINT')
internalProcess = null
}
@@ -25,12 +26,12 @@ const killInternalProcess = () => {
const forkBundlePath = path.resolve(__dirname, `${__DEV__ ? '../../' : './'}dist/internals`)
const bootInternalProcess = () => {
- console.log('booting internal process...')
+ logger.log('booting internal process...')
internalProcess = fork(forkBundlePath, {
env: { ...process.env, LEDGER_LIVE_SQLITE_PATH },
})
internalProcess.on('exit', code => {
- console.log(`Internal process ended with code ${code}`)
+ logger.warn(`Internal process ended with code ${code}`)
internalProcess = null
})
}
diff --git a/src/middlewares/logger.js b/src/middlewares/logger.js
new file mode 100644
index 00000000..5cbcc171
--- /dev/null
+++ b/src/middlewares/logger.js
@@ -0,0 +1,8 @@
+// @flow
+
+import logger from 'logger'
+
+export default () => (next: *) => (action: *) => {
+ logger.onReduxAction(action)
+ return next(action)
+}
diff --git a/src/reducers/accounts.js b/src/reducers/accounts.js
index b3a9ac8e..99cdee31 100644
--- a/src/reducers/accounts.js
+++ b/src/reducers/accounts.js
@@ -3,6 +3,7 @@
import { createSelector } from 'reselect'
import { handleActions } from 'redux-actions'
import { createAccountModel } from '@ledgerhq/live-common/lib/models/account'
+import logger from 'logger'
import type { Account, AccountRaw } from '@ledgerhq/live-common/lib/types'
@@ -25,7 +26,7 @@ const handlers: Object = {
{ payload: account }: { payload: Account },
): AccountsState => {
if (state.some(a => a.id === account.id)) {
- console.warn('ADD_ACCOUNT attempt for an account that already exists!', account.id)
+ logger.warn('ADD_ACCOUNT attempt for an account that already exists!', account.id)
return state
}
return [...state, account]
diff --git a/src/renderer/createStore.js b/src/renderer/createStore.js
index bd960576..6e14fa5e 100644
--- a/src/renderer/createStore.js
+++ b/src/renderer/createStore.js
@@ -5,6 +5,7 @@ import { routerMiddleware } from 'react-router-redux'
import thunk from 'redux-thunk'
import createHistory from 'history/createHashHistory'
import type { HashHistory } from 'history'
+import logger from 'middlewares/logger'
import reducers from 'reducers'
@@ -19,7 +20,7 @@ export default ({ state, history, dbMiddleware }: Props) => {
if (!history) {
history = createHistory()
}
- const middlewares = [routerMiddleware(history), thunk]
+ const middlewares = [routerMiddleware(history), thunk, logger]
if (dbMiddleware) {
middlewares.push(dbMiddleware)
}
diff --git a/src/renderer/events.js b/src/renderer/events.js
index d5987f7e..22f68282 100644
--- a/src/renderer/events.js
+++ b/src/renderer/events.js
@@ -9,6 +9,7 @@
// events should all appear in the promise result / observer msgs as soon as they have this requestId
import 'commands'
+import logger from 'logger'
import { ipcRenderer } from 'electron'
import debug from 'debug'
@@ -64,12 +65,12 @@ export default ({ store }: { store: Object, locked: boolean }) => {
}
},
error => {
- console.warn('listenDevices error', error)
+ logger.warn('listenDevices error', error)
store.dispatch(resetDevices())
syncDevices()
},
() => {
- console.warn('listenDevices ended unexpectedly. restarting')
+ logger.warn('listenDevices ended unexpectedly. restarting')
store.dispatch(resetDevices())
syncDevices()
},
diff --git a/src/renderer/init.js b/src/renderer/init.js
index 1702884f..2dc57f6b 100644
--- a/src/renderer/init.js
+++ b/src/renderer/init.js
@@ -1,5 +1,6 @@
// @flow
+import logger from 'logger'
import React from 'react'
import { remote } from 'electron'
import { render } from 'react-dom'
@@ -73,12 +74,24 @@ async function init() {
events({ store, locked })
const libcoreVersion = await libcoreGetVersion.send().toPromise()
- console.log('libcore', libcoreVersion)
+ logger.log('libcore', libcoreVersion)
+
+ // DOM elements can have a data-role that identify the UI entity
+ // and that allow us to track interactions with this.
+ window.addEventListener('click', ({ target }) => {
+ const { dataset } = target
+ if (dataset) {
+ const { role, roledata } = dataset
+ if (role) {
+ logger.onClickElement(role, roledata)
+ }
+ }
+ })
}
}
init().catch(e => {
// for now we make the app crash instead of pending forever. later we can render the error OR try to recover, but probably this is unrecoverable cases.
- console.error(e)
+ logger.error(e)
process.exit(1)
})