Enforce codestyle

This commit is contained in:
Thomas Nordquist
2019-01-02 16:37:36 +01:00
parent 48aa317c7c
commit 2b7e9a5ef7
24 changed files with 492 additions and 195 deletions

View File

@@ -1,11 +1,11 @@
import * as React from "react"; import * as React from 'react'
import * as q from '../../backend/src/Model' import * as q from '../../backend/src/Model'
import { Tree } from "./components/Tree" import { Tree } from './components/Tree'
import TitleBar from "./components/TitleBar"; import TitleBar from './components/TitleBar'
import { Sidebar } from "./components/Sidebar"; import { Sidebar } from './components/Sidebar'
import { withTheme, Theme } from '@material-ui/core/styles'; import { withTheme, Theme } from '@material-ui/core/styles'
class State { class State {
public selectedNode?: q.TreeNode | undefined public selectedNode?: q.TreeNode | undefined
@@ -17,12 +17,12 @@ interface Props {
class App extends React.Component<Props, State> { class App extends React.Component<Props, State> {
constructor(props: any) { constructor(props: any) {
super(props); super(props)
this.state = { this.state = {
selectedNode: undefined selectedNode: undefined,
} }
console.log("asd", this.props) console.log('asd', this.props)
this.theme = this.props.theme this.theme = this.props.theme
this.styles = { this.styles = {
primaryText: { primaryText: {
@@ -32,7 +32,7 @@ class App extends React.Component<Props, State> {
}, },
primaryColor: { primaryColor: {
backgroundColor: this.theme.palette.background.default, backgroundColor: this.theme.palette.background.default,
//padding: `${this.theme.spacing.unit}px ${this.theme.spacing.unit * 2}px`, // padding: `${this.theme.spacing.unit}px ${this.theme.spacing.unit * 2}px`,
color: this.theme.palette.common.white, color: this.theme.palette.common.white,
}, },
} }
@@ -45,7 +45,7 @@ class App extends React.Component<Props, State> {
return <div style={this.styles.primaryColor}> return <div style={this.styles.primaryColor}>
<TitleBar /> <TitleBar />
<Tree didSelectNode={(node: q.TreeNode) => { <Tree didSelectNode={(node: q.TreeNode) => {
this.setState({selectedNode: node}) this.setState({ selectedNode: node })
console.log('did select', node) console.log('did select', node)
}} /> }} />
</div> </div>

View File

@@ -1,8 +1,8 @@
import * as React from "react"; import * as React from 'react'
import * as q from '../../../backend/src/Model' import * as q from '../../../backend/src/Model'
import Drawer from '@material-ui/core/Drawer'; import Drawer from '@material-ui/core/Drawer'
import TextField from '@material-ui/core/TextField'; import TextField from '@material-ui/core/TextField'
import Paper from '@material-ui/core/Paper'; import Paper from '@material-ui/core/Paper'
import { ValueRenderer } from './ValueRenderer' import { ValueRenderer } from './ValueRenderer'
interface Props { interface Props {
@@ -16,13 +16,13 @@ interface State {
export class Sidebar extends React.Component<Props, State> { export class Sidebar extends React.Component<Props, State> {
private updateNode: (node?: q.TreeNode | undefined) => void private updateNode: (node?: q.TreeNode | undefined) => void
constructor(props: any) { constructor(props: any) {
super(props); super(props)
this.state = {} this.state = {}
this.updateNode = (node) => { this.updateNode = (node) => {
if (!node) { if (!node) {
this.setState(this.state) this.setState(this.state)
} else { } else {
this.setState({node: node}) this.setState({ node })
} }
} }
} }
@@ -44,8 +44,8 @@ export class Sidebar extends React.Component<Props, State> {
} }
private renderNode() { private renderNode() {
let style: React.CSSProperties = {display: 'block', width: '40vw'} const style: React.CSSProperties = { display: 'block', width: '40vw' }
let topicStyle: React.CSSProperties = {width: '100%'} const topicStyle: React.CSSProperties = { width: '100%' }
if (!this.state.node) { if (!this.state.node) {
return null return null

View File

@@ -1,13 +1,13 @@
import * as React from "react"; import * as React from 'react'
import * as q from '../../../backend/src/Model' import * as q from '../../../backend/src/Model'
import SearchIcon from '@material-ui/icons/Search'; import Search from '@material-ui/icons/Search'
import { AppBar, Toolbar, Typography, InputBase } from '@material-ui/core'; import { AppBar, Toolbar, Typography, InputBase } from '@material-ui/core'
import { withStyles, StyleRulesCallback } from '@material-ui/core/styles'; import { withStyles, StyleRulesCallback } from '@material-ui/core/styles'
import { fade } from '@material-ui/core/styles/colorManipulator'; import { fade } from '@material-ui/core/styles/colorManipulator'
const styles: StyleRulesCallback = (theme) => ({ const styles: StyleRulesCallback = theme => ({
title: { title: {
display: 'none', display: 'none',
[theme.breakpoints.up('sm')]: { [theme.breakpoints.up('sm')]: {
@@ -52,8 +52,8 @@ const styles: StyleRulesCallback = (theme) => ({
[theme.breakpoints.up('md')]: { [theme.breakpoints.up('md')]: {
width: 200, width: 200,
}, },
} },
}); })
interface Props { interface Props {
classes: any classes: any
@@ -61,21 +61,21 @@ interface Props {
class TitleBar extends React.Component<Props, {}> { class TitleBar extends React.Component<Props, {}> {
constructor(props: any) { constructor(props: any) {
super(props); super(props)
this.state = { this.state = {
selectedNode: undefined selectedNode: undefined,
} }
} }
public render() { public render() {
const { classes } = this.props; const { classes } = this.props
return <AppBar position="static"> return <AppBar position="static">
<Toolbar> <Toolbar>
<Typography className={classes.title} variant="h6" color="inherit">MQTT-Xplorer</Typography> <Typography className={classes.title} variant="h6" color="inherit">MQTT-Xplorer</Typography>
<div className={classes.search}> <div className={classes.search}>
<div className={classes.searchIcon}> <div className={classes.searchIcon}>
<SearchIcon /> <Search />
</div> </div>
<InputBase <InputBase
placeholder="Search…" placeholder="Search…"

View File

@@ -1,10 +1,10 @@
import * as React from "react"; import * as React from 'react'
import * as io from 'socket.io-client'; import * as io from 'socket.io-client'
import * as q from '../../../backend/src/Model' import * as q from '../../../backend/src/Model'
import { TreeNode } from './TreeNode' import { TreeNode } from './TreeNode'
import List from '@material-ui/core/List'; import List from '@material-ui/core/List'
var throttle = require('lodash.throttle'); const throttle = require('lodash.throttle')
class TreeState { class TreeState {
public tree: q.Tree public tree: q.Tree
@@ -24,10 +24,10 @@ export class Tree extends React.Component<TreeNodeProps, TreeState> {
private renderDuration: number = 300 private renderDuration: number = 300
constructor(props: any) { constructor(props: any) {
super(props); super(props)
let tree = new q.Tree() const tree = new q.Tree()
this.state = new TreeState(tree, {}) this.state = new TreeState(tree, {})
this.socket = io('http://localhost:3000'); this.socket = io('http://localhost:3000')
} }
public componentDidMount() { public componentDidMount() {
@@ -36,15 +36,15 @@ export class Tree extends React.Component<TreeNodeProps, TreeState> {
updateState.cancel() updateState.cancel()
updateState = throttle(() => { updateState = throttle(() => {
this.setState(state) this.setState(state)
}, Math.max(this.renderDuration * 5, 300), {trailing: true}) }, Math.max(this.renderDuration * 5, 300), { trailing: true })
}, 1000) }, 1000)
this.socket.on('message', (msg: any) => { this.socket.on('message', (msg: any) => {
const edges = msg.topic.split('/') const edges = msg.topic.split('/')
const node = q.TreeNodeFactory.fromEdgesAndValue(edges, Buffer.from(msg.payload, "base64").toString()) const node = q.TreeNodeFactory.fromEdgesAndValue(edges, Buffer.from(msg.payload, 'base64').toString())
this.state.tree.updateWithNode(node.firstNode()) this.state.tree.updateWithNode(node.firstNode())
updateState({tree: this.state.tree, msg: msg}) updateState({ msg, tree: this.state.tree })
}) })
} }
@@ -59,9 +59,9 @@ export class Tree extends React.Component<TreeNodeProps, TreeState> {
didSelectNode={this.props.didSelectNode} didSelectNode={this.props.didSelectNode}
treeNode={this.state.tree} treeNode={this.state.tree}
name="/" collapsed={false} name="/" collapsed={false}
performanceCallback={(ms) => this.renderDuration = ms} performanceCallback={ms => this.renderDuration = ms}
/> />
</List> </List>
</div>; </div>
} }
} }

View File

@@ -1,11 +1,11 @@
import * as React from "react"; import * as React from 'react'
import * as q from '../../../backend/src/Model' import * as q from '../../../backend/src/Model'
import List from '@material-ui/core/List'; import List from '@material-ui/core/List'
import ListItem from '@material-ui/core/ListItem'; import ListItem from '@material-ui/core/ListItem'
import Collapse from '@material-ui/core/Collapse'; import Collapse from '@material-ui/core/Collapse'
export interface TreeNodeProps { export interface TreeNodeProps {
treeNode: q.TreeNode, treeNode: q.TreeNode
name?: string | undefined name?: string | undefined
collapsed?: boolean | undefined collapsed?: boolean | undefined
performanceCallback?: ((ms: number) => void) | undefined performanceCallback?: ((ms: number) => void) | undefined
@@ -13,13 +13,13 @@ export interface TreeNodeProps {
} }
interface TreeNodeState { interface TreeNodeState {
title: string | undefined, title: string | undefined
collapsed: boolean, collapsed: boolean
collapsedOverride: boolean | undefined, collapsedOverride: boolean | undefined
edgeCount: number edgeCount: number
} }
let collapseLimit = 0 const collapseLimit = 0
declare var performance: any declare var performance: any
export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> { export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
@@ -29,14 +29,14 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
constructor(props: TreeNodeProps, state: TreeNodeState) { constructor(props: TreeNodeProps, state: TreeNodeState) {
super(props, state) super(props, state)
let edgeCount = Object.keys(props.treeNode.edges).length const edgeCount = Object.keys(props.treeNode.edges).length
let collapsed = edgeCount > collapseLimit const collapsed = edgeCount > collapseLimit
this.props.treeNode.on('update', () => { this.props.treeNode.on('update', () => {
this.dirty = true this.dirty = true
}) })
this.state = {collapsed, edgeCount: edgeCount, collapsedOverride: props.collapsed, title: props.name} this.state = { collapsed, edgeCount, collapsedOverride: props.collapsed, title: props.name }
} }
public setState(state: any) { public setState(state: any) {
@@ -51,7 +51,7 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
public componentDidUpdate() { public componentDidUpdate() {
this.dirty = false this.dirty = false
if (this.props.performanceCallback) { if (this.props.performanceCallback) {
let renderTime = performance.now()-this.willUpdateTime const renderTime = performance.now() - this.willUpdateTime
this.props.performanceCallback(renderTime) this.props.performanceCallback(renderTime)
} }
} }
@@ -73,10 +73,10 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
private renderNodes() { private renderNodes() {
const edges = Object.values(this.props.treeNode.edges) const edges = Object.values(this.props.treeNode.edges)
const listItemStyle = { const listItemStyle = {
padding: '3px 8px 3px 8px' padding: '3px 8px 3px 8px',
} }
const listStyle = { const listStyle = {
padding: '3px 8px 3px 16px' padding: '3px 8px 3px 16px',
} }
if (edges.length > 0) { if (edges.length > 0) {
@@ -94,11 +94,11 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
private renderSourceEdge() { private renderSourceEdge() {
const style: React.CSSProperties = { const style: React.CSSProperties = {
fontWeight: "bold", fontWeight: 'bold',
overflow: 'hidden', overflow: 'hidden',
display: 'inline-block', display: 'inline-block',
} }
let name = this.state.title || (this.props.treeNode.sourceEdge && this.props.treeNode.sourceEdge.name) const name = this.state.title || (this.props.treeNode.sourceEdge && this.props.treeNode.sourceEdge.name)
return <span style={style} onClick={() => this.toggle()}>{name}</span> return <span style={style} onClick={() => this.toggle()}>{name}</span>
} }
@@ -110,13 +110,13 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
} }
public componentWillReceiveProps() { public componentWillReceiveProps() {
let edgeCount = Object.keys(this.props.treeNode.edges).length const edgeCount = Object.keys(this.props.treeNode.edges).length
this.setState({collapsed: edgeCount > collapseLimit, edgeCount: edgeCount}) this.setState({ edgeCount, collapsed: edgeCount > collapseLimit })
} }
private renderValue() { private renderValue() {
const style: React.CSSProperties = { const style: React.CSSProperties = {
width: "15em", width: '15em',
whiteSpace: 'nowrap', whiteSpace: 'nowrap',
overflow: 'hidden', overflow: 'hidden',
textOverflow: 'ellipsis', textOverflow: 'ellipsis',
@@ -133,12 +133,12 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
} }
private clear() { private clear() {
return <div style={{clear: 'both'}} /> return <div style={{ clear: 'both' }} />
} }
private renderTitleLine() { private renderTitleLine() {
const style = { const style = {
lineHeight: '1em' lineHeight: '1em',
} }
return <div style={style}>{this.renderExpander()} {this.renderSourceEdge()} {this.renderCollapsedSubnodes()} {this.renderValue()}</div> return <div style={style}>{this.renderExpander()} {this.renderSourceEdge()} {this.renderCollapsedSubnodes()} {this.renderValue()}</div>
} }
@@ -160,7 +160,7 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
} }
private toggle() { private toggle() {
this.setState({collapsedOverride: !this.collapsed()}) this.setState({ collapsedOverride: !this.collapsed() })
} }
private renderExpander() { private renderExpander() {
@@ -178,8 +178,8 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
return null return null
} }
let style = { const style = {
color: '#333' color: '#333',
} }
return <span style={style}>({this.props.treeNode.leafes().length} nodes)</span> return <span style={style}>({this.props.treeNode.leafes().length} nodes)</span>
} }

View File

@@ -1,6 +1,6 @@
import * as React from "react"; import * as React from 'react'
import * as q from '../../../backend/src/Model' import * as q from '../../../backend/src/Model'
import ReactJson from 'react-json-view' import { default as ReactJson } from 'react-json-view'
interface Props { interface Props {
node?: q.TreeNode | undefined node?: q.TreeNode | undefined
@@ -13,13 +13,13 @@ interface State {
export class ValueRenderer extends React.Component<Props, State> { export class ValueRenderer extends React.Component<Props, State> {
private updateNode: (node?: q.TreeNode | undefined) => void private updateNode: (node?: q.TreeNode | undefined) => void
constructor(props: any) { constructor(props: any) {
super(props); super(props)
this.state = {} this.state = {}
this.updateNode = (node) => { this.updateNode = (node) => {
if (!node) { if (!node) {
this.setState(this.state) this.setState(this.state)
} else { } else {
this.setState({node: node}) this.setState({ node })
} }
} }
} }
@@ -31,7 +31,7 @@ export class ValueRenderer extends React.Component<Props, State> {
} }
public render() { public render() {
let node = this.props.node const node = this.props.node
if (!node || !node.message) { if (!node || !node.message) {
return null return null
} }
@@ -39,7 +39,7 @@ export class ValueRenderer extends React.Component<Props, State> {
let json let json
try { try {
json = JSON.parse(node.message.value) json = JSON.parse(node.message.value)
} catch(error) { } catch (error) {
return this.renderRawValue(node.message.value) return this.renderRawValue(node.message.value)
} }
@@ -53,13 +53,13 @@ export class ValueRenderer extends React.Component<Props, State> {
} }
private renderRawValue(value: string) { private renderRawValue(value: string) {
let style: React.CSSProperties = { const style: React.CSSProperties = {
wordBreak: 'break-all', wordBreak: 'break-all',
width: '100%', width: '100%',
overflow: 'scroll', overflow: 'scroll',
display: 'block', display: 'block',
lineHeight: '1.2em', lineHeight: '1.2em',
padding: '12px 5px 12px 5px' padding: '12px 5px 12px 5px',
} }
return <pre><code style={style}>{value}</code></pre> return <pre><code style={style}>{value}</code></pre>

View File

@@ -1,15 +1,15 @@
import * as React from "react"; import * as React from 'react'
import * as ReactDOM from "react-dom"; import * as ReactDOM from 'react-dom'
import App from './App' import App from './App'
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles'; import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles'
const theme = createMuiTheme({ const theme = createMuiTheme({
palette: { palette: {
type: 'dark', // Switching the dark mode on is a single property value change. type: 'dark', // Switching the dark mode on is a single property value change.
}, },
typography: { useNextVariants: true }, typography: { useNextVariants: true },
}); })
declare var document: any declare var document: any
@@ -17,5 +17,5 @@ ReactDOM.render(
<MuiThemeProvider theme={theme}> <MuiThemeProvider theme={theme}>
<App /> <App />
</MuiThemeProvider>, </MuiThemeProvider>,
document.getElementById("example") document.getElementById('example'),
); )

View File

@@ -10,22 +10,22 @@ export class DataSourceStateMachine extends EventEmitter {
private state: DataSourceState = { private state: DataSourceState = {
error: undefined, error: undefined,
connected: false, connected: false,
connecting: false connecting: false,
} }
public setConnected(connected: boolean) { public setConnected(connected: boolean) {
this.state = { this.state = {
connected,
error: undefined, error: undefined,
connected: connected, connecting: false,
connecting: false
} }
} }
public setError(error: Error) { public setError(error: Error) {
this.state = { this.state = {
error: error, error,
connected: false, connected: false,
connecting: false connecting: false,
} }
} }
@@ -33,7 +33,7 @@ export class DataSourceStateMachine extends EventEmitter {
this.state = { this.state = {
error: undefined, error: undefined,
connected: false, connected: false,
connecting: true connecting: true,
} }
} }

View File

@@ -19,7 +19,7 @@ export class MqttSource implements DataSource<MqttOptions> {
const state = new DataSourceStateMachine() const state = new DataSourceStateMachine()
const client = mqttConnect(options.url, { const client = mqttConnect(options.url, {
resubscribe: false resubscribe: false,
}) })
this.client = client this.client = client

View File

@@ -1,11 +1,3 @@
import { DataSource } from './DataSource' export { DataSource } from './DataSource'
import { DataSourceState, DataSourceStateMachine } from './DataSourceState' export { DataSourceState, DataSourceStateMachine } from './DataSourceState'
import { MqttOptions, MqttSource } from './MqttSource' export { MqttOptions, MqttSource } from './MqttSource'
export {
DataSource,
DataSourceState,
DataSourceStateMachine,
MqttOptions,
MqttSource,
}

View File

@@ -18,8 +18,8 @@ export class Edge implements Hashable {
public hash(): string { public hash(): string {
if (!this.cachedHash) { if (!this.cachedHash) {
let previousHash = (this.source && this.source.sourceEdge) ? this.source.sourceEdge.hash() : '' const previousHash = (this.source && this.source.sourceEdge) ? this.source.sourceEdge.hash() : ''
this.cachedHash = 'H' + sha1(previousHash + this.name) this.cachedHash = `H${sha1(previousHash + this.name)}`
} }
return this.cachedHash return this.cachedHash
@@ -28,8 +28,8 @@ export class Edge implements Hashable {
public firstEdge(): Edge { public firstEdge(): Edge {
if (this.source && this.source.sourceEdge) { if (this.source && this.source.sourceEdge) {
return this.source.sourceEdge.firstEdge() return this.source.sourceEdge.firstEdge()
} else { }
return this return this
} }
}
} }

View File

@@ -25,7 +25,7 @@ export class TreeNode extends EventEmitter {
} }
public hash(): string { public hash(): string {
return 'N' + (this.sourceEdge ? this.sourceEdge.hash() : '') return `N${(this.sourceEdge ? this.sourceEdge.hash() : '')}`
} }
public firstNode(): TreeNode { public firstNode(): TreeNode {
@@ -49,8 +49,8 @@ export class TreeNode extends EventEmitter {
this.emit('update') this.emit('update')
} }
public branch(): Array<TreeNode> { public branch(): TreeNode[] {
let previous = this.previous() const previous = this.previous()
if (!previous) { if (!previous) {
return [this] return [this]
} }
@@ -67,7 +67,7 @@ export class TreeNode extends EventEmitter {
this.emit('update') this.emit('update')
} }
public leafes(): Array<TreeNode> { public leafes(): TreeNode[] {
if (Object.values(this.edges).length === 0) { if (Object.values(this.edges).length === 0) {
return [this] return [this]
} }
@@ -78,9 +78,9 @@ export class TreeNode extends EventEmitter {
} }
private mergeEdges(node: TreeNode) { private mergeEdges(node: TreeNode) {
let edgeKeys = Object.keys(node.edges) const edgeKeys = Object.keys(node.edges)
for (let edgeKey of edgeKeys) { for (const edgeKey of edgeKeys) {
let matchingEdge = this.edges[edgeKey] const matchingEdge = this.edges[edgeKey]
if (matchingEdge) { if (matchingEdge) {
matchingEdge.target.updateWithNode(node.edges[edgeKey].target) matchingEdge.target.updateWithNode(node.edges[edgeKey].target)
} else { } else {

View File

@@ -1,17 +1,17 @@
import { Edge, Message, Tree, TreeNode } from './' import { Edge, Message, Tree, TreeNode } from './'
export abstract class TreeNodeFactory { export abstract class TreeNodeFactory {
public static fromEdgesAndValue(edgeNames: Array<string>, value: any): TreeNode { public static fromEdgesAndValue(edgeNames: string[], value: any): TreeNode {
let currentNode: TreeNode = new Tree() let currentNode: TreeNode = new Tree()
for (const edgeName of edgeNames) { for (const edgeName of edgeNames) {
const edge = new Edge(edgeName) const edge = new Edge(edgeName)
let newNode = new TreeNode(edge) const newNode = new TreeNode(edge)
edge.target = newNode edge.target = newNode
currentNode.addEdge(edge) currentNode.addEdge(edge)
currentNode = newNode currentNode = newNode
} }
currentNode.setMessage({ value: value }) currentNode.setMessage({ value })
return currentNode return currentNode
} }
} }

View File

@@ -4,34 +4,34 @@ import 'mocha'
describe('Edge', () => { describe('Edge', () => {
it('should contain a name', () => { it('should contain a name', () => {
let e = new Edge('foo') const e = new Edge('foo')
expect(e.name).to.equal('foo') expect(e.name).to.equal('foo')
}); })
it('firstEdge should retireve the first edge', () => { it('firstEdge should retireve the first edge', () => {
const topics = 'foo/bar/baz'.split('/') const topics = 'foo/bar/baz'.split('/')
const leaf = TreeNodeFactory.fromEdgesAndValue(topics, 5) const leaf = TreeNodeFactory.fromEdgesAndValue(topics, 5)
let bazEdge = leaf.sourceEdge const bazEdge = leaf.sourceEdge
if (!bazEdge) { if (!bazEdge) {
expect.fail('should not be undefined') expect.fail('should not be undefined')
return; return
} }
expect(bazEdge.name).to.eq('baz') expect(bazEdge.name).to.eq('baz')
expect(bazEdge.firstEdge().name).to.eq('foo') expect(bazEdge.firstEdge().name).to.eq('foo')
}); })
it('hash should not be empty', () => { it('hash should not be empty', () => {
let e = new Edge('bar') const e = new Edge('bar')
expect(e.hash().length).to.be.gt(0) expect(e.hash().length).to.be.gt(0)
}); })
it('hash should be stable', () => { it('hash should be stable', () => {
let e = new Edge('bar') const e = new Edge('bar')
let previousHash = e.hash() const previousHash = e.hash()
expect(e.hash()).to.eq(previousHash) expect(e.hash()).to.eq(previousHash)
}); })
it('hash should include change if parents are different', () => { it('hash should include change if parents are different', () => {
const topics1 = 'foo/bar/baz'.split('/') const topics1 = 'foo/bar/baz'.split('/')
@@ -45,5 +45,5 @@ describe('Edge', () => {
} }
expect(bazEdge1.hash()).to.not.eq(bazEdge2.hash()) expect(bazEdge1.hash()).to.not.eq(bazEdge2.hash())
}); })
}); })

View File

@@ -12,7 +12,7 @@ describe('Tree', () => {
const leaf = TreeNodeFactory.fromEdgesAndValue(topics, 3) const leaf = TreeNodeFactory.fromEdgesAndValue(topics, 3)
tree.updateWithNode(leaf.firstNode()) tree.updateWithNode(leaf.firstNode())
let expectedNode = tree.findNode('foo/bar') const expectedNode = tree.findNode('foo/bar')
expect(expectedNode).to.eq(leaf) expect(expectedNode).to.eq(leaf)
}) })
}); })

View File

@@ -9,17 +9,17 @@ describe('TreeNode.findNode', () => {
const topics = 'foo/bar/baz'.split('/') const topics = 'foo/bar/baz'.split('/')
const leaf = TreeNodeFactory.fromEdgesAndValue(topics, 5) const leaf = TreeNodeFactory.fromEdgesAndValue(topics, 5)
let root = leaf.firstNode() const root = leaf.firstNode()
expect(root.sourceEdge).to.eq(undefined) expect(root.sourceEdge).to.eq(undefined)
let barNode = root.findNode('foo/bar') const barNode = root.findNode('foo/bar')
if (!barNode) { if (!barNode) {
expect.fail('did not find node') expect.fail('did not find node')
return return
} }
expect(barNode.sourceEdge && barNode.sourceEdge.name).to.eq('bar') expect(barNode.sourceEdge && barNode.sourceEdge.name).to.eq('bar')
let bazNode = root.findNode('foo/bar/baz') const bazNode = root.findNode('foo/bar/baz')
if (!bazNode) { if (!bazNode) {
expect.fail('did not find node') expect.fail('did not find node')
return return

View File

@@ -5,10 +5,10 @@ declare module '../' {
} }
} }
TreeNode.prototype.findNode = function(path: String): TreeNode | undefined { TreeNode.prototype.findNode = function (path: String): TreeNode | undefined {
const topics = path.split('/') const topics = path.split('/')
let edge = this.edges[topics[0]] const edge = this.edges[topics[0]]
let remainingTopics = topics.slice(1, topics.length) const remainingTopics = topics.slice(1, topics.length)
if (edge && remainingTopics.length === 0) { if (edge && remainingTopics.length === 0) {
return edge.target return edge.target
} else if (edge) { } else if (edge) {

View File

@@ -17,7 +17,7 @@ describe('TreeNode', () => {
expect(leaf.message && leaf.message.value).to.eq(3) expect(leaf.message && leaf.message.value).to.eq(3)
const updateLeave = TreeNodeFactory.fromEdgesAndValue(topics, 5) const updateLeave = TreeNodeFactory.fromEdgesAndValue(topics, 5)
let root = leaf.firstNode() const root = leaf.firstNode()
root.updateWithNode(updateLeave.firstNode()) root.updateWithNode(updateLeave.firstNode())
expect(root.sourceEdge).to.eq(undefined) expect(root.sourceEdge).to.eq(undefined)
@@ -33,7 +33,7 @@ describe('TreeNode', () => {
const updateLeave = TreeNodeFactory.fromEdgesAndValue(topics2, 5) const updateLeave = TreeNodeFactory.fromEdgesAndValue(topics2, 5)
leaf.firstNode().updateWithNode(updateLeave.firstNode()) leaf.firstNode().updateWithNode(updateLeave.firstNode())
let barNode = leaf.firstNode().findNode('foo/bar') const barNode = leaf.firstNode().findNode('foo/bar')
expect(barNode && barNode.sourceEdge && barNode.sourceEdge.name).to.eq('bar') expect(barNode && barNode.sourceEdge && barNode.sourceEdge.name).to.eq('bar')
expect(barNode && barNode.message && barNode.message.value).to.eq(5) expect(barNode && barNode.message && barNode.message.value).to.eq(5)
@@ -50,10 +50,10 @@ describe('TreeNode', () => {
leaf1.firstNode().updateWithNode(leaf2.firstNode()) leaf1.firstNode().updateWithNode(leaf2.firstNode())
let expectedNode = leaf1.firstNode().findNode('foo/bar/baz') const expectedNode = leaf1.firstNode().findNode('foo/bar/baz')
if (!expectedNode) { if (!expectedNode) {
expect.fail('merge seems to have failed') expect.fail('merge seems to have failed')
return return
} }
}) })
}); })

View File

@@ -5,17 +5,17 @@ import './TreeNode.findNode'
describe('TreeNodeFactory', () => { describe('TreeNodeFactory', () => {
it('root node must not have a sourceEdge', () => { it('root node must not have a sourceEdge', () => {
let topic = 'foo/bar' const topic = 'foo/bar'
let edges = topic.split('/') const edges = topic.split('/')
let leaf = TreeNodeFactory.fromEdgesAndValue(edges, 5) const leaf = TreeNodeFactory.fromEdgesAndValue(edges, 5)
expect(leaf.firstNode().sourceEdge).to.eq(undefined) expect(leaf.firstNode().sourceEdge).to.eq(undefined)
}); })
it('should create node', () => { it('should create node', () => {
let topic = 'foo/bar' const topic = 'foo/bar'
let edges = topic.split('/') const edges = topic.split('/')
let node = TreeNodeFactory.fromEdgesAndValue(edges, 5) const node = TreeNodeFactory.fromEdgesAndValue(edges, 5)
if (!node.sourceEdge || !node.sourceEdge.source || !node.message) { if (!node.sourceEdge || !node.sourceEdge.source || !node.message) {
expect.fail('should not happen') expect.fail('should not happen')
@@ -26,14 +26,14 @@ describe('TreeNodeFactory', () => {
expect(node.sourceEdge.name).to.eq('bar') expect(node.sourceEdge.name).to.eq('bar')
expect(node.message.value).to.eq(5) expect(node.message.value).to.eq(5)
let foo = node.firstNode().findNode('foo') const foo = node.firstNode().findNode('foo')
expect(foo && foo.sourceEdge && foo.sourceEdge.name).to.eq('foo') expect(foo && foo.sourceEdge && foo.sourceEdge.name).to.eq('foo')
}); })
it('node should contain edges in order', () => { it('node should contain edges in order', () => {
let topic = 'foo/bar/baz' const topic = 'foo/bar/baz'
let edges = topic.split('/') const edges = topic.split('/')
let node = TreeNodeFactory.fromEdgesAndValue(edges, 5) const node = TreeNodeFactory.fromEdgesAndValue(edges, 5)
if (!node.sourceEdge || !node.sourceEdge.source || !node.message) { if (!node.sourceEdge || !node.sourceEdge.source || !node.message) {
expect.fail('should not happen') expect.fail('should not happen')
@@ -56,5 +56,5 @@ describe('TreeNodeFactory', () => {
return return
} }
expect(fooNode.sourceEdge.name).to.eq('foo') expect(fooNode.sourceEdge.name).to.eq('foo')
}); })
}); })

View File

@@ -4,32 +4,29 @@ import { MqttSource, DataSource } from './DataSource'
import * as socketIO from 'socket.io' import * as socketIO from 'socket.io'
const http = require('http') const http = require('http')
let options = {url: 'mqtt://nodered'} const options = { url: 'mqtt://nodered' }
let dataSource = new MqttSource() const dataSource = new MqttSource()
const a: Array<any> = [] const a: any[] = []
const server = http.createServer() const server = http.createServer()
const io = socketIO(server) const io = socketIO(server)
io.on('connection', client => { io.on('connection', (client) => {
console.log('connection') console.log('connection')
a.forEach(b => { a.forEach((b) => {
io.emit('message', b) io.emit('message', b)
}) })
client.on('disconnect', () => { /* … */ }); client.on('disconnect', () => { /* … */ })
}); })
server.listen(3000); server.listen(3000)
let state = dataSource.connect(options) const state = dataSource.connect(options)
dataSource.onMessage((topic: string, payload: Buffer) => { dataSource.onMessage((topic: string, payload: Buffer) => {
a.push({ topic, payload: payload.toString('base64') }) let buffer = payload
if (payload.length > 10000) { a.push({ topic, payload: buffer.toString('base64') })
payload = payload.slice(0, 10000) if (buffer.length > 10000) {
buffer = buffer.slice(0, 10000)
} }
io.emit('message', { topic, payload: payload.toString('base64') }) io.emit('message', { topic, payload: buffer.toString('base64') })
}) })
setTimeout(() => {
dataSource.disconnect()
}, 1000000)

View File

@@ -1,28 +1,28 @@
import * as builder from 'electron-builder' import * as builder from 'electron-builder'
var linux: builder.CliOptions = { const linux: builder.CliOptions = {
x64: true, x64: true,
ia32: true, ia32: true,
armv7l: true, armv7l: true,
arm64: true, arm64: true,
linux: ['snap', 'AppImage', 'deb', 'pacman'], linux: ['snap', 'AppImage', 'deb', 'pacman'],
}; }
var win: builder.CliOptions = { const win: builder.CliOptions = {
x64: true, x64: true,
ia32: true, ia32: true,
armv7l: false, armv7l: false,
arm64: false, arm64: false,
win: ['portable'], win: ['portable'],
}; }
var mac: builder.CliOptions = { const mac: builder.CliOptions = {
x64: true, x64: true,
ia32: true, ia32: true,
armv7l: false, armv7l: false,
arm64: false, arm64: false,
mac: ['dmg'], mac: ['dmg'],
}; }
async function buildAll() { async function buildAll() {
await builder.build(linux) await builder.build(linux)

300
package-lock.json generated
View File

@@ -10,6 +10,46 @@
"integrity": "sha512-AsnBZN3a8/JcNt+KPkGGODaA4c7l3W5+WpeKgGSbstSLxqWtTXqd1ieJGBQ8IFCtRg8DmmKUcSkIkUc0A4p3YA==", "integrity": "sha512-AsnBZN3a8/JcNt+KPkGGODaA4c7l3W5+WpeKgGSbstSLxqWtTXqd1ieJGBQ8IFCtRg8DmmKUcSkIkUc0A4p3YA==",
"dev": true "dev": true
}, },
"@fimbul/bifrost": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/@fimbul/bifrost/-/bifrost-0.15.0.tgz",
"integrity": "sha512-sHTwnwA9YhxcVEJkBlfKH1KLmGQGnNYPxk+09w5NnkXelYiiP8a5f351weYfxG0CUPLt1Fgkha20Y/9+jhjn/Q==",
"dev": true,
"requires": {
"@fimbul/ymir": "^0.15.0",
"get-caller-file": "^2.0.0",
"tslib": "^1.8.1",
"tsutils": "^3.1.0"
},
"dependencies": {
"get-caller-file": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.1.tgz",
"integrity": "sha512-SpOZHfz845AH0wJYVuZk2jWDqFmu7Xubsx+ldIpwzy5pDUpu7OJHK7QYNSA2NPlDSKQwM1GFaAkciOWjjW92Sg==",
"dev": true
},
"tsutils": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.6.0.tgz",
"integrity": "sha512-hCG3lZz+uRmmiC4brr/kY6Yuypnl20PNe8t49DO4OUGlbxWkxYHF63EeG2XPSd0JcKiWmp9p55yQyrkxqSS5Dg==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
}
}
}
},
"@fimbul/ymir": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/@fimbul/ymir/-/ymir-0.15.0.tgz",
"integrity": "sha512-Ow0TfxxQ65vIktHcZyXHeDsGKuzJ9Vt6y77R/aOrXQXLMdYHG+XdbiUWzQbtaGOmNzYVkQfINiFnIdvn5Bn24g==",
"dev": true,
"requires": {
"inversify": "^5.0.0",
"reflect-metadata": "^0.1.12",
"tslib": "^1.8.1"
}
},
"@types/node": { "@types/node": {
"version": "8.10.39", "version": "8.10.39",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.39.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.39.tgz",
@@ -200,6 +240,44 @@
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
"dev": true "dev": true
}, },
"babel-code-frame": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
"dev": true,
"requires": {
"chalk": "^1.1.3",
"esutils": "^2.0.2",
"js-tokens": "^3.0.2"
},
"dependencies": {
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
}
}
},
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
@@ -519,6 +597,12 @@
"delayed-stream": "~1.0.0" "delayed-stream": "~1.0.0"
} }
}, },
"commander": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
"integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
"dev": true
},
"compare-version": { "compare-version": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz",
@@ -688,6 +772,24 @@
"sanitize-filename": "^1.6.1" "sanitize-filename": "^1.6.1"
} }
}, },
"doctrine": {
"version": "0.7.2",
"resolved": "http://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz",
"integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=",
"dev": true,
"requires": {
"esutils": "^1.1.6",
"isarray": "0.0.1"
},
"dependencies": {
"esutils": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz",
"integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=",
"dev": true
}
}
},
"dot-prop": { "dot-prop": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
@@ -862,6 +964,12 @@
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true "dev": true
}, },
"esutils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
"dev": true
},
"execa": { "execa": {
"version": "0.7.0", "version": "0.7.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
@@ -1011,6 +1119,12 @@
} }
} }
}, },
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"get-caller-file": { "get-caller-file": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
@@ -1038,6 +1152,20 @@
"assert-plus": "^1.0.0" "assert-plus": "^1.0.0"
} }
}, },
"glob": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"global-dirs": { "global-dirs": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
@@ -1088,6 +1216,15 @@
"har-schema": "^2.0.0" "har-schema": "^2.0.0"
} }
}, },
"has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
"dev": true,
"requires": {
"ansi-regex": "^2.0.0"
}
},
"has-flag": { "has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@@ -1141,6 +1278,16 @@
"repeating": "^2.0.0" "repeating": "^2.0.0"
} }
}, },
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
@@ -1153,6 +1300,12 @@
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
"dev": true "dev": true
}, },
"inversify": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/inversify/-/inversify-5.0.1.tgz",
"integrity": "sha512-Ieh06s48WnEYGcqHepdsJUIJUXpwH5o5vodAX+DK2JA/gjy4EbEcQZxw+uFfzysmKjiLXGYwNG3qDZsKVMcINQ==",
"dev": true
},
"invert-kv": { "invert-kv": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
@@ -1289,6 +1442,12 @@
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
"dev": true "dev": true
}, },
"js-tokens": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
"dev": true
},
"js-yaml": { "js-yaml": {
"version": "3.12.0", "version": "3.12.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz",
@@ -6936,6 +7095,12 @@
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
"dev": true "dev": true
}, },
"path-is-absolute": {
"version": "1.0.1",
"resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"path-is-inside": { "path-is-inside": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
@@ -6948,6 +7113,12 @@
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
"dev": true "dev": true
}, },
"path-parse": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true
},
"path-type": { "path-type": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
@@ -7141,6 +7312,12 @@
"strip-indent": "^1.0.1" "strip-indent": "^1.0.1"
} }
}, },
"reflect-metadata": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.12.tgz",
"integrity": "sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A==",
"dev": true
},
"registry-auth-token": { "registry-auth-token": {
"version": "3.3.2", "version": "3.3.2",
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
@@ -7209,6 +7386,15 @@
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
"dev": true "dev": true
}, },
"resolve": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz",
"integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
}
},
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -7552,6 +7738,120 @@
"yn": "^2.0.0" "yn": "^2.0.0"
} }
}, },
"tslib": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
"dev": true
},
"tslint": {
"version": "5.12.0",
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.0.tgz",
"integrity": "sha512-CKEcH1MHUBhoV43SA/Jmy1l24HJJgI0eyLbBNSRyFlsQvb9v6Zdq+Nz2vEOH00nC5SUx4SneJ59PZUS/ARcokQ==",
"dev": true,
"requires": {
"babel-code-frame": "^6.22.0",
"builtin-modules": "^1.1.1",
"chalk": "^2.3.0",
"commander": "^2.12.1",
"diff": "^3.2.0",
"glob": "^7.1.1",
"js-yaml": "^3.7.0",
"minimatch": "^3.0.4",
"resolve": "^1.3.2",
"semver": "^5.3.0",
"tslib": "^1.8.0",
"tsutils": "^2.27.2"
}
},
"tslint-config-airbnb": {
"version": "5.11.1",
"resolved": "https://registry.npmjs.org/tslint-config-airbnb/-/tslint-config-airbnb-5.11.1.tgz",
"integrity": "sha512-hkaittm2607vVMe8eotANGN1CimD5tor7uoY3ypg2VTtEcDB/KGWYbJOz58t8LI4cWSyWtgqYQ5F0HwKxxhlkQ==",
"dev": true,
"requires": {
"tslint-consistent-codestyle": "^1.14.1",
"tslint-eslint-rules": "^5.4.0",
"tslint-microsoft-contrib": "~5.2.1"
}
},
"tslint-consistent-codestyle": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslint-consistent-codestyle/-/tslint-consistent-codestyle-1.14.1.tgz",
"integrity": "sha512-UxGRX2fF5LpZtqYpuPFaIva+2D7ASX3pTVw41yis6Hmw7PPA3cBnFEX1jqRsnyxGrca6mHxz7xDnwCHtOjWJMQ==",
"dev": true,
"requires": {
"@fimbul/bifrost": "^0.15.0",
"tslib": "^1.7.1",
"tsutils": "^2.29.0"
}
},
"tslint-eslint-rules": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz",
"integrity": "sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w==",
"dev": true,
"requires": {
"doctrine": "0.7.2",
"tslib": "1.9.0",
"tsutils": "^3.0.0"
},
"dependencies": {
"tslib": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz",
"integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==",
"dev": true
},
"tsutils": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.6.0.tgz",
"integrity": "sha512-hCG3lZz+uRmmiC4brr/kY6Yuypnl20PNe8t49DO4OUGlbxWkxYHF63EeG2XPSd0JcKiWmp9p55yQyrkxqSS5Dg==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
}
}
}
},
"tslint-microsoft-contrib": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-5.2.1.tgz",
"integrity": "sha512-PDYjvpo0gN9IfMULwKk0KpVOPMhU6cNoT9VwCOLeDl/QS8v8W2yspRpFFuUS7/c5EIH/n8ApMi8TxJAz1tfFUA==",
"dev": true,
"requires": {
"tsutils": "^2.27.2 <2.29.0"
},
"dependencies": {
"tsutils": {
"version": "2.28.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz",
"integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
}
}
}
},
"tslint-react": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/tslint-react/-/tslint-react-3.6.0.tgz",
"integrity": "sha512-AIv1QcsSnj7e9pFir6cJ6vIncTqxfqeFF3Lzh8SuuBljueYzEAtByuB6zMaD27BL0xhMEqsZ9s5eHuCONydjBw==",
"dev": true,
"requires": {
"tsutils": "^2.13.1"
}
},
"tsutils": {
"version": "2.29.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
"integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
}
},
"tunnel-agent": { "tunnel-agent": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",

View File

@@ -32,6 +32,9 @@
"electron": "^4.0.0", "electron": "^4.0.0",
"electron-builder": "^20.38.4", "electron-builder": "^20.38.4",
"ts-node": "^7.0.1", "ts-node": "^7.0.1",
"tslint": "^5.12.0",
"tslint-config-airbnb": "^5.11.1",
"tslint-react": "^3.6.0",
"typescript": "^3.2.2" "typescript": "^3.2.2"
}, },
"dependencies": { "dependencies": {

View File

@@ -1,5 +1,10 @@
{ {
"extends": "tslint-config-airbnb",
"rules": { "rules": {
"member-access": true "semicolon": [true, "never"],
"max-line-length": [true, 200],
"member-access": true,
"no-else-after-return": false,
"align": false
} }
} }