Skip to content

Commit

Permalink
Remove generic construct
Browse files Browse the repository at this point in the history
  • Loading branch information
dino-absoluto committed Apr 18, 2019
1 parent 0a3b58f commit 5fb58c9
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 104 deletions.
8 changes: 4 additions & 4 deletions src/__tests__/base.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@
*/
/* eslint-env jest */
/* imports */
import { BaseElement, Base, BaseData } from '../base'
import { AbstractElement, Base } from '../base'
import { Group } from '../group'

/* code */
const immediate = (): Promise<void> => {
return new Promise((resolve): void => void setImmediate(resolve))
}

describe('BaseElement', (): void => {
describe('AbstractElement', (): void => {
test('simple', async (): Promise<void> => {
interface TestI {
a: number
b: number
c: number
}
class TestE<T extends TestI> extends BaseElement<T> {
class TestE extends AbstractElement {
public count = 0
public tProxy = this.proxy
public tFlush = this.flush
Expand Down Expand Up @@ -91,7 +91,7 @@ describe('BaseElement', (): void => {
})

describe('Base', (): void => {
class TestBase extends Base<BaseData> {
class TestBase extends Base {
public handleCalculateWidth (): number {
return 1
}
Expand Down
20 changes: 9 additions & 11 deletions src/bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@
*
*/
/* imports */
import { Base, BaseOptions, BaseData } from './base'
import { Base, BaseOptions } from './base'
import clamp from 'lodash-es/clamp'

/* code */
// █████▒░░░░░░░░░
// ██████▓░░░░░░░░
// █████████████▓░
// █▓▒░▒▓█
/** Describe a progress theme to class Bar constructor() */
/** @public Describe a progress theme to class Bar constructor() */
export interface BarTheme {
symbols: string[]
}
Expand All @@ -41,16 +41,10 @@ export interface BarOptions extends BaseOptions {
ratio?: number
}

/** @internal data */
export interface BarData extends BaseData {
ratio: number
theme: BarTheme
}

/** @public
* A progress bar
*/
export class Bar<T extends BarData> extends Base<T> {
export class Bar extends Base {
public constructor (options: BarOptions = {}) {
super(options)
if (options.theme != null) {
Expand All @@ -65,13 +59,17 @@ export class Bar<T extends BarData> extends Base<T> {
}

/** Bar rendering theme */
public get theme (): BarTheme { return this.proxy.theme || themeDefault }
public get theme (): BarTheme {
return this.proxy.theme as BarTheme || themeDefault
}
public set theme (theme: BarTheme) {
this.proxy.theme = theme
}

/** Completion ratio, range from 0 to 1 */
public get ratio (): number { return this.proxy.ratio || 0 }
public get ratio (): number {
return this.proxy.ratio as number || 0
}
public set ratio (value: number) {
this.proxy.ratio = clamp(value, 0, 1)
}
Expand Down
61 changes: 31 additions & 30 deletions src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,43 @@ import castArray from 'lodash-es/castArray'
// █████████████▓░
// █▓▒░▒▓█

/** @internal */
export abstract class BaseElement<T extends object = {}> {
protected proxy: Partial<T>
protected data: Partial<T> = {}
private pUpdate: Partial<T> = {}
/** @public */
export interface AbstractData {
[ key: string ]: unknown
}

/** @public */
export abstract class AbstractElement {
protected proxy: AbstractData
protected data: AbstractData = {}
/** @internal */
private pUpdate: AbstractData = {}
/** @internal */
private pUpdateTimer?: ReturnType<typeof setImmediate>

public constructor () {
this.proxy = new Proxy(this.data, {
get: ($, prop: keyof T): unknown => {
get: ($, prop: string): unknown => {
const { pUpdate } = this
if (pUpdate[prop] !== undefined) {
return pUpdate[prop]
} else {
return $[prop]
}
},
set: ($, prop: keyof T, value: unknown): boolean => {
set: ($, prop: string, value: unknown): boolean => {
if ($[prop] === value ||
($[prop] === this.pUpdate[prop] && $[prop] != null)) {
return true
}
this.pUpdate[prop] = value as T[keyof T]
this.pUpdate[prop] = value
this.pSchedule()
return true
}
})
}

/** @internal */
private pSchedule = once((): void => {
this.pUpdateTimer = setImmediate(this.flush)
})
Expand All @@ -67,7 +75,7 @@ export abstract class BaseElement<T extends object = {}> {
if (pUpdateTimer) {
clearImmediate(pUpdateTimer)
}
let data: Partial<T>
let data: AbstractData
;[ data, this.pUpdate ] = [ this.pUpdate, {} ]
this.handleFlush(data)
Object.assign(this.data, data)
Expand All @@ -76,22 +84,13 @@ export abstract class BaseElement<T extends object = {}> {
})
}

protected abstract handleFlush (data: Partial<T>): void
/** @internal */
protected abstract handleFlush (data: AbstractData): void
}

/** Post processing function */
/** @public Post processing function */
export type PostProcessFn = (...values: string[]) => string | string[]

/** @internal data */
export interface BaseData {
minWidth: number
maxWidth: number
flexGrow: number
flexShrink: number
enabled: boolean
postProcess?: PostProcessFn
}

/** @public Basic options elements should accept */
export interface BaseOptions {
/** Fixed width element */
Expand All @@ -112,8 +111,8 @@ export interface BaseOptions {
}

/** @public Base class for element */
export abstract class Base<T extends BaseData = BaseData>
extends BaseElement<T>
export abstract class Base
extends AbstractElement
implements ChildElement {
/** @internal */
private pParent?: ParentElement
Expand Down Expand Up @@ -153,7 +152,9 @@ export abstract class Base<T extends BaseData = BaseData>
}

/** Post process the rendered output */
public get postProcess (): PostProcessFn | undefined { return this.proxy.postProcess }
public get postProcess (): PostProcessFn | undefined {
return this.proxy.postProcess as PostProcessFn
}
public set postProcess (fn: PostProcessFn | undefined) {
this.proxy.postProcess = fn
}
Expand Down Expand Up @@ -194,7 +195,7 @@ export abstract class Base<T extends BaseData = BaseData>
/** @internal
* Handle flush event
*/
protected handleFlush (data: Partial<BaseData>): void {
protected handleFlush (data: AbstractData): void {
const { parent } = this
if (parent) {
parent.notify(this, this.data, data)
Expand All @@ -210,14 +211,14 @@ export abstract class Base<T extends BaseData = BaseData>
}

/** Minimum necessary width */
public get minWidth (): number { return this.proxy.minWidth || 0 }
public get minWidth (): number { return this.proxy.minWidth as number || 0 }
public set minWidth (value: number) {
this.proxy.minWidth = value >= 0 ? value : 0
}

/** Maximum necessary width */
public get maxWidth (): number {
return this.proxy.maxWidth || Number.MAX_SAFE_INTEGER
return this.proxy.maxWidth as number || Number.MAX_SAFE_INTEGER
}
public set maxWidth (value: number) {
this.proxy.maxWidth = Math.min(value >= 0 ? value : Number.MAX_SAFE_INTEGER,
Expand All @@ -236,23 +237,23 @@ export abstract class Base<T extends BaseData = BaseData>

/** How much the element will grow */
public get flexGrow (): number {
return (this.enabled && this.proxy.flexGrow) || 0
return (this.enabled && this.proxy.flexGrow as number) || 0
}
public set flexGrow (value: number) {
this.proxy.flexGrow = value >= 0 ? value : 0
}

/** How much the element will shrink */
public get flexShrink (): number {
return (this.enabled && this.proxy.flexShrink) || 0
return (this.enabled && this.proxy.flexShrink as number) || 0
}
public set flexShrink (value: number) {
this.proxy.flexShrink = value >= 0 ? value : 0
}

/** Is the element enabled? */
public get enabled (): boolean {
return this.proxy.enabled != null ? this.proxy.enabled : true
return this.proxy.enabled != null ? !!this.proxy.enabled : true
}
public set enabled (value: boolean) {
this.proxy.enabled = value
Expand Down
22 changes: 5 additions & 17 deletions src/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
*
*/
/* imports */
import { ChildElement, ParentElement } from './shared'
import { Base, BaseData, BaseOptions } from './base'
import { ChildElement, ParentElement, FlexChild } from './shared'
import { Base, BaseOptions } from './base'
import { Static } from './static'
import { flex } from './utils/flex'

Expand All @@ -28,27 +28,15 @@ import { flex } from './utils/flex'
// █████████████▓░
// █▓▒░▒▓█

/** @internal */
export type GroupData = BaseData
/** @public */
export type GroupOptions = BaseOptions

type FlexChild = string | number | ChildElement

/** @public elements container */
export interface Container {
add (item: FlexChild, atIndex?: number): void
remove (item: ChildElement): void
append (...items: FlexChild[]): void
clear (): void
}

/** @public
* A group of elements
*/
export class Group<T extends GroupData = GroupData>
extends Base<T>
implements ParentElement, Container {
export class Group
extends Base
implements ParentElement {
public readonly children: ChildElement[] = []

public constructor (options?: BaseOptions) {
Expand Down
4 changes: 2 additions & 2 deletions src/hide-cursor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
*/
/* imports */
import { Base, BaseData } from './base'
import { Base } from './base'
import { Output, OutputStream } from './output'

/* code */
Expand All @@ -29,7 +29,7 @@ import { Output, OutputStream } from './output'
/** @public
* Hide console cursor, this can only work when added to an Output stream.
*/
export class HideCursor extends Base<BaseData> {
export class HideCursor extends Base {
/** HideCursor doesn't accept any options */
public constructor () {
super(undefined)
Expand Down
20 changes: 18 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,28 @@
/* imports */

/* exports */
export {
AbstractData,
AbstractElement,
Base,
BaseOptions,
PostProcessFn
} from './base'
export {
Element,
ChildElement,
ParentElement,
FlexChild
} from './shared'
export { Static } from './static'
export { HideCursor } from './hide-cursor'
export { Base, BaseOptions } from './base'
export { Group, GroupOptions } from './group'
export { Space, SpaceOptions } from './space'
export { Text, TextAlignment, TextOptions } from './text'
export { Spinner, SpinnerOptions, SpinnerTheme } from './spinner'
export { Bar, BarOptions, BarTheme } from './bar'
export { Output, OutputOptions } from './output'
export {
Output,
OutputOptions,
OutputStream
} from './output'
9 changes: 3 additions & 6 deletions src/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*
*/
/* imports */
import { Group, GroupData, GroupOptions } from './group'
import { Group, GroupOptions } from './group'
import {
clearLine
, clearScreenDown
Expand All @@ -31,7 +31,7 @@ import once from 'lodash-es/once'
// ██████▓░░░░░░░░
// █████████████▓░
// █▓▒░▒▓█
/** @internal */
/** @public */
export interface OutputStream extends NodeJS.WritableStream {
isTTY?: boolean
columns?: number
Expand All @@ -43,9 +43,6 @@ export interface OutputOptions extends GroupOptions {
stream?: OutputStream
}

/** @internal */
export type OutputData = GroupData

/** @public Frame callback function */
type FrameCB = (frame: number) => void

Expand Down Expand Up @@ -124,7 +121,7 @@ export class TargetTTY implements Target {
}

/** @public Actual output to stderr */
export class Output<T extends OutputData = OutputData> extends Group<T> {
export class Output extends Group {
public readonly stream: OutputStream
public readonly isTTY: boolean = true
private pCreatedTime = Date.now()
Expand Down
Loading

0 comments on commit 5fb58c9

Please sign in to comment.