Skip to content

docs: fixed some typos #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,34 @@
## Usage

```js
import { Recordable } from './index.js'
import { Recordable } from '@nicholaswmin/recordable'

const task = new Recordable()
task.record(1)
task.record(100)

task.record(1)
for (let i = 0; i < 600; i++)
task.record(Math.round(Math.random() * 20) + 1)
task.record(100)

console.log(task.min)
// 3.05 ms
console.log(task.mean)
// 11.42 ms
// 23.42 ms
console.log(task.max)
// 85.17 m
// 85.17 ms
console.log(task.stddev)
// 5.17 ms
// 15.17 ms
```

### Plotting

```js
const task = new Recordable()
task.record(1)
task.record(100)

task.record(1)
for (let i = 0; i < 600; i++)
task.record(Math.round(Math.random() * 20) + 1)
task.record(100)

task.plot()
```
Expand Down
5 changes: 4 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { StatsView } from './src/stats-view.js'
import { StatsList } from './src/stats-list.js'
import { StatsStore } from './src/stats-store.js'
import { Recordable } from './src/recordable.js'

export { Recordable }
export { Recordable, StatsStore, StatsList, StatsView }
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'node:test'
import { Recordable } from '../index.js'
import { Recordable } from '../../index.js'

await test('#toClampedAverages(maxLength)', async t => {
let recordable, result = null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'node:test'
import { Recordable } from '../index.js'
import { Recordable } from '../../index.js'

await test('#constructor(name)', async t => {
let recordable = null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'node:test'
import { Recordable } from '../index.js'
import { Recordable } from '../../index.js'

await test('#recordable.histogram values', async t => {
let recordable
Expand Down
2 changes: 1 addition & 1 deletion test/histogram.test.js → recordable/histogram.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'node:test'
import { Recordable } from '../index.js'
import { Recordable } from '../../index.js'

await test('#historicalMeans', async t => {
let recordable, histogram = null
Expand Down
10 changes: 10 additions & 0 deletions recordable/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import './constructor.test.js'
import './record-delta.test.js'
import './histogram.test.js'
import './histogram-values.test.js'
import './clamped-averages.test.js'
import './to-json.test.js'
import './record.test.js'
import './reset.test.js'
import './plot.test.js'
import './tick.test.js'
39 changes: 39 additions & 0 deletions recordable/patch-event.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import test from 'node:test'
import { Recordable } from '../../index.js'

await test('#patchEvent', async t => {
let recordable

t.beforeEach(() => {
recordable = new Recordable({ name: 'foo' })
})

await t.test('a value is recorded', async t => {
let message = null

t.beforeEach(async () => {
recordable.ee.on('value:recorded', msg => {
message = msg
})

recordable.record(20)

return new Promise(res => setTimeout(res, 50))
})

await t.test('event is fired', async t => {
t.assert.ok(message)
})

await t.test('message look ok', async t => {
t.assert.ok(typeof message, 'object')
t.assert.ok(Object.hasOwn(message, 'name'))
t.assert.ok(Object.hasOwn(message, 'val'))
})

await t.test('has correct values', async t => {
t.assert.strictEqual(message.name, 'foo')
t.assert.strictEqual(message.val, 20)
})
})
})
2 changes: 1 addition & 1 deletion test/plot.test.js → recordable/plot.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'node:test'
import { Recordable } from '../index.js'
import { Recordable } from '../../index.js'

await test('#plot()', async t => {
let plot = null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'node:test'
import { Recordable } from '../index.js'
import { Recordable } from '../../index.js'

const sleep = (ms = 5) => new Promise(resolve => setTimeout(resolve, ms))

Expand Down
2 changes: 1 addition & 1 deletion test/record.test.js → recordable/record.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'node:test'
import { Recordable } from '../index.js'
import { Recordable } from '../../index.js'

await test('#record(val)', async t => {
let recordable
Expand Down
63 changes: 63 additions & 0 deletions recordable/remote-patch.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import test from 'node:test'
import { Recordable } from '../../index.js'

await test('#applyRemotePatch', async t => {
let recordable

t.beforeEach(() => {
recordable = new Recordable({ name: 'foo' })
})

await t.test('name is different', async t => {
await t.test('throws Error', t => {
t.assert.throws(() => {
recordable.applyRemotePatch({ name: 'bar', val: 10 })
}, {
name: 'RangeError'
})
})
})

await t.test('value is not a positive integer', async t => {
await t.test('throws Error', t => {
t.assert.throws(() => {
recordable.applyRemotePatch({ name: 'foo', val: 0 })
}, {
name: 'RangeError'
})
})
})

await t.test('patch is valid', async t => {
t.beforeEach(() => {
recordable.applyRemotePatch({ name: 'foo', val: 10 })
recordable.applyRemotePatch({ name: 'foo', val: 20 })
})

await t.test('does not throw error', t => {
t.assert.doesNotThrow(() => {
recordable.applyRemotePatch({ name: 'foo', val: 10 })
})
})

await t.test('does not emit "value:recorded" event', async t => {

Check failure on line 43 in recordable/remote-patch.test.js

View workflow job for this annotation

GitHub Actions / build (latest)

't' is defined but never used
recordable.ee.on('value:recorded', e => {

Check failure on line 44 in recordable/remote-patch.test.js

View workflow job for this annotation

GitHub Actions / build (latest)

'e' is defined but never used
})

recordable.applyRemotePatch({ name: 'foo', val: 10 })
await new Promise(resolve => setTimeout(resolve, 25))
})

await t.test('increases count', t => {
t.assert.strictEqual(recordable.count, 2)
})

await t.test('increases mean', t => {
t.assert.strictEqual(recordable.mean, 15)
})

await t.test('adds to items', t => {
t.assert.strictEqual(recordable.values.length, 2)
})
})
})
2 changes: 1 addition & 1 deletion test/reset.test.js → recordable/reset.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'node:test'
import { Recordable } from '../index.js'
import { Recordable } from '../../index.js'

await test('#reset()', async t => {
let recordable = null
Expand Down
2 changes: 1 addition & 1 deletion test/tick.test.js → recordable/tick.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'node:test'
import { Recordable } from '../index.js'
import { Recordable } from '../../index.js'

await test('#tick()', async t => {
const recordable = new Recordable()
Expand Down
2 changes: 1 addition & 1 deletion test/to-json.test.js → recordable/to-json.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'node:test'
import { Recordable } from '../index.js'
import { Recordable } from '../../index.js'

await test('#record(val)', async t => {
await t.test('reimporting its JSON revives it to same state', async t => {
Expand Down
21 changes: 21 additions & 0 deletions src/colorlist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const colorlist = {
black: '\x1B[30m',
red: '\x1B[31m',
green: '\x1B[32m',
yellow: '\x1B[33m',
blue: '\x1B[34m',
magenta: '\x1B[35m',
cyan: '\x1B[36m',
lightgray: '\x1B[37m',
default: '\x1B[39m',
darkgray: '\x1B[90m',
lightred: '\x1B[91m',
lightgreen: '\x1B[92m',
lightyellow: '\x1B[93m',
lightblue: '\x1B[94m',
lightmagenta: '\x1B[95m',
lightcyan: '\x1B[96m',
white: '\x1B[97m'
}

export default colorlist
4 changes: 2 additions & 2 deletions src/recordable.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ class Recordable {
})
})

this._recordFn = this.histogram.record.bind(this.histogram)
this.histogramRecord = this.histogram.record.bind(this.histogram)
this.histogram.record = val => {
const result = this._recordFn(val)
const result = this.histogramRecord(val)

this.values.push(val)

Expand Down
57 changes: 57 additions & 0 deletions src/stats-list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
class StatsList {
constructor({
title = '', subtitle = '', maxRows = 5,
sort = function(a, b) { a - b },
fields = [
['foo.mean', 'Mean Task Duration (ms)'],
['bar.count', 'Total Count']
]
} = {}, statsStore = null) {
this.statsStore = statsStore

this.title = title
this.subtitle = subtitle
this.maxRows = maxRows
this.fields = fields

this.rows = []
this.sort = sort
}

render() {
const rows = this.statsStore

Check failure on line 22 in src/stats-list.js

View workflow job for this annotation

GitHub Actions / build (latest)

'rows' is assigned a value but never used
? [this.statsStore.getRow()]
: this.rows.slice(this.rows.length - this.maxRows, this.rows.length)

const values = this.rows
.sort(this.sort)
.slice(this.rows.length - this.maxRows, this.rows.length)
.map(row => {
return this.fields.reduce((acc, field) => {
const split = field[0].split('.')
return {
...acc,
[field[1]] : row[2]
? row[2](row[split[0]][split[1]])
: row[split[0]][split[1]]
}
}, {})
})

this.title
? console.log('Title:', this.title)
: null

console.table(values)

this.subtitle
? console.log(this.subtitle)
: null
}

append(row) {
this.rows.push(row)
}
}

export { StatsList }
23 changes: 23 additions & 0 deletions src/stats-store.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Recordable } from './recordable.js'

class StatsStore {
constructor(...args) {
Object.assign(this, args.reduce((acc, name) => {
return { ...acc, [name]: new Recordable({ name }) }
}, {}))
}

getMembers() {
return Object.values(this).filter(value => value instanceof Recordable)
}

getRow() {
return this.getMembers().reduce((acc, member) => {
return {
...acc, [member.name]: member.histogram.toJSON()
}
}, { id: process.pid })
}
}

export { StatsStore }
36 changes: 36 additions & 0 deletions src/stats-view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
class StatsView {
constructor(lists, {
title = '',
subtitle = '',
updateInterval = 500
} = {}) {
this.title = title
this.subtitle = subtitle
this.lists = lists

this.timer = setInterval(this.render.bind(this), updateInterval)
}

render() {
console.clear()

console.log('\n')

this.title
? console.log('Title:', this.title)
: null

this.lists.forEach(list => {
list.render()
console.log('\n')
})

console.log('\n')
}

stop() {
clearInterval(this.timer)
}
}

export { StatsView }
Loading
Loading