Skip to content

Commit

Permalink
Merge pull request #368 from goatslacker/debug-component
Browse files Browse the repository at this point in the history
A debug component
  • Loading branch information
goatslacker committed Jun 30, 2015
2 parents b57d4fb + efe1251 commit ad9c2bb
Show file tree
Hide file tree
Showing 15 changed files with 699 additions and 4 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"browser": true,
"es6": true
},
"parser": "babel-eslint",
"ecmaFeatures": {
"modules": true,
"jsx": true
Expand All @@ -25,7 +26,7 @@
}],
"no-use-before-define": 2,
// possible errors
"comma-dangle": [2, "never"],
"comma-dangle": [0, "always"],
"no-cond-assign": [2, "always"],
"no-debugger": 1,
"no-alert": 1,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"babel": "^5.6.6",
"babel-core": "^5.6.6",
"babel-loader": "^5.1.4",
"babel-eslint": "3.1.18",
"chai": "^2.3.0",
"coveralls": "^2.11.2",
"envify": "^3.4.0",
Expand Down
10 changes: 9 additions & 1 deletion src/alt/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,15 @@ class Alt {
}

dispatch(action, data, details) {
this.batchingFunction(() => this.dispatcher.dispatch({ action, data, details }))
this.batchingFunction(() => {
const id = Math.random().toString(18).substr(2, 16)
return this.dispatcher.dispatch({
id,
action,
data,
details
})
})
}

createUnsavedStore(StoreModel, ...args) {
Expand Down
30 changes: 30 additions & 0 deletions src/utils/Debugger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*eslint-disable */
import DebugActions from './debug/DebugActions'
import DispatcherDebugger from './DispatcherDebugger'
import React from 'react'
import StoreExplorer from './StoreExplorer'

class Debugger extends React.Component {
componentDidMount() {
DebugActions.setAlt(this.props.alt)
}

renderInspectorWindow() {
return this.props.inspector
? <this.props.inspector />
: null
}

render() {
return (
<div>
<h1>Debug</h1>
<DispatcherDebugger alt={this.props.alt} />
<StoreExplorer alt={this.props.alt} />
{this.renderInspectorWindow()}
</div>
)
}
}

export default Debugger
196 changes: 196 additions & 0 deletions src/utils/DispatcherDebugger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/*eslint-disable */
import React from 'react'
import { Column, Table } from 'fixed-data-table'
import makeFinalStore from './makeFinalStore'
import connectToStores from './connectToStores'

import FixedDataTableCss from './debug/FixedDataTableCss'

import DebugActions from './debug/DebugActions'
import DispatcherStore from './debug/DispatcherStore'

class DispatcherDebugger extends React.Component {
constructor() {
super()

this.getDispatch = this.getDispatch.bind(this)
this.renderName = this.renderName.bind(this)
this.renderReplay = this.renderReplay.bind(this)
this.renderRevert = this.renderRevert.bind(this)
this.view = this.view.bind(this)
}

componentDidMount() {
const finalStore = makeFinalStore(this.props.alt)
finalStore.listen(state => DebugActions.addDispatch(state.payload))
DebugActions.setAlt(this.props.alt)
}

clear() {
DebugActions.clear()
}

getDispatch(idx) {
const dispatch = this.props.dispatches[idx]
return {
id: dispatch.id,
action: dispatch.action,
data: dispatch.data,
details: dispatch.details,
recorded: dispatch.recorded,
dispatchedStores: dispatch.dispatchedStores,
mtime: this.props.mtime,
}
}

loadRecording() {
const json = prompt('Give me a serialized recording')
if (json) DebugActions.loadRecording(json)
}

revert(ev) {
const data = ev.target.dataset
DebugActions.revert(data.dispatchId)
}

saveRecording() {
DebugActions.saveRecording()
}

startReplay() {
DebugActions.startReplay()
DebugActions.replay()
}

stopReplay() {
DebugActions.stopReplay()
}

toggleLogDispatches() {
DebugActions.toggleLogDispatches()
}

togglePauseReplay() {
DebugActions.togglePauseReplay()
}

toggleRecording() {
DebugActions.toggleRecording()
}

view(ev) {
const data = ev.target.dataset
const dispatch = this.props.dispatches[data.index]
DebugActions.selectData(dispatch)
}

renderName(name, _, dispatch, idx) {
return (
<div
data-index={idx}
onClick={this.view}
style={{ cursor: 'pointer' }}
>
{name}
</div>
)
}

renderReplay() {
if (this.props.inReplayMode) {
return (
<span>
<span onClick={this.togglePauseReplay}>
{this.props.isReplaying ? 'Pause Replay' : 'Resume Replay'}
</span>
{' | '}
<span onClick={this.stopReplay}>
Stop Replay
</span>
</span>
)
}

return (
<span onClick={this.startReplay}>
Start Replay
</span>
)
}

renderRevert(a, b, dispatch) {
return (
<div>
<span
data-dispatch-id={dispatch.id}
onClick={this.revert}
style={{ cursor: 'pointer' }}
>
Revert
</span>
<span dangerouslySetInnerHTML={{
__html: this.props.currentStateId === dispatch.id ? '&#10003;' : ''
}} />
</div>
)
}

render() {
return (
<div>
<h3>Dispatches</h3>
<FixedDataTableCss />
<div>
<span onClick={this.toggleRecording}>
{this.props.isRecording ? 'Stop Recording' : 'Record'}
</span>
{' | '}
<span onClick={this.clear}>
Clear
</span>
{' | '}
<span onClick={this.saveRecording}>
Save
</span>
{' | '}
<span onClick={this.loadRecording}>
Load
</span>
{' | '}
{this.renderReplay()}
</div>
<Table
headerHeight={30}
height={480}
rowGetter={this.getDispatch}
rowHeight={30}
rowsCount={this.props.dispatches.length}
width={320}
>
<Column
cellRenderer={this.renderName}
dataKey="action"
label="Name"
width={250}
/>
<Column
cellRenderer={this.renderRevert}
dataKey=""
label="Revert"
width={70}
/>
</Table>
</div>
)
}
}

export default connectToStores({
getPropsFromStores() {
return DispatcherStore.getState()
},

getStores() {
return [DispatcherStore]
}
}, DispatcherDebugger)
4 changes: 3 additions & 1 deletion src/utils/DispatcherRecorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,9 @@ DispatcherRecorder.prototype.replay = function (replayTime, done) {
DispatcherRecorder.prototype.serializeEvents = function () {
const events = this.events.map((event) => {
return {
id: event.id,
action: event.action,
data: event.data
data: event.data || {}
}
})
return JSON.stringify(events)
Expand All @@ -129,6 +130,7 @@ DispatcherRecorder.prototype.loadEvents = function (events) {
data: event.data
}
})
return parsedEvents
}

export default DispatcherRecorder
Loading

0 comments on commit ad9c2bb

Please sign in to comment.