diff --git a/CHANGELOG b/CHANGELOG index ccaede8..9ae13a1 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,6 @@ +## v0.5.0 (28.05.2023) + * Implement new CONFIG action to allow overriding configuration without starting the timer. + ## v0.4.1 (27.05.2023) * Bugfix: When the timer was in a paused state and received an override configuration, it failed to update the visible timer progress. diff --git a/package-lock.json b/package-lock.json index 3170027..232644d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "node-red-contrib-controltimer", - "version": "0.4.1", + "version": "0.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "node-red-contrib-controltimer", - "version": "0.4.1", + "version": "0.5.0", "license": "MIT", "devDependencies": { "@types/ejs": "^3.1.1", @@ -205,9 +205,9 @@ } }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { "ansi-regex": "^6.0.1" @@ -1334,9 +1334,9 @@ } }, "node_modules/boxen/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { "ansi-regex": "^6.0.1" @@ -5949,9 +5949,9 @@ } }, "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, "dependencies": { "ansi-regex": "^6.0.1" diff --git a/package.json b/package.json index 7d8aaa6..6277ecd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red-contrib-controltimer", - "version": "0.4.1", + "version": "0.5.0", "description": "A controllable Node-RED timer node. Start, Stop, Reset, Pause and Continue the timer. Use the timer as a loop or a delay.", "scripts": { "build": "scripty", diff --git a/src/controltimer.ejs b/src/controltimer.ejs index dcd8f7b..9f403f7 100644 --- a/src/controltimer.ejs +++ b/src/controltimer.ejs @@ -39,6 +39,7 @@ isResetActionEnabled: { value: <%= defaults.isResetActionEnabled %> }, isPauseActionEnabled: { value: <%= defaults.isPauseActionEnabled %> }, isContinueActionEnabled: { value: <%= defaults.isContinueActionEnabled %> }, + isConfigActionEnabled: { value: <%= defaults.isConfigActionEnabled %> }, actionPropertyNameType: { value: '<%= defaults.actionPropertyNameType %>' }, actionPropertyName: { value: '<%= defaults.actionPropertyName %>', required: true, validate: RED.validators.typedInput('actionPropertyNameType') }, startActionNameType: { value: '<%= defaults.startActionNameType %>' }, @@ -51,12 +52,14 @@ pauseActionName: { value: '<%= defaults.pauseActionName %>', required: true, validate: RED.validators.typedInput('pauseActionNameType') }, continueActionNameType: { value: '<%= defaults.continueActionNameType %>' }, continueActionName: { value: '<%= defaults.continueActionName %>', required: true, validate: RED.validators.typedInput('continueActionNameType') }, + configActionNameType: { value: '<%= defaults.configActionNameType %>' }, + configActionName: { value: '<%= defaults.configActionName %>', required: true, validate: RED.validators.typedInput('configActionNameType') }, }, inputs: 1, outputs: 2, icon: "controltimer.png", label: function () { - return this.name || `${this.timerDuration} ${this.timerDurationUnit} ${this.timerType === '<%= TIMER_TYPE.DELAY %>' ? '<%= TIMER_TYPE.DELAY %>' : '<%= TIMER_TYPE.LOOP %>'}`; + return this.name || `${this.timerDuration} ${this.timerDurationUnit} ${this.timerType === '<%= TimerType.DELAY %>' ? '<%= TimerType.DELAY %>' : '<%= TimerType.LOOP %>'}`; }, labelStyle: function () { return this.name ? 'node_label_italic' : ''; @@ -166,12 +169,14 @@ initializeNodeRedCheckbox('isResetActionEnabled'); initializeNodeRedCheckbox('isPauseActionEnabled'); initializeNodeRedCheckbox('isContinueActionEnabled'); + initializeNodeRedCheckbox('isConfigActionEnabled'); initializeNodeRedTypedTextInput('actionPropertyName', ['str']); initializeNodeRedTypedTextInput('startActionName', ['str']); initializeNodeRedTypedTextInput('stopActionName', ['str']); initializeNodeRedTypedTextInput('resetActionName', ['str']); initializeNodeRedTypedTextInput('pauseActionName', ['str']); initializeNodeRedTypedTextInput('continueActionName', ['str']); + initializeNodeRedTypedTextInput('configActionName', ['str']); } initializeInputs(); @@ -180,11 +185,11 @@ $('#node-input-timerType').change(() => { const selectedTimerType = $('#node-input-timerType').val(); - if (selectedTimerType === '<%= TIMER_TYPE.LOOP %>') { + if (selectedTimerType === '<%= TimerType.LOOP %>') { $('.loop-options').show(); } - if (selectedTimerType === '<%= TIMER_TYPE.DELAY %>') { + if (selectedTimerType === '<%= TimerType.DELAY %>') { $('.loop-options').hide(); } }); @@ -225,6 +230,7 @@ this.isStopActionEnabled = elementDefaults.isStopActionEnabled; this.isPauseActionEnabled = elementDefaults.isPauseActionEnabled; this.isContinueActionEnabled = elementDefaults.isContinueActionEnabled; + this.isConfigActionEnabled = elementDefaults.isConfigActionEnabled; this.actionPropertyNameType = elementDefaults.actionPropertyNameType; this.actionPropertyName = elementDefaults.actionPropertyName; this.startActionNameType = elementDefaults.startActionNameType; @@ -237,6 +243,8 @@ this.pauseActionName = elementDefaults.pauseActionName; this.continueActionNameType = elementDefaults.continueActionNameType; this.continueActionName = elementDefaults.continueActionName; + this.configActionNameType = elementDefaults.configActionNameType; + this.configActionName = elementDefaults.configActionName; initializeInputs(); }); @@ -289,6 +297,7 @@ this.isStopActionEnabled = $('#node-input-isStopActionEnabled').is(":checked"); this.isPauseActionEnabled = $('#node-input-isPauseActionEnabled').is(":checked"); this.isContinueActionEnabled = $('#node-input-isContinueActionEnabled').is(":checked"); + this.isConfigActionEnabled = $('#node-input-isConfigActionEnabled').is(":checked"); this.actionPropertyNameType = $('#node-input-actionPropertyNameType').val(); this.actionPropertyName = $('#node-input-actionPropertyName').val(); this.startActionNameType = $('#node-input-startActionNameType').val(); @@ -301,6 +310,8 @@ this.pauseActionName = $('#node-input-pauseActionName').val(); this.continueActionNameType = $('#node-input-continueActionNameType').val(); this.continueActionName = $('#node-input-continueActionName').val(); + this.configActionNameType = $('#node-input-configActionNameType').val(); + this.configActionName = $('#node-input-configActionName').val(); }, }); @@ -386,8 +397,8 @@
@@ -573,6 +584,13 @@ +
+ +
+ +
+
+
@@ -608,6 +626,12 @@
+ +
+ + + +
diff --git a/src/controltimer.ts b/src/controltimer.ts index 0549801..eaf1511 100644 --- a/src/controltimer.ts +++ b/src/controltimer.ts @@ -1,7 +1,7 @@ import { Node, NodeAPI, NodeMessageInFlow } from 'node-red'; import { constants, ControlTimerNodeDef, nodeName } from './node-config'; -import { STATE, Timer } from './timer'; +import { State, Timer } from './timer'; type NodeMessage = NodeMessageInFlow; @@ -27,25 +27,25 @@ module.exports = function (RED: NodeAPI): void { }); timer.on('state', ({ state, progress }) => { - if (state === STATE.IDLE) { + if (state === State.IDLE) { node.status({ fill: 'grey', shape: 'ring', text: 'Idle' }); } - if (state === STATE.RUNNING) { + if (state === State.RUNNING) { node.status({ fill: 'green', shape: 'dot', text: `Running${progress}` }); } - if (state === STATE.STOPPED) { + if (state === State.STOPPED) { node.status({ fill: 'red', shape: 'dot', text: 'Stopped' }); } - if (state === STATE.PAUSED) { + if (state === State.PAUSED) { node.status({ fill: 'yellow', shape: 'dot', text: `Paused${progress}` }); } }); - timer.on(STATE.STOPPED, () => node.send([null, getHaltedMessage()])); - timer.on(STATE.PAUSED, () => node.send([null, getHaltedMessage()])); + timer.on(State.STOPPED, () => node.send([null, getHaltedMessage()])); + timer.on(State.PAUSED, () => node.send([null, getHaltedMessage()])); timer.on('timer', () => node.send([getTriggerMessage(), null])); timer.on('loop-timeout', () => node.send([null, getMessage(config.loopTimeoutMessage)])); timer.on('loop-max-iterations', () => node.send([null, getMessage(config.loopMaxIterationsMessage)])); @@ -58,14 +58,27 @@ module.exports = function (RED: NodeAPI): void { const isPauseActionMessage = message[config.actionPropertyName] === config.pauseActionName && config.isPauseActionEnabled; const isContinueActionMessage = message[config.actionPropertyName] === config.continueActionName && config.isContinueActionEnabled; const isStopActionMessage = message[config.actionPropertyName] === config.stopActionName && config.isStopActionEnabled; - const isUnknownMessage = !(isStartActionMessage || isResetActionMessage || isPauseActionMessage || isContinueActionMessage || isStopActionMessage); + const isConfigActionMessage = message[config.actionPropertyName] === config.configActionName && config.isConfigActionEnabled; + const isUnknownMessage = !( + isStartActionMessage || + isResetActionMessage || + isPauseActionMessage || + isContinueActionMessage || + isStopActionMessage || + isConfigActionMessage + ); const timerTypeOverride = message[constants.timerTypeOverridePropertyName] ?? null; const timerDurationOverride = message[constants.timerDurationOverridePropertyName] ?? null; const timerDurationUnitOverride = message[constants.timerDurationUnitOverridePropertyName] ?? null; - const isOverrideMessage = timerTypeOverride !== null && timerDurationOverride !== null && timerDurationUnitOverride !== null; + const hasConfigOverride = timerTypeOverride !== null && timerDurationOverride !== null && timerDurationUnitOverride !== null; + + if (isConfigActionMessage && !hasConfigOverride) { + done(new Error('Config override not found or is invalid')); + return; + } - if (isStartActionMessage && isOverrideMessage) { + if (!isUnknownMessage && hasConfigOverride) { timer.setConfigOverride({ timerType: timerTypeOverride, duration: timerDurationOverride, @@ -73,29 +86,11 @@ module.exports = function (RED: NodeAPI): void { }); } - if (timer.getState() === STATE.PAUSED) { - if (isStartActionMessage && config.continueTimerOnReceivalOfStartAction) { - timer.continue(); - done(); - return; - } - } - - if (timer.getState() !== STATE.RUNNING) { - if (isStartActionMessage || (isUnknownMessage && config.startTimerOnReceivalOfUnknownMessage)) { - timer.start(); - done(); - return; - } - } - if ( - isResetActionMessage || - (isUnknownMessage && config.resetTimerOnReceivalOfUnknownMessage) || - (isStartActionMessage && config.resetTimerOnReceivalOfStartAction) || - (isStartActionMessage && isOverrideMessage) + (isStartActionMessage || (isUnknownMessage && config.startTimerOnReceivalOfUnknownMessage)) && + (timer.state === State.IDLE || timer.state === State.STOPPED) ) { - timer.reset(); + timer.start(); done(); return; } @@ -112,11 +107,22 @@ module.exports = function (RED: NodeAPI): void { return; } - if (isContinueActionMessage) { + if (isContinueActionMessage || (timer.state === State.PAUSED && isStartActionMessage && config.continueTimerOnReceivalOfStartAction)) { timer.continue(); done(); return; } + + if ( + isResetActionMessage || + (isUnknownMessage && config.resetTimerOnReceivalOfUnknownMessage) || + (isStartActionMessage && config.resetTimerOnReceivalOfStartAction) || + (isStartActionMessage && hasConfigOverride) + ) { + timer.reset(); + done(); + return; + } }); node.on('close', (done) => { diff --git a/src/node-config.ts b/src/node-config.ts index e11ea3f..5273903 100644 --- a/src/node-config.ts +++ b/src/node-config.ts @@ -1,6 +1,6 @@ import { NodeDef } from 'node-red'; -import { DurationUnit, TIMER_TYPE } from './timer'; +import { DurationUnit, TimerType } from './timer'; export const nodeName = 'controltimer'; export type ControlTimerNodeDef = NodeDef & Props; @@ -18,10 +18,11 @@ export type StopActionNameType = 'str'; export type ResetActionNameType = 'str'; export type PauseActionNameType = 'str'; export type ContinueActionNameType = 'str'; +export type ConfigActionNameType = 'str'; export interface Props { name: string; - timerType: TIMER_TYPE; + timerType: TimerType; timerDurationUnit: DurationUnit; timerDurationType: TimerDurationType; @@ -56,6 +57,7 @@ export interface Props { isResetActionEnabled: boolean; isPauseActionEnabled: boolean; isContinueActionEnabled: boolean; + isConfigActionEnabled: boolean; actionPropertyNameType: ActionPropertyNameType; actionPropertyName: string; startActionNameType: StartActionNameType; @@ -68,11 +70,13 @@ export interface Props { pauseActionName: string; continueActionNameType: ContinueActionNameType; continueActionName: string; + configActionNameType: ConfigActionNameType; + configActionName: string; } export const defaults: Props = { name: '', - timerType: TIMER_TYPE.DELAY, + timerType: TimerType.DELAY, timerDurationUnit: DurationUnit.SECOND, timerDurationType: 'num', @@ -107,6 +111,7 @@ export const defaults: Props = { isResetActionEnabled: true, isPauseActionEnabled: true, isContinueActionEnabled: true, + isConfigActionEnabled: true, actionPropertyNameType: 'str', actionPropertyName: 'payload', startActionNameType: 'str', @@ -119,6 +124,8 @@ export const defaults: Props = { pauseActionName: 'PAUSE', continueActionNameType: 'str', continueActionName: 'CONTINUE', + configActionNameType: 'str', + configActionName: 'CONFIG', }; export const constants = { diff --git a/src/render-html.ts b/src/render-html.ts index 106ed41..1d2411a 100644 --- a/src/render-html.ts +++ b/src/render-html.ts @@ -3,12 +3,12 @@ import * as fs from 'fs'; import * as path from 'path'; import { defaults, nodeName } from './node-config'; -import { DurationUnit, TIMER_TYPE } from './timer'; +import { DurationUnit, TimerType } from './timer'; (() => { const srcEjsPath = path.resolve('src/controltimer.ejs'); const ejsTemplate = fs.readFileSync(srcEjsPath, 'utf8'); - const nodeHtml = ejs.render(ejsTemplate, { defaults, nodeName, TIMER_TYPE, DurationUnit }); + const nodeHtml = ejs.render(ejsTemplate, { defaults, nodeName, TimerType, DurationUnit }); const distHtmlPath = path.resolve('dist/controltimer.html'); fs.writeFileSync(distHtmlPath, nodeHtml); })(); diff --git a/src/timer.ts b/src/timer.ts index c6ad26e..432a187 100644 --- a/src/timer.ts +++ b/src/timer.ts @@ -1,7 +1,7 @@ import { EventEmitter } from 'events'; import { clearInterval, clearTimeout } from 'timers'; -enum ACTION { +enum Action { START = 'START', STOP = 'STOP', RESET = 'RESET', @@ -9,14 +9,14 @@ enum ACTION { CONTINUE = 'CONTINUE', } -export enum STATE { +export enum State { IDLE = 'IDLE', RUNNING = 'RUNNING', STOPPED = 'STOPPED', PAUSED = 'PAUSED', } -export enum TIMER_TYPE { +export enum TimerType { LOOP = 'loop', DELAY = 'delay', } @@ -29,7 +29,7 @@ export enum DurationUnit { } interface TimerConfig { - timerType: TIMER_TYPE; + timerType: TimerType; duration: number; durationUnit: DurationUnit; isTimerProgressUpdateEnabled: boolean; @@ -40,7 +40,7 @@ interface TimerConfig { export class Timer extends EventEmitter { static defaultConfig: TimerConfig = { - timerType: TIMER_TYPE.DELAY, + timerType: TimerType.DELAY, duration: 5, durationUnit: DurationUnit.SECOND, isTimerProgressUpdateEnabled: true, @@ -49,6 +49,23 @@ export class Timer extends EventEmitter { timerLoopTimeoutUnit: DurationUnit.MILLISECOND, }; + static validateConfigOverride(configOverride: Pick) { + const { timerType, duration, durationUnit } = configOverride; + const isNil = (value: unknown) => value === undefined || value === null; + + if (isNil(timerType) || typeof timerType !== 'string' || !Object.values(TimerType).includes(timerType)) { + throw new Error('timerType is not valid'); + } + + if (isNil(duration) || !Number.isInteger(duration) || !Number.isFinite(duration) || duration <= 0) { + throw new Error('duration is not valid'); + } + + if (isNil(durationUnit) || typeof durationUnit !== 'string' || !Object.values(DurationUnit).includes(durationUnit)) { + throw new Error('durationUnit is not valid'); + } + } + static getInstance(config: TimerConfig) { return new Timer(config); } @@ -56,7 +73,7 @@ export class Timer extends EventEmitter { private config: TimerConfig = Timer.defaultConfig; private configOverride: Pick; - private currentState: STATE = STATE.IDLE; + private currentState: State = State.IDLE; private timerId: NodeJS.Timeout; private progressUpdateIntervalTimerId: NodeJS.Timeout; private stoppedTransitionToIdleTimeoutTimerId: NodeJS.Timeout; @@ -68,7 +85,7 @@ export class Timer extends EventEmitter { constructor(config: TimerConfig) { super(); this.config = config; // TODO: Validate config - this.setCurrentState(STATE.IDLE); + this.setCurrentState(State.IDLE); } // #################### @@ -76,23 +93,23 @@ export class Timer extends EventEmitter { // #################### public start() { - this.handleAction(ACTION.START); + this.handleAction(Action.START); } public stop() { - this.handleAction(ACTION.STOP); + this.handleAction(Action.STOP); } public reset() { - this.handleAction(ACTION.RESET); + this.handleAction(Action.RESET); } public pause() { - this.handleAction(ACTION.PAUSE); + this.handleAction(Action.PAUSE); } public continue() { - this.handleAction(ACTION.CONTINUE); + this.handleAction(Action.CONTINUE); } public hardReset() { @@ -101,7 +118,7 @@ export class Timer extends EventEmitter { } private softReset() { - this.currentState = STATE.IDLE; + this.currentState = State.IDLE; this.destroyTimers(); this.currentLoopIteration = 0; this.pausedTimerRunningMilliseconds = undefined; @@ -109,15 +126,16 @@ export class Timer extends EventEmitter { } public setConfigOverride(configOverride: Pick) { - this.configOverride = configOverride; // TODO: Validate configOverride + Timer.validateConfigOverride(configOverride); + this.configOverride = configOverride; this.emit('state', { state: this.currentState, - progress: this.currentState === STATE.PAUSED ? this.getPausedTimerProgress() : this.getRunningTimerProgress(), + progress: this.currentState === State.PAUSED ? this.getPausedTimerProgress() : this.getRunningTimerProgress(), }); } - public getState() { + public get state() { return this.currentState; } @@ -125,43 +143,43 @@ export class Timer extends EventEmitter { // ## Timer action handling ## // ########################### - private handleAction(action: ACTION) { - if (this.currentState === STATE.IDLE) { - if (action === ACTION.START) { + private handleAction(action: Action) { + if (this.currentState === State.IDLE) { + if (action === Action.START) { this.startTimer(); } } - if (this.currentState === STATE.RUNNING) { - if (action === ACTION.STOP) { + if (this.currentState === State.RUNNING) { + if (action === Action.STOP) { this.stopTimer(); } - if (action === ACTION.RESET) { + if (action === Action.RESET) { this.resetTimer(); } - if (action === ACTION.PAUSE) { + if (action === Action.PAUSE) { this.pauseTimer(); } } - if (this.currentState === STATE.STOPPED) { - if (action === ACTION.START) { + if (this.currentState === State.STOPPED) { + if (action === Action.START) { this.startTimer(); } } - if (this.currentState === STATE.PAUSED) { - if (action === ACTION.STOP) { + if (this.currentState === State.PAUSED) { + if (action === Action.STOP) { this.stopTimer(); } - if (action === ACTION.RESET) { + if (action === Action.RESET) { this.resetTimer(); } - if (action === ACTION.CONTINUE) { + if (action === Action.CONTINUE) { this.continueTimer(); } } @@ -174,20 +192,20 @@ export class Timer extends EventEmitter { private startTimer() { this.softReset(); this.timerId = this.createAndGetTimer(); - this.setCurrentState(STATE.RUNNING, this.getRunningTimerProgress()); + this.setCurrentState(State.RUNNING, this.getRunningTimerProgress()); this.startProgressUpdateTimer(); } private stopTimer() { this.hardReset(); - this.setCurrentState(STATE.STOPPED); + this.setCurrentState(State.STOPPED); this.startStoppedTransitionToIdleTimer(); } private resetTimer() { this.softReset(); this.timerId = this.createAndGetTimer(); - this.setCurrentState(STATE.RUNNING, this.getRunningTimerProgress()); + this.setCurrentState(State.RUNNING, this.getRunningTimerProgress()); this.startProgressUpdateTimer(); } @@ -196,18 +214,18 @@ export class Timer extends EventEmitter { const previousRunningDurationInMilliseconds = this.pausedTimerRunningMilliseconds ?? 0; this.pausedTimerRunningMilliseconds = Date.now() - this.timerStartedAtUnixTimestamp + previousRunningDurationInMilliseconds; this.timerStartedAtUnixTimestamp = undefined; - this.setCurrentState(STATE.PAUSED, this.getPausedTimerProgress()); + this.setCurrentState(State.PAUSED, this.getPausedTimerProgress()); } private continueTimer() { this.timerId = this.createAndGetTimer(this.timerDurationInMilliseconds - this.pausedTimerRunningMilliseconds); - this.setCurrentState(STATE.RUNNING, this.getRunningTimerProgress()); + this.setCurrentState(State.RUNNING, this.getRunningTimerProgress()); this.startProgressUpdateTimer(); } private finishTimer() { this.hardReset(); - this.setCurrentState(STATE.IDLE); + this.setCurrentState(State.IDLE); } // ########################### @@ -217,7 +235,7 @@ export class Timer extends EventEmitter { private createAndGetTimer(durationInMillisecondsOverride?: number) { const durationInMilliseconds = durationInMillisecondsOverride ?? this.timerDurationInMilliseconds; - if ((this.config.timerType === TIMER_TYPE.LOOP && !this.configOverride) || this.configOverride?.timerType === TIMER_TYPE.LOOP) { + if ((this.config.timerType === TimerType.LOOP && !this.configOverride) || this.configOverride?.timerType === TimerType.LOOP) { this.pausedTimerRunningMilliseconds = durationInMillisecondsOverride ? this.pausedTimerRunningMilliseconds : undefined; this.timerStartedAtUnixTimestamp = Date.now(); @@ -242,7 +260,7 @@ export class Timer extends EventEmitter { }, durationInMilliseconds); } - if ((this.config.timerType === TIMER_TYPE.DELAY && !this.configOverride) || this.configOverride?.timerType === TIMER_TYPE.DELAY) { + if ((this.config.timerType === TimerType.DELAY && !this.configOverride) || this.configOverride?.timerType === TimerType.DELAY) { this.pausedTimerRunningMilliseconds = durationInMillisecondsOverride ? this.pausedTimerRunningMilliseconds : undefined; this.timerStartedAtUnixTimestamp = Date.now(); @@ -295,7 +313,7 @@ export class Timer extends EventEmitter { } this.progressUpdateIntervalTimerId = setInterval(() => { - this.setCurrentState(STATE.RUNNING, this.getRunningTimerProgress()); + this.setCurrentState(State.RUNNING, this.getRunningTimerProgress()); }, 50); } @@ -303,7 +321,7 @@ export class Timer extends EventEmitter { clearTimeout(this.stoppedTransitionToIdleTimeoutTimerId); this.stoppedTransitionToIdleTimeoutTimerId = undefined; - if (this.currentState !== STATE.STOPPED) { + if (this.currentState !== State.STOPPED) { return; } @@ -316,7 +334,7 @@ export class Timer extends EventEmitter { // ## Other utility functions ## // ############################# - private setCurrentState(state: STATE, progress = '') { + private setCurrentState(state: State, progress = '') { this.currentState = state; this.emit('state', { state, progress }); this.emit(state);