Last active
December 10, 2023 08:02
-
-
Save nyteshade/d67304151b4f15ff5908652e1a9476c0 to your computer and use it in GitHub Desktop.
Tickers are small state objects that are designed to increment or decrement values within themselves
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Ticker } from './ticker.js' | |
/** | |
* The `Count` class extends the `Ticker` class and provides additional methods | |
* for arithmetic operations on the count value, like adding, subtracting, | |
* multiplying, and dividing by a specified delta value. | |
*/ | |
class Count extends Ticker { | |
/** | |
* Adds a specified delta value to the current count value and returns the | |
* updated `Count` instance. | |
* | |
* @param {number} delta - The amount to add to the current count value. | |
* @returns {Count} The `Count` instance, updated with the new count value. | |
*/ | |
add(delta) { | |
this.value += delta | |
return this | |
} | |
/** | |
* Subtracts a specified delta value from the current count value and returns | |
* the updated `Count` instance. | |
* | |
* @param {number} delta - The amount to subtract from the current count value. | |
* @returns {Count} The `Count` instance, updated with the new count value. | |
*/ | |
sub(delta) { | |
this.value -= delta | |
return this | |
} | |
/** | |
* Multiplies the current count value by a specified delta value and returns the | |
* updated `Count` instance. | |
* | |
* @param {number} delta - The factor to multiply the current count value by. | |
* @returns {Count} The `Count` instance, updated with the new count value. | |
*/ | |
multiply(delta) { | |
this.value *= delta | |
return this | |
} | |
/** | |
* Divides the current count value by a specified delta value and returns the | |
* updated `Count` instance. | |
* | |
* @param {number} delta - The divisor to divide the current count value by. | |
* @returns {Count} The `Count` instance, updated with the new count value. | |
*/ | |
divide(delta) { | |
this.value /= delta | |
return this | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Ticker } from './ticker.js' | |
/** | |
* LiminalTicker extends the Ticker class, providing enhanced functionality with | |
* threshold monitoring and callback execution. It is designed to trigger a callback | |
* when its value reaches or surpasses a specified threshold. The class allows for | |
* customizable threshold comparison logic and callback functions, making it flexible | |
* for various use cases. | |
*/ | |
class LiminalTicker extends Ticker { | |
/** | |
* Constructs a LiminalTicker object with initial value, threshold, and callback | |
* functions. | |
* | |
* @param {any} initialValue - The initial value of the ticker. While it defaults | |
* to 0, it can be set to any type, depending on the intended use of the ticker. | |
* @param {any} threshold - The threshold value to trigger the callback. The type | |
* should be compatible with the type of initialValue for proper comparison. | |
* @param {Function} thresholdCallback - A function to be called when the ticker | |
* value meets or exceeds the threshold. It defaults to a no-operation function | |
* if not provided. | |
* @param {Function} thresholdMet - A predicate function that determines if the | |
* threshold condition is met. It receives the current value and the threshold | |
* as arguments and returns a boolean. By default, it checks if value is greater | |
* than or equal to the threshold, suitable for numeric comparisons. | |
*/ | |
constructor( | |
initialValue = 0, | |
threshold = 0, | |
thresholdCallback = function() {}, | |
thresholdMet = (value, threshold) => value >= threshold | |
) { | |
super(initialValue); | |
this.threshold = threshold; | |
// Bind the callbacks if they're functions | |
this.thresholdCallback = typeof thresholdCallback === 'function' | |
? thresholdCallback.bind(this) | |
: function() {}; | |
this.thresholdMet = typeof thresholdMet === 'function' | |
? thresholdMet.bind(this) | |
: (value, threshold) => value >= threshold; | |
// Override the value property | |
Object.defineProperty(this, 'value', { | |
get: () => this._value, | |
set: (newValue) => { | |
this._value = newValue; | |
this.checkThreshold(); | |
}, | |
configurable: true, | |
enumerable: true | |
}); | |
this.value = initialValue; | |
} | |
/** | |
* Checks whether the current ticker value meets or exceeds the threshold. If the | |
* condition is met and the threshold callback has not been previously triggered, the | |
* callback function is executed. The callback will not be triggered again until the | |
* value falls below the threshold and then meets or exceeds it again. | |
*/ | |
checkThreshold() { | |
if (this.thresholdMet(this.value, this.threshold)) { | |
this.thresholdCallback(this.value, this.threshold); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Ticker } from './ticker.js' | |
/** | |
* The `Strings` class extends the `Ticker` class to manipulate an array of strings. | |
* It provides methods for adding, removing, and joining strings with a separator. | |
*/ | |
export class Strings extends Ticker { | |
/** | |
* Constructs a `Strings` object with an initial array of strings. | |
* | |
* @param {...string} strings - An array of strings to initialize the `Strings` object. | |
*/ | |
constructor(...strings) { | |
super( | |
[...strings], | |
function increment(string) { this.value.push(string) }, | |
function decrement(string) { | |
if (this.value.includes(string)) | |
this.value.splice(this.value.indexOf(string), 1) | |
else | |
this.value.pop() | |
}, | |
function reset() { this.value = this.initialValue }, | |
function primitive() { return this.value.join(this.separator ?? '') } | |
) | |
this.separator = '' | |
} | |
/** | |
* Sets a separator string for joining the internal array of strings. | |
* | |
* @param {string} separator - The separator string to use for joining. | |
* @returns {Strings} The `Strings` instance, to allow method chaining. | |
*/ | |
setSeparator(separator) { | |
this.separator = separator | |
return this | |
} | |
/** | |
* Adds one or more strings to the end of the internal array. | |
* | |
* @param {...string} args - The strings to add to the array. | |
* @returns {Strings} The `Strings` instance, to allow method chaining. | |
*/ | |
push(...args) { | |
this.value.push(...args) | |
return this | |
} | |
/** | |
* Retrieves the last string in the internal array. | |
* | |
* @type {string} - The last string in the array. | |
*/ | |
get last() { | |
return this.value[this.value.length - 1] | |
} | |
/** | |
* Retrieves the first string in the internal array. | |
* | |
* @type {string} - The first string in the array. | |
*/ | |
get first() { | |
return this.value[0] | |
} | |
/** | |
* Overrides the `Symbol.toStringTag` to return the class name when converted to | |
* a string. Useful for debugging and logging. | |
* | |
* @type {string} - The class name. | |
*/ | |
get [Symbol.toStringTag]() { | |
return this.constructor.name | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* The Ticker class is a customizable counter that can be incremented, decremented, | |
* reset, and converted to a primitive value. | |
*/ | |
class Ticker { | |
/** | |
* Creates a quick ticker object that can be used to keep track of counts. Think of it | |
* like a stopwatch that can be started, stopped, and reset. If the value is not a | |
* number, you can also supply custom functions that handle the incrementing, | |
* decrementing, and resetting of the value. If a primitive constructor is supplied, | |
* the value will be converted to that type when it is converted to a primitive value. | |
* | |
* Notable for customizations is that if non big-arrow functions are supplied to | |
* incrementer, decrementer, or resetter, they will be bound to the ticker object | |
* instance before being invoked. Additionally any parameters passed to the functions | |
* tick, increment, decrement, or reset will be passed to the customized functions | |
* when executed. | |
* | |
* @param [value=0] - The initial value of the object. It defaults to 0 if no | |
* value is provided. | |
* @param [incrementer] - The incrementer parameter is a function that increases | |
* the value of the "value" property by 1. | |
* @param [decrementer] - The `decrementer` parameter is a function that | |
* decreases the value of the `value` property by 1. | |
* @param [resetter] - The `resetter` parameter is a function that sets the | |
* `value` property of the object to 0. | |
* @param [primitive] - The "primitive" parameter is a reference to the Number | |
* constructor function. It is used to specify the type of the "value" property. | |
* By default, it is set to the Number constructor function, but you can pass any | |
* other constructor function for a different type, such as String or Boolean. | |
*/ | |
constructor( | |
value = 0, | |
incrementer = function increment() { this.value += 1 }, | |
decrementer = function decrement() { this.value -= 1 }, | |
resetter = function reset() { this.value = this.initialValue }, | |
primitive = undefined | |
) { | |
Object.assign(this, { | |
value, | |
initialValue: value, | |
incrementer, | |
decrementer, | |
resetter, | |
primitive | |
}) | |
if (!this.primitive) { | |
this.primitive = Ticker.detectPrimitive(value) | |
} | |
} | |
static detectPrimitive(fromValue) { | |
if (typeof fromValue === 'number') { | |
this.primitive = Number | |
} else if (typeof fromValue === 'string') { | |
this.primitive = String | |
} | |
} | |
/** | |
* The tick function calls the incrementer function and returns the current | |
* object. | |
* | |
* @param args - The "args" parameter is a rest parameter that allows the | |
* function to accept any number of arguments as an array. | |
* @returns The `tick` method is returning the current instance of the object | |
* (`this`). | |
*/ | |
tick(...args) { | |
this.incrementer.bind(this)(...args); | |
return this; | |
} | |
/** | |
* The increment function takes in any number of arguments, binds the incrementer | |
* function to the current object, and then returns the object itself. | |
* | |
* @param args - The "args" parameter is a rest parameter that allows the | |
* function to accept any number of arguments as an array. | |
* @returns the object on which it is called. | |
*/ | |
increment(...args) { | |
this.incrementer.bind(this)(...args); | |
return this; | |
} | |
/** | |
* The "decrement" function binds the "decrementer" function to the current | |
* object and then returns the object itself. | |
* | |
* @param args - args is a rest parameter that allows the function to accept any | |
* number of arguments as an array. | |
* @returns The "this" object is being returned. | |
*/ | |
decrement(...args) { | |
this.decrementer.bind(this)(...args); | |
return this; | |
} | |
/** | |
* The "reset" function is a method that resets the state of an object and | |
* returns the object itself. | |
* | |
* @param args - The "args" parameter is a rest parameter that allows the | |
* function to accept any number of arguments as an array. | |
* @returns The `reset` method is returning the instance of the object on which | |
* it is called. | |
*/ | |
reset(...args) { | |
this.resetter.bind(this)(...args); | |
return this; | |
} | |
/** | |
* The above function returns the name of the constructor of an object. | |
* | |
* @returns The name of the constructor function. | |
*/ | |
get [Symbol.toStringTag]() { | |
return this.constructor.name | |
} | |
/** | |
* The above function defines a method that converts an object to a primitive | |
* value. | |
* | |
* @param hint - The `hint` parameter is a string that indicates the preferred | |
* type of the conversion. It can have one of the following values: | |
* @returns The `primitive` value of `this.value`. | |
*/ | |
[Symbol.toPrimitive](hint) { | |
return (this.primitive ?? Number)(this.value) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment