Fix broken ts build

This commit is contained in:
Jerko Steiner 2019-11-13 20:08:10 -03:00
parent 4fa6a0d17a
commit 3a5b07c218
14 changed files with 149 additions and 112 deletions

View File

@ -1,6 +1,7 @@
/* eslint-disable */
import EventEmitter from 'events' import EventEmitter from 'events'
const Peer = jest.fn().mockImplementation(() => { const Peer = jest.fn().mockImplementation(() => {
let peer = new EventEmitter() const peer = new EventEmitter()
peer.destroy = jest.fn() peer.destroy = jest.fn()
peer.signal = jest.fn() peer.signal = jest.fn()
peer.send = jest.fn() peer.send = jest.fn()

View File

@ -10,12 +10,14 @@ import socket from '../socket'
import storeMock from '../store' import storeMock from '../store'
import { callId, getUserMedia } from '../window' import { callId, getUserMedia } from '../window'
import { MockStore } from 'redux-mock-store' import { MockStore } from 'redux-mock-store'
import { bindActionCreators } from 'redux'
jest.useFakeTimers() jest.useFakeTimers()
describe('reducers/alerts', () => { describe('reducers/alerts', () => {
const store: MockStore = storeMock as any const store: MockStore = storeMock as any
const callActions = bindActionCreators(CallActions, store.dispatch)
beforeEach(() => { beforeEach(() => {
store.clearActions(); store.clearActions();
@ -31,7 +33,7 @@ describe('reducers/alerts', () => {
describe('init', () => { describe('init', () => {
it('calls handshake.init when connected & got camera stream', async () => { it('calls handshake.init when connected & got camera stream', async () => {
const promise = CallActions.init(store.dispatch, store.getState) const promise = callActions.init()
socket.emit('connect') socket.emit('connect')
expect(store.getActions()).toEqual([{ expect(store.getActions()).toEqual([{
type: constants.INIT_PENDING, type: constants.INIT_PENDING,
@ -60,8 +62,7 @@ describe('reducers/alerts', () => {
}) })
it('calls dispatches disconnect message on disconnect', async () => { it('calls dispatches disconnect message on disconnect', async () => {
const promise = callActions.init()
const promise = CallActions.init(store.dispatch, store.getState)
socket.emit('connect') socket.emit('connect')
socket.emit('disconnect') socket.emit('disconnect')
expect(store.getActions()).toEqual([{ expect(store.getActions()).toEqual([{
@ -102,7 +103,7 @@ describe('reducers/alerts', () => {
it('dispatches alert when failed to get media stream', async () => { it('dispatches alert when failed to get media stream', async () => {
(getUserMedia as any).fail(true) (getUserMedia as any).fail(true)
const promise = CallActions.init(store.dispatch, store.getState) const promise = callActions.init()
socket.emit('connect') socket.emit('connect')
await promise await promise
}) })

View File

@ -4,8 +4,7 @@ import * as StreamActions from './StreamActions'
import * as constants from '../constants' import * as constants from '../constants'
import socket from '../socket' import socket from '../socket'
import { callId, getUserMedia } from '../window' import { callId, getUserMedia } from '../window'
import { Dispatch } from 'redux' import { Dispatch, GetState } from '../store'
import { GetState } from '../store'
export interface InitAction { export interface InitAction {
type: 'INIT' type: 'INIT'
@ -20,7 +19,7 @@ const initialize = (): InitializeAction => ({
type: 'INIT', type: 'INIT',
}) })
export const init = async (dispatch: Dispatch, getState: GetState) => { export const init = () => async (dispatch: Dispatch, getState: GetState) => {
dispatch(initialize()) dispatch(initialize())
const socket = await connect(dispatch) const socket = await connect(dispatch)
@ -39,10 +38,10 @@ export async function connect (dispatch: Dispatch) {
resolve(socket) resolve(socket)
}) })
socket.on('connect', () => { socket.on('connect', () => {
NotifyActions.warning('Connected to server socket')(dispatch) dispatch(NotifyActions.warning('Connected to server socket'))
}) })
socket.on('disconnect', () => { socket.on('disconnect', () => {
NotifyActions.error('Server socket disconnected')(dispatch) dispatch(NotifyActions.error('Server socket disconnected'))
}) })
}) })
} }

View File

@ -1,7 +1,7 @@
import * as constants from '../constants' import * as constants from '../constants'
import * as ChatActions from './ChatActions'
import { Dispatch } from 'redux' import { Dispatch } from 'redux'
import _ from 'underscore' import _ from 'underscore'
import { ThunkResult } from '../store'
const TIMEOUT = 5000 const TIMEOUT = 5000
@ -13,21 +13,29 @@ function format (string: string, args: string[]) {
export type NotifyType = 'info' | 'warning' | 'error' export type NotifyType = 'info' | 'warning' | 'error'
const _notify = (type: NotifyType, args: string[]) => (dispatch: Dispatch) => { function notify(dispatch: Dispatch, type: NotifyType, args: string[]) {
const string = args[0] || '' const string = args[0] || ''
const message = format(string, Array.prototype.slice.call(args, 1)) const message = format(string, Array.prototype.slice.call(args, 1))
const id = _.uniqueId('notification') const id = _.uniqueId('notification')
const payload: Notification = { id, type, message } const payload: Notification = { id, type, message }
dispatch(addNotification(payload))
dispatch(ChatActions.addMessage({
userId: '[PeerCalls]',
message,
timestamp: new Date().toLocaleString(),
image: undefined,
}))
setTimeout(() => { setTimeout(() => {
dispatch(dismissNotification(id)) dispatch(dismissNotification(id))
}, TIMEOUT) }, TIMEOUT)
return addNotification(payload)
}
export const info = (...args: any[]): ThunkResult<NotificationAddAction> => {
return dispatch => notify(dispatch, 'info', args)
}
export const warning = (...args: any[]): ThunkResult<NotificationAddAction> => {
return dispatch => notify(dispatch, 'warning', args)
}
export const error = (...args: any[]): ThunkResult<NotificationAddAction> => {
return dispatch => notify(dispatch, 'error', args)
} }
function addNotification(payload: Notification): NotificationAddAction { function addNotification(payload: Notification): NotificationAddAction {
@ -60,18 +68,6 @@ export interface NotificationDismissAction {
payload: { id: string } payload: { id: string }
} }
export function info (...args: any[]) {
return (dispatch: Dispatch) => _notify('info', args)(dispatch)
}
export function warning (...args: any[]) {
return (dispatch: Dispatch) => _notify('warning', args)(dispatch)
}
export function error (...args: any[]) {
return (dispatch: Dispatch) => _notify('error', args)(dispatch)
}
export interface NotificationClearAction { export interface NotificationClearAction {
type: 'NOTIFY_CLEAR' type: 'NOTIFY_CLEAR'
} }

View File

@ -167,9 +167,9 @@ describe('PeerActions', () => {
PeerActions.sendMessage({ payload: 'test', type: 'text' })( PeerActions.sendMessage({ payload: 'test', type: 'text' })(
dispatch, getState) dispatch, getState)
const { peers } = store.getState() const { peers } = store.getState()
expect(peers['user2'].send.mock.calls) expect((peers['user2'].send as jest.Mock).mock.calls)
.toEqual([[ '{"payload":"test","type":"text"}' ]]) .toEqual([[ '{"payload":"test","type":"text"}' ]])
expect(peers['user3'].send.mock.calls) expect((peers['user3'].send as jest.Mock).mock.calls)
.toEqual([[ '{"payload":"test","type":"text"}' ]]) .toEqual([[ '{"payload":"test","type":"text"}' ]])
}) })

View File

@ -6,7 +6,7 @@ import Peer from 'simple-peer'
import _ from 'underscore' import _ from 'underscore'
import _debug from 'debug' import _debug from 'debug'
import { play, iceServers } from '../window' import { play, iceServers } from '../window'
import { Dispatch } from 'redux' import { Dispatch, GetState } from '../store'
const debug = _debug('peercalls') const debug = _debug('peercalls')
@ -14,8 +14,6 @@ export interface Peers {
[id: string]: Peer.Instance [id: string]: Peer.Instance
} }
export type GetState = () => { peers: Peers }
export interface PeerHandlerOptions { export interface PeerHandlerOptions {
socket: SocketIOClient.Socket socket: SocketIOClient.Socket
user: { id: string } user: { id: string }
@ -38,7 +36,7 @@ class PeerHandler {
handleError = (err: Error) => { handleError = (err: Error) => {
const { dispatch, getState, user } = this const { dispatch, getState, user } = this
debug('peer: %s, error %s', user.id, err.stack) debug('peer: %s, error %s', user.id, err.stack)
NotifyActions.error('A peer connection error occurred')(dispatch) dispatch(NotifyActions.error('A peer connection error occurred'))
const peer = getState().peers[user.id] const peer = getState().peers[user.id]
peer && peer.destroy() peer && peer.destroy()
dispatch(removePeer(user.id)) dispatch(removePeer(user.id))
@ -53,7 +51,7 @@ class PeerHandler {
handleConnect = () => { handleConnect = () => {
const { dispatch, user } = this const { dispatch, user } = this
debug('peer: %s, connect', user.id) debug('peer: %s, connect', user.id)
NotifyActions.warning('Peer connection established')(dispatch) dispatch(NotifyActions.warning('Peer connection established'))
play() play()
} }
handleStream = (stream: MediaStream) => { handleStream = (stream: MediaStream) => {
@ -64,10 +62,10 @@ class PeerHandler {
stream, stream,
})) }))
} }
handleData = (object: any) => { handleData = (buffer: ArrayBuffer) => {
const { dispatch, user } = this const { dispatch, user } = this
const message = JSON.parse(new window.TextDecoder('utf-8').decode(object)) const message = JSON.parse(new window.TextDecoder('utf-8').decode(buffer))
debug('peer: %s, message: %o', user.id, object) debug('peer: %s, message: %o', user.id, buffer)
switch (message.type) { switch (message.type) {
case 'file': case 'file':
dispatch(ChatActions.addMessage({ dispatch(ChatActions.addMessage({
@ -89,7 +87,7 @@ class PeerHandler {
handleClose = () => { handleClose = () => {
const { dispatch, user } = this const { dispatch, user } = this
debug('peer: %s, close', user.id) debug('peer: %s, close', user.id)
NotifyActions.error('Peer connection closed')(dispatch) dispatch(NotifyActions.error('Peer connection closed'))
dispatch(StreamActions.removeStream(user.id)) dispatch(StreamActions.removeStream(user.id))
dispatch(removePeer(user.id)) dispatch(removePeer(user.id))
} }
@ -116,11 +114,11 @@ export function createPeer (options: CreatePeerOptions) {
return (dispatch: Dispatch, getState: GetState) => { return (dispatch: Dispatch, getState: GetState) => {
const userId = user.id const userId = user.id
debug('create peer: %s, stream:', userId, stream) debug('create peer: %s, stream:', userId, stream)
NotifyActions.warning('Connecting to peer...')(dispatch) dispatch(NotifyActions.warning('Connecting to peer...'))
const oldPeer = getState().peers[userId] const oldPeer = getState().peers[userId]
if (oldPeer) { if (oldPeer) {
NotifyActions.info('Cleaning up old connection...')(dispatch) dispatch(NotifyActions.info('Cleaning up old connection...'))
oldPeer.destroy() oldPeer.destroy()
dispatch(removePeer(userId)) dispatch(removePeer(userId))
} }
@ -244,7 +242,7 @@ export const sendFile = (file: File) =>
async (dispatch: Dispatch, getState: GetState) => { async (dispatch: Dispatch, getState: GetState) => {
const { name, size, type } = file const { name, size, type } = file
if (!window.FileReader) { if (!window.FileReader) {
NotifyActions.error('File API is not supported by your browser')(dispatch) dispatch(NotifyActions.error('File API is not supported by your browser'))
return return
} }
const reader = new window.FileReader() const reader = new window.FileReader()

View File

@ -3,8 +3,8 @@ import * as PeerActions from '../actions/PeerActions'
import * as constants from '../constants' import * as constants from '../constants'
import _ from 'underscore' import _ from 'underscore'
import _debug from 'debug' import _debug from 'debug'
import { Dispatch } from 'redux'
import { SignalData } from 'simple-peer' import { SignalData } from 'simple-peer'
import { Dispatch, GetState } from '../store'
const debug = _debug('peercalls') const debug = _debug('peercalls')
@ -13,7 +13,7 @@ export interface SocketHandlerOptions {
roomName: string roomName: string
stream?: MediaStream stream?: MediaStream
dispatch: Dispatch dispatch: Dispatch
getState: PeerActions.GetState getState: GetState
} }
export interface SignalOptions { export interface SignalOptions {
@ -31,7 +31,7 @@ class SocketHandler {
roomName: string roomName: string
stream?: MediaStream stream?: MediaStream
dispatch: Dispatch dispatch: Dispatch
getState: PeerActions.GetState getState: GetState
constructor (options: SocketHandlerOptions) { constructor (options: SocketHandlerOptions) {
this.socket = options.socket this.socket = options.socket
@ -50,8 +50,8 @@ class SocketHandler {
handleUsers = ({ initiator, users }: UsersOptions) => { handleUsers = ({ initiator, users }: UsersOptions) => {
const { socket, stream, dispatch, getState } = this const { socket, stream, dispatch, getState } = this
debug('socket users: %o', users) debug('socket users: %o', users)
NotifyActions.info('Connected users: {0}', users.length)(dispatch) this.dispatch(NotifyActions.info('Connected users: {0}', users.length))
const { peers } = getState() const { peers } = this.getState()
users users
.filter(user => !peers[user.id] && user.id !== socket.id) .filter(user => !peers[user.id] && user.id !== socket.id)
@ -78,7 +78,7 @@ export interface HandshakeOptions {
export function handshake (options: HandshakeOptions) { export function handshake (options: HandshakeOptions) {
const { socket, roomName, stream } = options const { socket, roomName, stream } = options
return (dispatch: Dispatch, getState: PeerActions.GetState) => { return (dispatch: Dispatch, getState: GetState) => {
const handler = new SocketHandler({ const handler = new SocketHandler({
socket, socket,
roomName, roomName,
@ -92,7 +92,7 @@ export function handshake (options: HandshakeOptions) {
debug('socket.id: %s', socket.id) debug('socket.id: %s', socket.id)
debug('emit ready for room: %s', roomName) debug('emit ready for room: %s', roomName)
NotifyActions.info('Ready for connections')(dispatch) dispatch(NotifyActions.info('Ready for connections'))
socket.emit('ready', roomName) socket.emit('ready', roomName)
} }
} }

View File

@ -0,0 +1,3 @@
export * from './action'
export * from './middleware'
export * from './reducer'

View File

@ -2,98 +2,114 @@ jest.mock('../actions/CallActions')
jest.mock('../socket') jest.mock('../socket')
jest.mock('../window') jest.mock('../window')
import * as constants from '../constants'
import App from './App'
import React from 'react' import React from 'react'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import TestUtils from 'react-dom/test-utils' import TestUtils from 'react-dom/test-utils'
import configureStore from 'redux-mock-store'
import reducers from '../reducers'
import { MediaStream } from '../window'
import { Provider } from 'react-redux' import { Provider } from 'react-redux'
import { AnyAction, applyMiddleware, createStore } from 'redux'
import { init } from '../actions/CallActions' import { init } from '../actions/CallActions'
import { middlewares } from '../store' import { Alert } from '../actions/NotifyActions'
import * as constants from '../constants'
import reducers from '../reducers'
import { middlewares, State, Store } from '../store'
import { MediaStream } from '../window'
import App from './App'
describe('App', () => { describe('App', () => {
const initAction = { type: 'INIT' } const initAction = { type: 'INIT' }
let state let store: Store
let state: Partial<State>
let dispatchSpy: jest.SpyInstance<AnyAction, AnyAction[]>
beforeEach(() => { beforeEach(() => {
init.mockReturnValue(initAction) state = {};
state = reducers() (init as jest.Mock).mockReturnValue(initAction)
dispatchSpy = jest.spyOn(store, 'dispatch')
window.HTMLMediaElement.prototype.play = jest.fn() window.HTMLMediaElement.prototype.play = jest.fn()
}) })
let component, node, store afterEach(() => {
function render () { dispatchSpy.mockReset()
store = configureStore(middlewares)(state) dispatchSpy.mockRestore()
component = TestUtils.renderIntoDocument( })
<Provider store={store}>
<App /> let node: Element
</Provider> async function render () {
store = createStore(
reducers,
state,
applyMiddleware(...middlewares),
) )
node = ReactDOM.findDOMNode(component) const div = document.createElement('div')
await new Promise<HTMLDivElement>(resolve => {
ReactDOM.render(
<Provider store={store}>
<div ref={app => resolve(app!)}>
<App />
</div>
</Provider>,
div,
)
})
} }
describe('render', () => { describe('render', () => {
it('renders without issues', () => { it('renders without issues', () => {
render() render()
expect(node).toBeTruthy() expect(node).toBeTruthy()
expect(init.mock.calls.length).toBe(1) expect((init as jest.Mock).mock.calls.length).toBe(1)
}) })
}) })
describe('state', () => { describe('state', () => {
let alert let alert: Alert
beforeEach(() => { beforeEach(() => {
state.streams = { state.streams = {
test: { test: {
mediaStream: new MediaStream(), mediaStream: new MediaStream(),
url: 'blob://' url: 'blob://',
} },
} }
state.peers = { state.peers = {
test: {} test: {} as any,
} }
state.notifications = state.notifications.merge({ state.notifications = {
'notification1': { 'notification1': {
id: 'notification1', id: 'notification1',
message: 'test', message: 'test',
type: 'warning' type: 'warning',
},
} }
}) state.alerts = [{
const alerts = state.alerts.asMutable()
alert = {
dismissable: true, dismissable: true,
action: 'Dismiss', action: 'Dismiss',
message: 'test alert' message: 'test alert',
} type: 'info',
alerts.push(alert) }]
state.alerts = alerts
render() render()
store.clearActions()
}) })
describe('alerts', () => { describe('alerts', () => {
it('can be dismissed', () => { it('can be dismissed', () => {
const dismiss = node.querySelector('.action-alert-dismiss') const dismiss = node.querySelector('.action-alert-dismiss')!
TestUtils.Simulate.click(dismiss) TestUtils.Simulate.click(dismiss)
expect(store.getActions()).toEqual([{ expect(dispatchSpy.mock.calls).toEqual([[{
type: constants.ALERT_DISMISS, type: constants.ALERT_DISMISS,
payload: alert payload: alert,
}]) }]])
}) })
}) })
describe('video', () => { describe('video', () => {
it('can be activated', () => { it('can be activated', () => {
const video = node.querySelector('video') const video = node.querySelector('video')!
TestUtils.Simulate.click(video) TestUtils.Simulate.click(video)
expect(store.getActions()).toEqual([{ expect(dispatchSpy.mock.calls).toEqual([[{
type: constants.ACTIVE_TOGGLE, type: constants.ACTIVE_TOGGLE,
payload: { userId: constants.ME } payload: { userId: constants.ME },
}]) }]])
}) })
}) })

View File

@ -1,6 +1,6 @@
import * as NotifyActions from '../actions/NotifyActions' import * as NotifyActions from '../actions/NotifyActions'
import _ from 'underscore' import _ from 'underscore'
import { applyMiddleware, createStore, Store } from 'redux' import { applyMiddleware, createStore, Store, bindActionCreators } from 'redux'
import { create } from '../middlewares' import { create } from '../middlewares'
import reducers from './index' import reducers from './index'
@ -9,21 +9,24 @@ jest.useFakeTimers()
describe('reducers/alerts', () => { describe('reducers/alerts', () => {
let store: Store let store: Store
let notifyActions: typeof NotifyActions
beforeEach(() => { beforeEach(() => {
store = createStore( store = createStore(
reducers, reducers,
applyMiddleware(...create()), applyMiddleware(...create()),
) )
notifyActions = bindActionCreators(NotifyActions, store.dispatch)
}) })
describe('clearAlert', () => { describe('clearAlert', () => {
[true, false].forEach(dismissable => { [true, false].forEach(dismissable => {
beforeEach(() => { beforeEach(() => {
store.dispatch(NotifyActions.clearAlerts()) notifyActions.clearAlerts()
}) })
it('adds alert to store', () => { it('adds alert to store', () => {
store.dispatch(NotifyActions.alert('test', dismissable)) notifyActions.alert('test', dismissable)
expect(store.getState().alerts).toEqual([{ expect(store.getState().alerts).toEqual([{
action: dismissable ? 'Dismiss' : undefined, action: dismissable ? 'Dismiss' : undefined,
dismissable, dismissable,
@ -69,7 +72,7 @@ describe('reducers/alerts', () => {
describe(type, () => { describe(type, () => {
beforeEach(() => { beforeEach(() => {
NotifyActions[type]('Hi {0}!', 'John')(store.dispatch) notifyActions[type]('Hi {0}!', 'John')
}) })
it('adds a notification', () => { it('adds a notification', () => {
@ -86,7 +89,7 @@ describe('reducers/alerts', () => {
}) })
it('does not fail when no arguments', () => { it('does not fail when no arguments', () => {
NotifyActions[type]()(store.dispatch) notifyActions[type]()
}) })
}) })
@ -96,9 +99,9 @@ describe('reducers/alerts', () => {
describe('clear', () => { describe('clear', () => {
it('clears all alerts', () => { it('clears all alerts', () => {
NotifyActions.info('Hi {0}!', 'John')(store.dispatch) notifyActions.info('Hi {0}!', 'John')
NotifyActions.warning('Hi {0}!', 'John')(store.dispatch) notifyActions.warning('Hi {0}!', 'John')
NotifyActions.error('Hi {0}!', 'John')(store.dispatch) notifyActions.error('Hi {0}!', 'John')
store.dispatch(NotifyActions.clear()) store.dispatch(NotifyActions.clear())
expect(store.getState().notifications).toEqual({}) expect(store.getState().notifications).toEqual({})
}) })

View File

@ -1,14 +1,28 @@
import * as constants from '../constants' import * as constants from '../constants'
import { Message, MessageAddAction } from '../actions/ChatActions' import { Message, MessageAddAction } from '../actions/ChatActions'
import { NotificationAddAction } from '../actions/NotifyActions'
export type MessagesState = Message[] export type MessagesState = Message[]
const defaultState: MessagesState = [] const defaultState: MessagesState = []
function convertNotificationToMessage(action: NotificationAddAction): Message {
return {
userId: '[PeerCalls]',
message: action.payload.message,
timestamp: new Date().toLocaleString(),
}
}
export default function messages ( export default function messages (
state = defaultState, action: MessageAddAction, state = defaultState, action: MessageAddAction | NotificationAddAction,
) { ): MessagesState {
switch (action && action.type) { switch (action.type) {
case constants.NOTIFY:
return [
...state,
convertNotificationToMessage(action),
]
case constants.MESSAGE_ADD: case constants.MESSAGE_ADD:
return [...state, action.payload] return [...state, action.payload]
default: default:

View File

@ -3,13 +3,14 @@ import _ from 'underscore'
import Peer from 'simple-peer' import Peer from 'simple-peer'
import { PeerAction } from '../actions/PeerActions' import { PeerAction } from '../actions/PeerActions'
export interface PeersState { export type PeersState = Record<string, Peer.Instance>
[userId: string]: Peer.Instance
}
const defaultState: PeersState = {} const defaultState: PeersState = {}
export default function peers (state = defaultState, action: PeerAction) { export default function peers(
state = defaultState,
action: PeerAction,
): PeersState {
switch (action.type) { switch (action.type) {
case constants.PEER_ADD: case constants.PEER_ADD:
return { return {

View File

@ -1,13 +1,16 @@
import { Action, applyMiddleware, createStore as _createStore, Store as ReduxStore } from 'redux'
import { ThunkAction, ThunkDispatch } from 'redux-thunk'
import { create } from './middlewares' import { create } from './middlewares'
import { middleware as asyncMiddleware }from './async'
import reducers from './reducers' import reducers from './reducers'
import { applyMiddleware, createStore as _createStore, Store as ReduxStore } from 'redux'
export const middlewares = create( export const middlewares = create(
window.localStorage && window.localStorage.log, window.localStorage && window.localStorage.log,
) )
export const createStore = () => _createStore( export const createStore = () => _createStore(
reducers, reducers,
applyMiddleware(...middlewares), applyMiddleware(...middlewares, asyncMiddleware),
) )
export default createStore() export default createStore()
@ -17,3 +20,6 @@ export type Store = ReturnType<typeof createStore>
type TGetState<T> = T extends ReduxStore<infer State> ? State : never type TGetState<T> = T extends ReduxStore<infer State> ? State : never
export type State = TGetState<Store> export type State = TGetState<Store>
export type GetState = () => State export type GetState = () => State
export type Dispatch = ThunkDispatch<State, undefined, Action>
export type ThunkResult<R> = ThunkAction<R, State, undefined, Action>

View File

@ -1,5 +1,4 @@
#!/usr/bin/env node #!/usr/bin/env node
'use strict'
if (!process.env.DEBUG) { if (!process.env.DEBUG) {
process.env.DEBUG = 'peercalls' process.env.DEBUG = 'peercalls'
} }