Compare commits
44 Commits
Author | SHA1 | Date | |
---|---|---|---|
d789eec558 | |||
22027d2308 | |||
87d29fbb50 | |||
1c5a1c21da | |||
969088ad04 | |||
76768a1307 | |||
419fe80bde | |||
5a9584917c | |||
2b21ee9a24 | |||
3a110c9fd9 | |||
25f7ad37ae | |||
992d167a34 | |||
cfcfde2132 | |||
b5ab945501 | |||
88378e2f31 | |||
db92311daa | |||
36bff0a70a | |||
fa8fd9fa35 | |||
dd783b455f | |||
996685e7fb | |||
110b2c00cf | |||
c8b455b8e2 | |||
d16fd8b69b | |||
f7ed88cd57 | |||
19b5ba4a5d | |||
457182a97a | |||
a7a961c869 | |||
f1d7771e30 | |||
ff16b70206 | |||
8e43ce7e9b | |||
f129ce42b6 | |||
56a802664f | |||
743c9fb847 | |||
ac2edd6d74 | |||
725102d02c | |||
7c73579c9f | |||
a1996ea1bd | |||
dc92ae7140 | |||
3e862f233c | |||
73f7360f8c | |||
2c74de8aef | |||
78498626ea | |||
b2299b149a | |||
885b2432a8 |
@ -19,23 +19,35 @@ mirror:
|
|||||||
stage: security
|
stage: security
|
||||||
script:
|
script:
|
||||||
- npmci git mirror
|
- npmci git mirror
|
||||||
|
only:
|
||||||
|
- tags
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
- lossless
|
||||||
- docker
|
- docker
|
||||||
- notpriv
|
- notpriv
|
||||||
|
|
||||||
audit:
|
auditProductionDependencies:
|
||||||
|
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
||||||
|
stage: security
|
||||||
|
script:
|
||||||
|
- npmci npm prepare
|
||||||
|
- npmci command npm install --production --ignore-scripts
|
||||||
|
- npmci command npm config set registry https://registry.npmjs.org
|
||||||
|
- npmci command npm audit --audit-level=high --only=prod --production
|
||||||
|
tags:
|
||||||
|
- docker
|
||||||
|
|
||||||
|
auditDevDependencies:
|
||||||
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
||||||
stage: security
|
stage: security
|
||||||
script:
|
script:
|
||||||
- npmci npm prepare
|
- npmci npm prepare
|
||||||
- npmci command npm install --ignore-scripts
|
- npmci command npm install --ignore-scripts
|
||||||
- npmci command npm config set registry https://registry.npmjs.org
|
- npmci command npm config set registry https://registry.npmjs.org
|
||||||
- npmci command npm audit --audit-level=high
|
- npmci command npm audit --audit-level=high --only=dev
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
|
||||||
- docker
|
- docker
|
||||||
- notpriv
|
allow_failure: true
|
||||||
|
|
||||||
# ====================
|
# ====================
|
||||||
# test stage
|
# test stage
|
||||||
@ -50,9 +62,7 @@ testStable:
|
|||||||
- npmci npm test
|
- npmci npm test
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
coverage: /\d+.?\d+?\%\s*coverage/
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
|
||||||
- docker
|
- docker
|
||||||
- priv
|
|
||||||
|
|
||||||
testBuild:
|
testBuild:
|
||||||
stage: test
|
stage: test
|
||||||
@ -63,9 +73,7 @@ testBuild:
|
|||||||
- npmci command npm run build
|
- npmci command npm run build
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
coverage: /\d+.?\d+?\%\s*coverage/
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
|
||||||
- docker
|
- docker
|
||||||
- notpriv
|
|
||||||
|
|
||||||
release:
|
release:
|
||||||
stage: release
|
stage: release
|
||||||
@ -85,6 +93,8 @@ release:
|
|||||||
codequality:
|
codequality:
|
||||||
stage: metadata
|
stage: metadata
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
only:
|
||||||
|
- tags
|
||||||
script:
|
script:
|
||||||
- npmci command npm install -g tslint typescript
|
- npmci command npm install -g tslint typescript
|
||||||
- npmci npm prepare
|
- npmci npm prepare
|
||||||
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -15,7 +15,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"projectType": {
|
"projectType": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["website", "element", "service", "npm"]
|
"enum": ["website", "element", "service", "npm", "wcc"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
25937
package-lock.json
generated
25937
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
35
package.json
35
package.json
@ -1,32 +1,34 @@
|
|||||||
{
|
{
|
||||||
"name": "@pushrocks/smarttime",
|
"name": "@pushrocks/smarttime",
|
||||||
"private": false,
|
"private": false,
|
||||||
"version": "3.0.19",
|
"version": "3.0.41",
|
||||||
"description": "handle time in smart ways",
|
"description": "handle time in smart ways",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
"typings": "dist_ts/index.d.ts",
|
"typings": "dist_ts/index.d.ts",
|
||||||
"author": "Lossless GmbH",
|
"author": "Lossless GmbH",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "(tstest ./test/)",
|
"test": "(tstest ./test)",
|
||||||
"build": "(tsbuild && tsbundle npm)"
|
"build": "(tsbuild --web && tsbundle npm)"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@gitzone/tsbuild": "^2.1.11",
|
"@gitzone/tsbuild": "^2.1.28",
|
||||||
"@gitzone/tsbundle": "^1.0.69",
|
"@gitzone/tsbundle": "^1.0.88",
|
||||||
"@gitzone/tsrun": "^1.2.6",
|
"@gitzone/tsrun": "^1.2.18",
|
||||||
"@gitzone/tstest": "^1.0.24",
|
"@gitzone/tstest": "^1.0.60",
|
||||||
"@pushrocks/tapbundle": "^3.0.9",
|
"@pushrocks/tapbundle": "^3.2.14",
|
||||||
"@types/node": "^14.0.5",
|
"@types/node": "^16.11.6",
|
||||||
"tslint": "^6.1.2",
|
"tslint": "^6.1.3",
|
||||||
"tslint-config-prettier": "^1.18.0"
|
"tslint-config-prettier": "^1.18.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@pushrocks/smartdelay": "^2.0.9",
|
"@pushrocks/lik": "^5.0.0",
|
||||||
"@pushrocks/smartpromise": "^3.0.2",
|
"@pushrocks/smartdelay": "^2.0.13",
|
||||||
"croner": "^1.1.23",
|
"@pushrocks/smartpromise": "^3.1.6",
|
||||||
"dayjs": "^1.8.27",
|
"croner": "^4.0.69",
|
||||||
"is-nan": "^1.3.0"
|
"dayjs": "^1.10.7",
|
||||||
|
"is-nan": "^1.3.2",
|
||||||
|
"pretty-ms": "^7.0.1"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/**/*",
|
"ts/**/*",
|
||||||
@ -39,5 +41,8 @@
|
|||||||
"cli.js",
|
"cli.js",
|
||||||
"npmextra.json",
|
"npmextra.json",
|
||||||
"readme.md"
|
"readme.md"
|
||||||
|
],
|
||||||
|
"browserslist": [
|
||||||
|
"last 1 chrome versions"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
22
readme.md
22
readme.md
@ -8,13 +8,20 @@ handle time in smart ways
|
|||||||
* [docs (typedoc)](https://pushrocks.gitlab.io/smarttime/)
|
* [docs (typedoc)](https://pushrocks.gitlab.io/smarttime/)
|
||||||
|
|
||||||
## Status for master
|
## Status for master
|
||||||
[](https://gitlab.com/pushrocks/smarttime/commits/master)
|
|
||||||
[](https://gitlab.com/pushrocks/smarttime/commits/master)
|
Status Category | Status Badge
|
||||||
[](https://www.npmjs.com/package/@pushrocks/smarttime)
|
-- | --
|
||||||
[](https://snyk.io/test/npm/@pushrocks/smarttime)
|
GitLab Pipelines | [](https://lossless.cloud)
|
||||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
GitLab Pipline Test Coverage | [](https://lossless.cloud)
|
||||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
npm | [](https://lossless.cloud)
|
||||||
[](https://prettier.io/)
|
Snyk | [](https://lossless.cloud)
|
||||||
|
TypeScript Support | [](https://lossless.cloud)
|
||||||
|
node Support | [](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
||||||
|
Code Style | [](https://lossless.cloud)
|
||||||
|
PackagePhobia (total standalone install weight) | [](https://lossless.cloud)
|
||||||
|
PackagePhobia (package size on registry) | [](https://lossless.cloud)
|
||||||
|
BundlePhobia (total size when bundled) | [](https://lossless.cloud)
|
||||||
|
Platform support | [](https://lossless.cloud) [](https://lossless.cloud)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -44,7 +51,6 @@ import { ExtendedDate } from '@pushrocks/smarttime'
|
|||||||
const myDate: Date = ExtendedDate.fromEuropeanDate('8.6.2018')
|
const myDate: Date = ExtendedDate.fromEuropeanDate('8.6.2018')
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Contribution
|
## Contribution
|
||||||
|
|
||||||
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
|
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
|
||||||
|
@ -5,7 +5,7 @@ import * as smarttime from '../ts/index';
|
|||||||
// Test TimeStamp class
|
// Test TimeStamp class
|
||||||
let testTimeStamp: smarttime.TimeStamp;
|
let testTimeStamp: smarttime.TimeStamp;
|
||||||
let testTimeStamp2: smarttime.TimeStamp;
|
let testTimeStamp2: smarttime.TimeStamp;
|
||||||
tap.test('should create valid testTimeStamp instance', async tools => {
|
tap.test('should create valid testTimeStamp instance', async (tools) => {
|
||||||
testTimeStamp = new smarttime.TimeStamp();
|
testTimeStamp = new smarttime.TimeStamp();
|
||||||
await tools.delayFor(2);
|
await tools.delayFor(2);
|
||||||
testTimeStamp2 = new smarttime.TimeStamp();
|
testTimeStamp2 = new smarttime.TimeStamp();
|
||||||
@ -23,7 +23,7 @@ tap.test('should have valid linuxtime', async () => {
|
|||||||
let testHrtMeasurement: smarttime.HrtMeasurement;
|
let testHrtMeasurement: smarttime.HrtMeasurement;
|
||||||
|
|
||||||
// Test HrtMeasurement
|
// Test HrtMeasurement
|
||||||
tap.test('should create valid HrtMeasurements', async tools => {
|
tap.test('should create valid HrtMeasurements', async (tools) => {
|
||||||
testHrtMeasurement = new smarttime.HrtMeasurement();
|
testHrtMeasurement = new smarttime.HrtMeasurement();
|
||||||
testHrtMeasurement.start();
|
testHrtMeasurement.start();
|
||||||
await tools.delayFor(20);
|
await tools.delayFor(20);
|
||||||
@ -41,7 +41,7 @@ tap.test('should combine units', async () => {
|
|||||||
weeks: 2,
|
weeks: 2,
|
||||||
days: 2,
|
days: 2,
|
||||||
hours: 2,
|
hours: 2,
|
||||||
minutes: 2
|
minutes: 2,
|
||||||
});
|
});
|
||||||
// tslint:disable-next-line:no-console
|
// tslint:disable-next-line:no-console
|
||||||
console.log(computedTime);
|
console.log(computedTime);
|
60
test/test.cronmanager.both.ts
Normal file
60
test/test.cronmanager.both.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { tap, expect } from '@pushrocks/tapbundle';
|
||||||
|
|
||||||
|
import * as smarttime from '../ts/index';
|
||||||
|
|
||||||
|
let testCronManager: smarttime.CronManager;
|
||||||
|
|
||||||
|
tap.test('should create a valid instance of cronmanager', async () => {
|
||||||
|
testCronManager = new smarttime.CronManager();
|
||||||
|
expect(testCronManager).to.be.instanceOf(smarttime.CronManager);
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('should create a valid cronJon', async (tools) => {
|
||||||
|
const done = tools.defer();
|
||||||
|
const done2 = tools.defer();
|
||||||
|
const done3 = tools.defer();
|
||||||
|
let counter = 0;
|
||||||
|
let counter2 = 0;
|
||||||
|
let counter3 = 0;
|
||||||
|
const cronJob = testCronManager.addCronjob('*/2 * * * * *', async () => {
|
||||||
|
if (counter === 5) {
|
||||||
|
testCronManager.removeCronjob(cronJob);
|
||||||
|
done.resolve();
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
console.log(`${new Date().getSeconds()} hey ${counter} -> runs every 2 seconds`);
|
||||||
|
});
|
||||||
|
const cronJob2 = testCronManager.addCronjob('*/3 * * * * *', async () => {
|
||||||
|
if (counter2 === 5) {
|
||||||
|
testCronManager.removeCronjob(cronJob2);
|
||||||
|
done2.resolve();
|
||||||
|
}
|
||||||
|
counter2++;
|
||||||
|
console.log(`${new Date().getSeconds()} hey ${counter2} -> runs every 3 seconds`);
|
||||||
|
});
|
||||||
|
const cronJob3 = testCronManager.addCronjob('*/4 * * * * *', async () => {
|
||||||
|
if (counter3 === 5) {
|
||||||
|
done3.resolve();
|
||||||
|
}
|
||||||
|
counter3++;
|
||||||
|
console.log(`${new Date().getSeconds()} hey ${counter3} -> runs every 4 seconds`);
|
||||||
|
});
|
||||||
|
testCronManager.start();
|
||||||
|
await done.promise;
|
||||||
|
await done2.promise;
|
||||||
|
await done3.promise;
|
||||||
|
testCronManager.stop();
|
||||||
|
testCronManager.removeCronjob(cronJob3);
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.test('runs every full minute', async (tools) => {
|
||||||
|
const done = tools.defer();
|
||||||
|
const cronJob = testCronManager.addCronjob('0 * * * * *', async () => {
|
||||||
|
done.resolve();
|
||||||
|
});
|
||||||
|
testCronManager.start();
|
||||||
|
await done.promise;
|
||||||
|
testCronManager.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.start();
|
@ -1,27 +0,0 @@
|
|||||||
import { tap, expect } from '@pushrocks/tapbundle';
|
|
||||||
|
|
||||||
import * as smarttime from '../ts/index';
|
|
||||||
|
|
||||||
let testCronManager: smarttime.CronManager;
|
|
||||||
|
|
||||||
tap.test('should create a valid instance of cronmanager', async () => {
|
|
||||||
testCronManager = new smarttime.CronManager();
|
|
||||||
expect(testCronManager).to.be.instanceOf(smarttime.CronManager);
|
|
||||||
});
|
|
||||||
|
|
||||||
tap.test('should create a valid cronJon', async tools => {
|
|
||||||
const done = tools.defer();
|
|
||||||
let counter = 0;
|
|
||||||
testCronManager.addCronjob('*/2 * * * * *', () => {
|
|
||||||
if (counter === 10) {
|
|
||||||
done.resolve();
|
|
||||||
}
|
|
||||||
counter++;
|
|
||||||
console.log(`hey ${counter}`);
|
|
||||||
});
|
|
||||||
testCronManager.start();
|
|
||||||
await done.promise;
|
|
||||||
testCronManager.stop();
|
|
||||||
});
|
|
||||||
|
|
||||||
tap.start();
|
|
@ -2,6 +2,11 @@ import { expect, tap } from '@pushrocks/tapbundle';
|
|||||||
|
|
||||||
import * as smarttime from '../ts/index';
|
import * as smarttime from '../ts/index';
|
||||||
|
|
||||||
|
tap.test('should create a valid JavaScript Date', async () => {
|
||||||
|
const extendedDate = new smarttime.ExtendedDate(Date.now());
|
||||||
|
console.log(extendedDate);
|
||||||
|
});
|
||||||
|
|
||||||
tap.test('should create a valid JavaScript Date from European TimeStamp', async () => {
|
tap.test('should create a valid JavaScript Date from European TimeStamp', async () => {
|
||||||
const extendedDate = smarttime.ExtendedDate.fromEuropeanDate('1.6.2018');
|
const extendedDate = smarttime.ExtendedDate.fromEuropeanDate('1.6.2018');
|
||||||
console.log(extendedDate);
|
console.log(extendedDate);
|
||||||
@ -21,4 +26,9 @@ tap.test('should create a European date string', async () => {
|
|||||||
expect(extendedDate.exportToEuropeanDate()).to.equal('13.02.2018');
|
expect(extendedDate.exportToEuropeanDate()).to.equal('13.02.2018');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tap.test('should format a date', async () => {
|
||||||
|
const extendedDate = new smarttime.ExtendedDate(Date.now());
|
||||||
|
console.log(extendedDate.format('YYYY-MM-DD - hh:mm'));
|
||||||
|
})
|
||||||
|
|
||||||
tap.start();
|
tap.start();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
export * from './smarttime.classes.cronmanager';
|
export * from './smarttime.classes.cronmanager';
|
||||||
|
export * from './smarttime.classes.cronjob';
|
||||||
export * from './smarttime.classes.extendeddate';
|
export * from './smarttime.classes.extendeddate';
|
||||||
export * from './smarttime.classes.hrtmeasurement';
|
export * from './smarttime.classes.hrtmeasurement';
|
||||||
export * from './smarttime.classes.interval';
|
export * from './smarttime.classes.interval';
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import * as plugins from './smarttime.plugins';
|
import * as plugins from './smarttime.plugins';
|
||||||
import { CronManager } from './smarttime.classes.cronmanager';
|
import { CronManager } from './smarttime.classes.cronmanager';
|
||||||
|
|
||||||
|
import { CronParser } from './smarttime.classes.cronparser';
|
||||||
|
|
||||||
export type TJobFunction = (() => void) | (() => Promise<any>);
|
export type TJobFunction = (() => void) | (() => Promise<any>);
|
||||||
|
|
||||||
export class CronJob {
|
export class CronJob {
|
||||||
public croner;
|
public cronParser: CronParser | typeof plugins.croner;
|
||||||
public status: 'started' | 'stopped' | 'initial' = 'initial';
|
public status: 'started' | 'stopped' | 'initial' = 'initial';
|
||||||
public cronExpression: string;
|
public cronExpression: string;
|
||||||
public jobFunction: TJobFunction;
|
public jobFunction: TJobFunction;
|
||||||
@ -13,7 +15,7 @@ export class CronJob {
|
|||||||
constructor(cronManager: CronManager, cronExpressionArg: string, jobFunction: TJobFunction) {
|
constructor(cronManager: CronManager, cronExpressionArg: string, jobFunction: TJobFunction) {
|
||||||
this.cronExpression = cronExpressionArg;
|
this.cronExpression = cronExpressionArg;
|
||||||
this.jobFunction = jobFunction;
|
this.jobFunction = jobFunction;
|
||||||
this.croner = plugins.croner(this.cronExpression);
|
this.cronParser = plugins.croner(cronExpressionArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -21,15 +23,29 @@ export class CronJob {
|
|||||||
*/
|
*/
|
||||||
public checkExecution(): number {
|
public checkExecution(): number {
|
||||||
if (this.nextExecutionUnix === 0) {
|
if (this.nextExecutionUnix === 0) {
|
||||||
this.nextExecutionUnix = this.croner.msToNext();
|
this.getNextExecutionTime();
|
||||||
}
|
}
|
||||||
if (Date.now() > this.nextExecutionUnix) {
|
if (Date.now() > this.nextExecutionUnix) {
|
||||||
this.jobFunction();
|
const maybePromise = this.jobFunction();
|
||||||
this.nextExecutionUnix = this.croner.msToNext();
|
if (maybePromise instanceof Promise) {
|
||||||
|
maybePromise.catch(e => console.log(e));
|
||||||
|
}
|
||||||
|
this.nextExecutionUnix = this.getNextExecutionTime();
|
||||||
}
|
}
|
||||||
return this.nextExecutionUnix;
|
return this.nextExecutionUnix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getNextExecutionTime() {
|
||||||
|
return this.nextExecutionUnix = Date.now() + this.getTimeToNextExecution();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gets the time to next execution
|
||||||
|
*/
|
||||||
|
public getTimeToNextExecution() {
|
||||||
|
return this.cronParser.msToNext();
|
||||||
|
}
|
||||||
|
|
||||||
public start() {
|
public start() {
|
||||||
this.status = 'started';
|
this.status = 'started';
|
||||||
}
|
}
|
||||||
|
@ -1,58 +1,84 @@
|
|||||||
import * as plugins from './smarttime.plugins';
|
import * as plugins from './smarttime.plugins';
|
||||||
import { CronJob } from './smarttime.classes.cronjob';
|
import { CronJob } from './smarttime.classes.cronjob';
|
||||||
|
import { getMilliSecondsAsHumanReadableString } from './smarttime.units';
|
||||||
|
|
||||||
export class CronManager {
|
export class CronManager {
|
||||||
public executionTimeout: plugins.smartdelay.Timeout<void>;
|
public executionTimeout: plugins.smartdelay.Timeout<void>;
|
||||||
|
|
||||||
public status: 'started' | 'stopped' = 'stopped';
|
public status: 'started' | 'stopped' = 'stopped';
|
||||||
public cronjobs: CronJob[] = [];
|
public cronjobs = new plugins.lik.ObjectMap<CronJob>();
|
||||||
|
|
||||||
constructor() {}
|
constructor() {}
|
||||||
|
|
||||||
public addCronjob(cronIdentifierArg: string, cronFunctionArg: () => any) {
|
public addCronjob(cronIdentifierArg: string, cronFunctionArg: () => Promise<void>) {
|
||||||
const newCronJob = new CronJob(this, cronIdentifierArg, cronFunctionArg);
|
const newCronJob = new CronJob(this, cronIdentifierArg, cronFunctionArg);
|
||||||
this.cronjobs.push(newCronJob);
|
this.cronjobs.add(newCronJob);
|
||||||
if (this.status === 'started') {
|
if (this.status === 'started') {
|
||||||
newCronJob.start();
|
newCronJob.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return newCronJob;
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeCronjob(cronjobArg: CronJob) {
|
||||||
|
cronjobArg.stop();
|
||||||
|
this.cronjobs.remove(cronjobArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* starts the cronjob
|
* starts the cronjob
|
||||||
*/
|
*/
|
||||||
public start() {
|
public start() {
|
||||||
this.status = 'started';
|
if (this.status !== 'started') {
|
||||||
for (const cronJob of this.cronjobs) {
|
this.status = 'started';
|
||||||
cronJob.start();
|
for (const cronJob of this.cronjobs.getArray()) {
|
||||||
}
|
cronJob.start();
|
||||||
this.executionTimeout = new plugins.smartdelay.Timeout(0);
|
}
|
||||||
|
const runCronCycle = async () => {
|
||||||
// recursion
|
this.executionTimeout = new plugins.smartdelay.Timeout(0);
|
||||||
const runCheckExecution = () => {
|
do {
|
||||||
console.log(`Next CronJob scheduled in ${this.executionTimeout.getTimeLeft()} milliseconds`);
|
let nextRunningCronjob: CronJob;
|
||||||
this.executionTimeout.promise.then(() => {
|
for (const cronJob of this.cronjobs.getArray()) {
|
||||||
let timeToNextOverallExecution: number;
|
cronJob.checkExecution();
|
||||||
for (const cronJob of this.cronjobs) {
|
if (
|
||||||
const timeToNextJobExecution = cronJob.checkExecution();
|
!nextRunningCronjob ||
|
||||||
if (timeToNextJobExecution < timeToNextOverallExecution || !timeToNextOverallExecution) {
|
cronJob.getTimeToNextExecution() < nextRunningCronjob.getTimeToNextExecution()
|
||||||
timeToNextOverallExecution = timeToNextJobExecution;
|
) {
|
||||||
|
nextRunningCronjob = cronJob;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nextRunningCronjob) {
|
||||||
|
this.executionTimeout = new plugins.smartdelay.Timeout(
|
||||||
|
nextRunningCronjob.getTimeToNextExecution()
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
`Next CronJob scheduled in ${getMilliSecondsAsHumanReadableString(
|
||||||
|
this.executionTimeout.getTimeLeft()
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.executionTimeout = new plugins.smartdelay.Timeout(1000);
|
||||||
|
console.log('no cronjobs specified! Checking again in 1 second');
|
||||||
}
|
}
|
||||||
}
|
|
||||||
this.executionTimeout = new plugins.smartdelay.Timeout(timeToNextOverallExecution);
|
|
||||||
runCheckExecution();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
runCheckExecution();
|
await this.executionTimeout.promise;
|
||||||
|
} while (this.status === 'started');
|
||||||
|
};
|
||||||
|
runCronCycle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stops all cronjobs
|
* stops all cronjobs
|
||||||
*/
|
*/
|
||||||
public stop() {
|
public stop() {
|
||||||
this.status = 'stopped';
|
if (this.status === 'started') {
|
||||||
this.executionTimeout.cancel();
|
this.status = 'stopped';
|
||||||
for (const cron of this.cronjobs) {
|
this.executionTimeout.cancel();
|
||||||
|
} else {
|
||||||
|
console.log(`You tried to stop a CronManager that was not actually started.`);
|
||||||
|
}
|
||||||
|
for (const cron of this.cronjobs.getArray()) {
|
||||||
cron.stop();
|
cron.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
88
ts/smarttime.classes.cronparser.ts
Normal file
88
ts/smarttime.classes.cronparser.ts
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import * as plugins from './smarttime.plugins';
|
||||||
|
|
||||||
|
export class CronParser {
|
||||||
|
public cronExpression: string;
|
||||||
|
public get cronArray() {
|
||||||
|
return this.cronExpression.split(' ');
|
||||||
|
}
|
||||||
|
constructor(cronExpressionArg: string) {
|
||||||
|
this.cronExpression = cronExpressionArg;
|
||||||
|
if (this.cronArray.length < 6) {
|
||||||
|
throw new Error('CronParser needs second level accuracy');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getNextPartMatch(cronPart: string, startValue: number, moduloArg: number) {
|
||||||
|
if (cronPart === '*') {
|
||||||
|
return startValue;
|
||||||
|
}
|
||||||
|
if (cronPart.includes('/')) {
|
||||||
|
const every = parseInt(cronPart.split('/')[1], 10);
|
||||||
|
const findEvenMatch = (recursionStartArg: number): number => {
|
||||||
|
if (recursionStartArg % every === 0) {
|
||||||
|
return recursionStartArg;
|
||||||
|
} else {
|
||||||
|
return findEvenMatch(recursionStartArg + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return findEvenMatch(startValue);
|
||||||
|
}
|
||||||
|
if (parseInt(cronPart, 10) || cronPart === '0') {
|
||||||
|
const match = parseInt(cronPart, 10);
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public msToNext() {
|
||||||
|
const cronArray = this.cronArray;
|
||||||
|
const secondExpression = cronArray[0];
|
||||||
|
const minuteExpression = cronArray[1];
|
||||||
|
const hourExpression = cronArray[2];
|
||||||
|
const dayExpression = cronArray[3];
|
||||||
|
const monthExpression = cronArray[4];
|
||||||
|
const yearExpression = cronArray[5];
|
||||||
|
|
||||||
|
let currentDate = new Date();
|
||||||
|
let currentSecond = currentDate.getSeconds() + 1;
|
||||||
|
let currentMinute = currentDate.getMinutes();
|
||||||
|
let currentHour = currentDate.getHours();
|
||||||
|
let currentDay = currentDate.getDate();
|
||||||
|
let currentMonth = currentDate.getMonth();
|
||||||
|
let currentYear = currentDate.getFullYear();
|
||||||
|
|
||||||
|
const targetSecond = this.getNextPartMatch(secondExpression, currentSecond, 59);
|
||||||
|
if (targetSecond < currentSecond) {
|
||||||
|
currentMinute = (currentMinute + 1) % 59;
|
||||||
|
}
|
||||||
|
const targetMinute = this.getNextPartMatch(minuteExpression, currentMinute, 59);
|
||||||
|
if (targetMinute < currentMinute) {
|
||||||
|
currentHour = (currentHour + 1) % 23;
|
||||||
|
}
|
||||||
|
const targetHour = this.getNextPartMatch(hourExpression, currentHour, 23);
|
||||||
|
if (targetHour < currentHour) {
|
||||||
|
currentDay = (currentDay + 1) % 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetDay = currentDay;
|
||||||
|
if (targetDay < currentDay) {
|
||||||
|
currentMonth = (currentMonth + 1) % 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetMonth = currentMonth;
|
||||||
|
if (targetMonth < currentMonth) {
|
||||||
|
currentYear = (currentYear + 1);
|
||||||
|
}
|
||||||
|
const targetYear = currentYear;
|
||||||
|
|
||||||
|
const targetDate = new Date(
|
||||||
|
targetYear,
|
||||||
|
targetMonth,
|
||||||
|
targetDay,
|
||||||
|
targetHour,
|
||||||
|
targetMinute,
|
||||||
|
targetSecond
|
||||||
|
);
|
||||||
|
const targetTime = targetDate.getTime();
|
||||||
|
return targetTime - Date.now();
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import * as plugins from './smarttime.plugins';
|
import * as plugins from './smarttime.plugins';
|
||||||
|
import * as units from './smarttime.units';
|
||||||
|
|
||||||
export type TAvailableZone = 'Europe/Berlin';
|
export type TAvailableZone = 'Europe/Berlin';
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ export class ExtendedDate extends Date {
|
|||||||
// INSTANCE
|
// INSTANCE
|
||||||
public timezone: TAvailableZone;
|
public timezone: TAvailableZone;
|
||||||
|
|
||||||
constructor(unixMilli: number) {
|
constructor(unixMilli: number = Date.now()) {
|
||||||
super(unixMilli);
|
super(unixMilli);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +99,7 @@ export class ExtendedDate extends Date {
|
|||||||
'September',
|
'September',
|
||||||
'October',
|
'October',
|
||||||
'November',
|
'November',
|
||||||
'December'
|
'December',
|
||||||
];
|
];
|
||||||
const daysArray = [
|
const daysArray = [
|
||||||
'Monday',
|
'Monday',
|
||||||
@ -107,7 +108,7 @@ export class ExtendedDate extends Date {
|
|||||||
'Thursday',
|
'Thursday',
|
||||||
'Friday',
|
'Friday',
|
||||||
'Saturday',
|
'Saturday',
|
||||||
'Sunday'
|
'Sunday',
|
||||||
];
|
];
|
||||||
return {
|
return {
|
||||||
year: this.getFullYear(),
|
year: this.getFullYear(),
|
||||||
@ -118,7 +119,28 @@ export class ExtendedDate extends Date {
|
|||||||
day: this.getDate(),
|
day: this.getDate(),
|
||||||
dayString: ('0' + this.getDate()).slice(-2),
|
dayString: ('0' + this.getDate()).slice(-2),
|
||||||
dayOfTheWeek: this.getDay(),
|
dayOfTheWeek: this.getDay(),
|
||||||
dayOfTheWeekName: daysArray[this.getDay()]
|
dayOfTheWeekName: daysArray[this.getDay()],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public format (formatArg: string) {
|
||||||
|
return plugins.dayjs(this.getTime()).format(formatArg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boolean checks
|
||||||
|
*/
|
||||||
|
public isToday () {
|
||||||
|
return plugins.dayjs(this.getTime()).isToday();
|
||||||
|
}
|
||||||
|
|
||||||
|
public lessTimePassedToNow(unitArgs: units.IUnitCombinationArg): boolean {
|
||||||
|
const maxPassedUnixTime = units.getMilliSecondsFromUnits(unitArgs);
|
||||||
|
const actualPassedUnixTime = Date.now() - this.getTime();
|
||||||
|
return actualPassedUnixTime < maxPassedUnixTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public moreTimePassedToNow(unitArgs: units.IUnitCombinationArg) {
|
||||||
|
return !this.lessTimePassedToNow(unitArgs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ export class TimeStamp {
|
|||||||
/**
|
/**
|
||||||
* returns new TimeStamp from milliseconds
|
* returns new TimeStamp from milliseconds
|
||||||
*/
|
*/
|
||||||
public static fromMilliSeconds(milliSecondsArg) {
|
public static fromMilliSeconds(milliSecondsArg: number) {
|
||||||
return new TimeStamp(milliSecondsArg);
|
return new TimeStamp(milliSecondsArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
// @pushrocks scope
|
// @pushrocks scope
|
||||||
|
import * as lik from '@pushrocks/lik';
|
||||||
import * as smartdelay from '@pushrocks/smartdelay';
|
import * as smartdelay from '@pushrocks/smartdelay';
|
||||||
import * as smartpromise from '@pushrocks/smartpromise';
|
import * as smartpromise from '@pushrocks/smartpromise';
|
||||||
|
|
||||||
export { smartdelay, smartpromise };
|
export { lik, smartdelay, smartpromise };
|
||||||
|
|
||||||
// third parties
|
// third parties;
|
||||||
import croner from 'croner';
|
const croner: any = require('croner');
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import isToday from 'dayjs/plugin/isToday';
|
||||||
|
import prettyMs from 'pretty-ms';
|
||||||
|
|
||||||
export { croner, dayjs };
|
dayjs.extend(isToday);
|
||||||
|
|
||||||
|
export { croner, dayjs, prettyMs };
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import * as plugins from './smarttime.plugins';
|
||||||
|
|
||||||
export let units = {
|
export let units = {
|
||||||
years: (timesArg = 1): number => {
|
years: (timesArg = 1): number => {
|
||||||
return timesArg * 3.154e10;
|
return timesArg * 3.154e10;
|
||||||
@ -16,7 +18,7 @@ export let units = {
|
|||||||
},
|
},
|
||||||
minutes: (timesArg = 1) => {
|
minutes: (timesArg = 1) => {
|
||||||
return timesArg * 60000;
|
return timesArg * 60000;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IUnitCombinationArg {
|
export interface IUnitCombinationArg {
|
||||||
@ -30,7 +32,7 @@ export interface IUnitCombinationArg {
|
|||||||
|
|
||||||
export let getMilliSecondsFromUnits = (combinationArg: IUnitCombinationArg) => {
|
export let getMilliSecondsFromUnits = (combinationArg: IUnitCombinationArg) => {
|
||||||
let timeInMilliseconds = 0;
|
let timeInMilliseconds = 0;
|
||||||
let addMilliSeconds = milliSecondsArg => {
|
let addMilliSeconds = (milliSecondsArg: number) => {
|
||||||
timeInMilliseconds = timeInMilliseconds + milliSecondsArg;
|
timeInMilliseconds = timeInMilliseconds + milliSecondsArg;
|
||||||
};
|
};
|
||||||
if (combinationArg.years) {
|
if (combinationArg.years) {
|
||||||
@ -54,3 +56,7 @@ export let getMilliSecondsFromUnits = (combinationArg: IUnitCombinationArg) => {
|
|||||||
|
|
||||||
return timeInMilliseconds;
|
return timeInMilliseconds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getMilliSecondsAsHumanReadableString = (milliSecondsArg: number): string => {
|
||||||
|
return plugins.prettyMs(milliSecondsArg);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user